jpeg-decoder-0.3.0/.cargo_vcs_info.json0000644000000001360000000000100133640ustar { "git": { "sha1": "071bca9de1bf439459f233da5629e94660b3415f" }, "path_in_vcs": "" }jpeg-decoder-0.3.0/.github/workflows/rust.yml000064400000000000000000000065630072674642500173330ustar 00000000000000name: Rust CI on: push: branches: [master, github-actions] pull_request: branches: [master] jobs: build: runs-on: ubuntu-latest strategy: matrix: rust: ["1.61.0", stable, beta, nightly] features: ["", "rayon"] command: [test, benchmark] steps: - name: Installing Rust toolchain uses: actions-rs/toolchain@v1 with: override: true toolchain: ${{ matrix.rust }} - uses: actions/checkout@v2 - name: build run: > cargo build --verbose --no-default-features --features "$FEATURES" - name: test run: > cargo test --tests --benches --no-default-features --features "$FEATURES" if: ${{ matrix.command == 'test' && matrix.rust != '1.61.0' }} env: FEATURES: ${{ matrix.features }} - name: benchmark run: cargo bench --bench decoding_benchmark --no-default-features --features "$FEATURES" -- --warm-up-time 1 --measurement-time 1 --sample-size 25 if: ${{ matrix.command == 'benchmark' && matrix.rust != '1.61.0' }} env: FEATURES: ${{ matrix.features }} cross_compile_aarch64: runs-on: ubuntu-latest strategy: matrix: rust: [nightly-2022-03-24] features: ["", "rayon", "nightly_aarch64_neon"] steps: - name: Installing emulator and linker run: | sudo apt-get update sudo apt-get install qemu binfmt-support qemu-user-static gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu - name: Installing Rust toolchain uses: actions-rs/toolchain@v1 with: override: true toolchain: ${{ matrix.rust }} target: aarch64-unknown-linux-musl - uses: actions/checkout@v2 - name: build run: > cargo build --verbose --no-default-features --target aarch64-unknown-linux-musl --features "$FEATURES" env: CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER: aarch64-linux-gnu-gcc - name: test run: > cargo test --tests --benches --no-default-features --target aarch64-unknown-linux-musl --features "$FEATURES" env: FEATURES: ${{ matrix.features }} CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER: aarch64-linux-gnu-gcc cross_compile_wasm: runs-on: ubuntu-latest steps: - name: Install node run: | sudo apt-get update sudo apt-get install nodejs node -v - name: Install wasm-bindgen run: > curl -L "$WASMBINDGEN_UPSTREAM" | tar xzf - --strip-components=1 wasm-bindgen-0.2.83-x86_64-unknown-linux-musl/wasm-bindgen-test-runner && sudo mv wasm-bindgen-test-runner /usr/bin/wasm-bindgen-test-runner env: WASMBINDGEN_UPSTREAM: https://github.com/rustwasm/wasm-bindgen/releases/download/0.2.83/wasm-bindgen-0.2.83-x86_64-unknown-linux-musl.tar.gz - name: Installing Rust toolchain uses: actions-rs/toolchain@v1 with: override: true toolchain: stable target: wasm32-unknown-unknown - uses: actions/checkout@v2 - name: Test run: | cargo update cargo update -p wasm-bindgen --precise 0.2.83 cargo test -vv --target wasm32-unknown-unknown env: CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_RUNNER: wasm-bindgen-test-runner jpeg-decoder-0.3.0/.gitignore000064400000000000000000000000230072674642500141670ustar 00000000000000Cargo.lock target/ jpeg-decoder-0.3.0/CHANGELOG.md000064400000000000000000000124040072674642500140160ustar 00000000000000# Change Log All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). ## v0.3.0 (2022-10-17) - The MSRV policy is now managed by the `rust-version` field in `Cargo.toml`. - The color transform can now be overridden as well as hinted with `Decoder::set_color_transform`. ## v0.2.6 (2022-05-09) - Another fix to allow usage in WASM target. - Decoding in the WASM target is now actively tested in CI. ## v0.2.5 (2022-05-02) - Fix single threaded usage in WASM target. ## v0.2.4 (2022-04-01) - Corrects minimal version requirements of dependency `rayon`. ## v0.2.3 (2022-02-14) - Added `Decoder::set_max_decoding_buffer_size` which limits the bytes allocated for the output of the decoding process. - Added Arm64-Neon intrinsic implementation of idct and color conversion. This depends on a Rust nightly compiler feature ([`aarch64_target_feature`]) and it must be explicitly enabled. As soon as the minimum supported Rust version includes the stabilization of this feature, the code will be enabled by default and the feature changed to do nothing. [`aarch64_target_feature`]: https://github.com/rust-lang/rust/issues/90620 ## v0.2.2 (2022-02-12) - Added and SSE3-specific SIMD intrinsic implementation for idct and color conversion. It will run if applicable targets are detect at _runtime_. - The SIMD implementation is not bit-for-bit compatible with non-SIMD output. You can enable the `platform_independent` feature, to ensure that only bit-for-bit equivalent code runs and output is the same on all platforms. - Improved performance some more by avoiding bounds checks with array types. - Multithreading is now used more frequently, without the rayon target, except on an explicit list of unsupported platforms. ## v0.2.1 (2022-12-09) - Fix decoding error due to conflict of lossless with some spectral selections. ## v0.2.0 (2021-12-04) - Added Lossless JPEG support - Added support for EXIF and ICC data - Minimum supported rust version changed to 1.48 and no formal policy for bump releases for now - Minor stability fixes on invalid jpeg images ## v0.1.22 (2021-01-27) - Fix panic on jpeg without frames. ## v0.1.21 (2021-01-23) - Fix incorrect order of MCUs in non-interleaved streams - DCT Progressive images with incomplete coefficient blocks are now rendered - Fix a panic on invalid dimensions - Reduce allocations and runtime of decoding - Rework multi-threading to run a thread per component ## v0.1.20 (2020-07-04) - Fix decoding of some progressive images failing - Several more performance improvements - Add `PixelFormat::pixel_bytes` to determine the size of pixels - Cleanup and clarification of the 8x8 idct implementation - Updated fuzzing harnesses and helpers ## v0.1.19 (2020-04-27) - Fix decoding returning too much image data - Fix recognizing padding in marker segments - Several decode performance improvements - Remove use of deprecated `Error::description` ## v0.1.18 (2019-12-10) - Fix two bugs causing panics introduced in 0.1.17. ## v0.1.17 (2019-12-08) - Minimum supported rust version changed to 1.34 - Fix clippy::into_iter_on_array warning - Ignore extraneous bytes after SOS - Support IDCT Scaling ## v0.1.16 (2019-08-25) - Minimum supported rust version changed to 1.28 - Allow zero length DHT segments ## v0.1.15 (2018-06-10) - Added support for WebAssembly and asm.js (thanks @CryZe!) - Bugfix for images with APP14 segments longer than 12 bytes. ## v0.1.14 (2018-02-15) - Updated `rayon` to 1.0. ## v0.1.13 (2017-06-14) - Updated `rayon` to 0.8. ## v0.1.12 (2017-04-07) - Fixed an integer overflow in `derive_huffman_codes`. - Updated `rayon` to 0.7. ## v0.1.11 (2017-01-09) - Fixed an integer overflow. - Updated `byteorder` to 1.0. ## v0.1.10 (2016-12-23) - Updated `rayon` to 0.6 ## v0.1.9 (2016-12-12) - Added a generic integer upsampler, which brings support for some unusual subsampling schemes, e.g. 4:1:1 (thanks @iamrohit7!) - Made rayon optional through the `rayon` cargo feature (thanks @jackpot51!) ## v0.1.8 (2016-11-05) * Updated rayon to version 0.5. ## v0.1.7 (2016-10-04) - Added `UnsupportedFeature::NonIntegerSubsamplingRatio` error - Fixed a bug which could cause certain images to fail decoding - Fixed decoding of JPEGs which has a final RST marker in their entropy-coded data - Avoid allocating coefficients when calling `read_info()` on progressive JPEGs ## v0.1.6 (2016-07-12) - Added support for 16-bit quantization tables (even though the JPEG spec explicitly states "An 8-bit DCT-based process shall not use a 16-bit precision quantization table", but since libjpeg allows it there is little choice...) - Added support for decoding files with extraneous data (this violates the JPEG spec, but libjpeg allows it) - Fixed panic when decoding files without SOF - Fixed bug which caused files with certain APP marker segments to fail decoding ## v0.1.5 (2016-06-22) - Removed `euclid` and `num-rational` dependencies - Updated `rayon` to 0.4 ## v0.1.4 (2016-04-20) - Replaced `num` with `num-rational` ## v0.1.3 (2016-04-06) - Updated `byteorder` to 0.5 ## v0.1.2 (2016-03-08) - Fixed a bug which was causing some progressive JPEGs to fail decoding - Performance improvements ## v0.1.1 (2016-02-29) - Performance improvements ## v0.1.0 (2016-02-13) - Initial release jpeg-decoder-0.3.0/Cargo.lock0000644000000427450000000000100113530ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 [[package]] name = "adler32" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" [[package]] name = "atty" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", "winapi", ] [[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bstr" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" dependencies = [ "lazy_static", "memchr", "regex-automata", "serde", ] [[package]] name = "bumpalo" version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" [[package]] name = "byteorder" version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "cast" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" version = "2.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ "bitflags", "textwrap", "unicode-width", ] [[package]] name = "console_error_panic_hook" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" dependencies = [ "cfg-if", "wasm-bindgen", ] [[package]] name = "crc32fast" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ "cfg-if", ] [[package]] name = "criterion" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f" dependencies = [ "atty", "cast", "clap", "criterion-plot", "csv", "itertools", "lazy_static", "num-traits", "oorandom", "plotters", "rayon", "regex", "serde", "serde_cbor", "serde_derive", "serde_json", "tinytemplate", "walkdir", ] [[package]] name = "criterion-plot" version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876" dependencies = [ "cast", "itertools", ] [[package]] name = "crossbeam-channel" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" dependencies = [ "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-deque" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" dependencies = [ "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f916dfc5d356b0ed9dae65f1db9fc9770aa2851d2662b988ccf4fe3516e86348" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", "memoffset", "scopeguard", ] [[package]] name = "crossbeam-utils" version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac" dependencies = [ "cfg-if", ] [[package]] name = "csv" version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" dependencies = [ "bstr", "csv-core", "itoa 0.4.8", "ryu", "serde", ] [[package]] name = "csv-core" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" dependencies = [ "memchr", ] [[package]] name = "deflate" version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174" dependencies = [ "adler32", "byteorder", ] [[package]] name = "either" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" [[package]] name = "half" version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" [[package]] name = "hermit-abi" version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", ] [[package]] name = "itertools" version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ "either", ] [[package]] name = "itoa" version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "itoa" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" [[package]] name = "jpeg-decoder" version = "0.3.0" dependencies = [ "criterion", "png", "rayon", "walkdir", "wasm-bindgen", "wasm-bindgen-test", ] [[package]] name = "js-sys" version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" dependencies = [ "wasm-bindgen", ] [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" version = "0.2.135" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c" [[package]] name = "log" version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if", ] [[package]] name = "memchr" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memoffset" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ "autocfg", ] [[package]] name = "miniz_oxide" version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" dependencies = [ "adler32", ] [[package]] name = "num-traits" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ "autocfg", ] [[package]] name = "num_cpus" version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" dependencies = [ "hermit-abi", "libc", ] [[package]] name = "once_cell" version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" [[package]] name = "oorandom" version = "11.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "plotters" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97" dependencies = [ "num-traits", "plotters-backend", "plotters-svg", "wasm-bindgen", "web-sys", ] [[package]] name = "plotters-backend" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" [[package]] name = "plotters-svg" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f" dependencies = [ "plotters-backend", ] [[package]] name = "png" version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6" dependencies = [ "bitflags", "crc32fast", "deflate", "miniz_oxide", ] [[package]] name = "proc-macro2" version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" dependencies = [ "unicode-ident", ] [[package]] name = "quote" version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" dependencies = [ "proc-macro2", ] [[package]] name = "rayon" version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" dependencies = [ "autocfg", "crossbeam-deque", "either", "rayon-core", ] [[package]] name = "rayon-core" version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" dependencies = [ "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", "num_cpus", ] [[package]] name = "regex" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" dependencies = [ "regex-syntax", ] [[package]] name = "regex-automata" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" [[package]] name = "regex-syntax" version = "0.6.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" [[package]] name = "ryu" version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" [[package]] name = "same-file" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" dependencies = [ "winapi-util", ] [[package]] name = "scoped-tls" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" [[package]] name = "scopeguard" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" [[package]] name = "serde_cbor" version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" dependencies = [ "half", "serde", ] [[package]] name = "serde_derive" version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "serde_json" version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41feea4228a6f1cd09ec7a3593a682276702cd67b5273544757dae23c096f074" dependencies = [ "itoa 1.0.4", "ryu", "serde", ] [[package]] name = "syn" version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "textwrap" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" dependencies = [ "unicode-width", ] [[package]] name = "tinytemplate" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" dependencies = [ "serde", "serde_json", ] [[package]] name = "unicode-ident" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" [[package]] name = "unicode-width" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" [[package]] name = "walkdir" version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" dependencies = [ "same-file", "winapi", "winapi-util", ] [[package]] name = "wasm-bindgen" version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" dependencies = [ "cfg-if", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" dependencies = [ "cfg-if", "js-sys", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" dependencies = [ "quote", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ "proc-macro2", "quote", "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" [[package]] name = "wasm-bindgen-test" version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09d2fff962180c3fadf677438054b1db62bee4aa32af26a45388af07d1287e1d" dependencies = [ "console_error_panic_hook", "js-sys", "scoped-tls", "wasm-bindgen", "wasm-bindgen-futures", "wasm-bindgen-test-macro", ] [[package]] name = "wasm-bindgen-test-macro" version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4683da3dfc016f704c9f82cf401520c4f1cb3ee440f7f52b3d6ac29506a49ca7" dependencies = [ "proc-macro2", "quote", ] [[package]] name = "web-sys" version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" dependencies = [ "js-sys", "wasm-bindgen", ] [[package]] name = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ "winapi-i686-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu", ] [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ "winapi", ] [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" jpeg-decoder-0.3.0/Cargo.toml0000644000000031200000000000100113560ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2018" rust-version = "1.61.0" name = "jpeg-decoder" version = "0.3.0" authors = ["The image-rs Developers"] exclude = [ "/tests/*", "!/tests/*.rs", ] description = "JPEG decoder" documentation = "https://docs.rs/jpeg-decoder" readme = "README.md" keywords = [ "jpeg", "jpg", "decoder", "image", ] license = "MIT / Apache-2.0" repository = "https://github.com/image-rs/jpeg-decoder" resolver = "2" [[test]] name = "rayon" required-features = ["rayon"] [[test]] name = "rayon-0" required-features = ["rayon"] [[test]] name = "rayon-1" required-features = ["rayon"] [[test]] name = "rayon-2" required-features = ["rayon"] [[bench]] name = "decoding_benchmark" harness = false [[bench]] name = "large_image" harness = false [dependencies.rayon] version = "1.5.1" optional = true [dev-dependencies.criterion] version = "0.3" [dev-dependencies.png] version = "0.16" [dev-dependencies.walkdir] version = "2.0" [dev-dependencies.wasm-bindgen] version = "=0.2.83" [dev-dependencies.wasm-bindgen-test] version = "0.3" [features] default = ["rayon"] nightly_aarch64_neon = [] platform_independent = [] jpeg-decoder-0.3.0/Cargo.toml.orig000064400000000000000000000023010072674642500150670ustar 00000000000000[package] name = "jpeg-decoder" version = "0.3.0" edition = "2018" resolver = "2" rust-version = "1.61.0" license = "MIT / Apache-2.0" description = "JPEG decoder" authors = ["The image-rs Developers"] readme = "README.md" documentation = "https://docs.rs/jpeg-decoder" repository = "https://github.com/image-rs/jpeg-decoder" keywords = ["jpeg", "jpg", "decoder", "image"] exclude = ["/tests/*", "!/tests/*.rs"] [dependencies] rayon = { version = "1.5.1", optional = true } [dev-dependencies] png = "0.16" walkdir = "2.0" criterion = "0.3" wasm-bindgen-test = "0.3" wasm-bindgen = "=0.2.83" [features] default = ["rayon"] platform_independent = [] # Opt-in, this depends on Rust nightly. Will be changed to a no-op feature when # the Rust feature is stabilized which is expected to be 1.61. nightly_aarch64_neon = [] ## Internal development configuration: testing and benchmarking [[bench]] name = "decoding_benchmark" harness = false [[bench]] name = "large_image" harness = false [[test]] name = "rayon" required-features = ["rayon"] [[test]] name = "rayon-0" required-features = ["rayon"] [[test]] name = "rayon-1" required-features = ["rayon"] [[test]] name = "rayon-2" required-features = ["rayon"] jpeg-decoder-0.3.0/LICENSE-APACHE000064400000000000000000000251370072674642500141400ustar 00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. 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. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor 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 Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You 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 the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You 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 such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its 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. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. jpeg-decoder-0.3.0/LICENSE-MIT000064400000000000000000000020740072674642500136430ustar 00000000000000MIT License Copyright (c) 2016 The jpeg-decoder Developers 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. jpeg-decoder-0.3.0/README.md000064400000000000000000000022130072674642500134610ustar 00000000000000# jpeg-decoder [![Rust CI](https://github.com/image-rs/jpeg-decoder/workflows/Rust%20CI/badge.svg)](https://github.com/image-rs/jpeg-decoder/actions) [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/k65rrkd0f8yb4o9w/branch/master?svg=true)](https://ci.appveyor.com/project/kaksmet/jpeg-decoder/branch/master) [![Crates.io](https://img.shields.io/crates/v/jpeg-decoder.svg)](https://crates.io/crates/jpeg-decoder) A Rust library for decoding JPEGs. [Documentation](https://docs.rs/jpeg-decoder) ## Example Cargo.toml: ```toml [dependencies] jpeg-decoder = "0.2" ``` main.rs: ```rust extern crate jpeg_decoder as jpeg; use std::fs::File; use std::io::BufReader; fn main() { let file = File::open("hello_world.jpg").expect("failed to open file"); let mut decoder = jpeg::Decoder::new(BufReader::new(file)); let pixels = decoder.decode().expect("failed to decode image"); let metadata = decoder.info().unwrap(); } ``` ## Requirements This crate compiles with rust >= 1.48. Minimum Supported Rust Version: - All releases `0.1.*` compile with rust >= 1.36. - The releases `0.2.*` may bump Rust Version requirements (TBD). jpeg-decoder-0.3.0/appveyor.yml000064400000000000000000000012310072674642500145710ustar 00000000000000environment: matrix: - TARGET: x86_64-pc-windows-msvc - TARGET: i686-pc-windows-msvc - TARGET: i686-pc-windows-gnu install: - ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-nightly-${env:TARGET}.exe" - rust-nightly-%TARGET%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust" - SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin - SET PATH=%PATH%;C:\MinGW\bin - rustc -V - cargo -V build: false test_script: - cargo build --verbose - cargo test --tests --benches - cargo bench --bench decoding_benchmark --no-default-features --features "$FEATURES" -- --warm-up-time 1 --measurement-time 1 --sample-size 25 jpeg-decoder-0.3.0/benches/decoding_benchmark.rs000064400000000000000000000023320072674642500177470ustar 00000000000000extern crate criterion; extern crate jpeg_decoder; use criterion::{black_box, Criterion}; use jpeg_decoder as jpeg; use jpeg_decoder::ImageInfo; fn read_image(image: &[u8]) -> Vec { jpeg::Decoder::new(black_box(image)).decode().unwrap() } fn read_metadata(image: &[u8]) -> ImageInfo { let mut decoder = jpeg::Decoder::new(black_box(image)); decoder.read_info().unwrap(); decoder.info().unwrap() } fn main() { let mut c = Criterion::default().configure_from_args(); c.bench_function("decode a 512x512 JPEG", |b| b.iter(|| { read_image(include_bytes!("tower.jpg")) })); c.bench_function("decode a 512x512 progressive JPEG", |b| b.iter(|| { read_image(include_bytes!("tower_progressive.jpg")) })); c.bench_function("decode a 512x512 grayscale JPEG", |b| b.iter(|| { read_image(include_bytes!("tower_grayscale.jpg")) })); c.bench_function("extract metadata from an image", |b| b.iter(|| { read_metadata(include_bytes!("tower.jpg")) })); c.bench_function("decode a 3072x2048 RGB Lossless JPEG", |b| b.iter(|| { read_image(include_bytes!("../tests/reftest/images/lossless/jpeg_lossless_sel1-rgb.jpg")) })); c.final_summary(); }jpeg-decoder-0.3.0/benches/large_image.jpg000064400000000000000000017176150072674642500165730ustar 00000000000000JFIFC       C  D !1AQaq"2#B3Rb$Cr4%S5=!1"AQ2a#qB3$R4b%Dr ?SF6fW遞YMhP!현ЮvKcJe&JsBqllM,%0 cNnR@D@M`d060@ٺB6;J7bb]`RM!4; L,YkN2em7$Rt)a$M۔,leX.`.-؇SaLQo$$0ش9t, R !x@\@Nm!Xm0E6LiNL,MMNhV9Ud"B-BF(Na!6!l bv {,L,m !cb2줫bERft iSAILc&U `&L#H"ʱNㄛ}>!}"`8LR(TG)݄0yL.a*ٮ"SfLlYQ,si`¸ J"UKhRb9DIVɒ+m\#4{)ŹRlK9R-{2!Kb 6Bkb/$\)`8%H % m1)Hs\>?,nƱ|Jc´R|hT )- JF<'cide1٩FnE2k C%R)1 XY;*DcCCxV@,d /d,ˤ+nL@쯇dXLfc@0?xJP@$0A.EE4-1S,cJB1yP!) cAcZl,s\D)cL"A8I2q HbrlXn&@M qS r!.C!rBR6"%B5AeAfj%%`lT ̯mQaCŌ bT8}-Bn"`,a!Q@&[Y%+m<'als)HcDt7N B0= ͡)SBbAaM|&9^a0҃ f`q!nc }*Ŋ :M0[ggMAgJa Yiu=0Y6'6h@ctRfZqY6=΍l`!b;C ̟ mQ4KcrԠHYd[Q%fN5FFP!췔[3 2d$؛1V0g>`NLW?$6b8Wa+{+L!I[) ̵#jCgxr ;`e6oӴ3ky+)Mu#`Rh[#:}0@46SgRhs+/{;6sm-͝+B3iFM>ƖVhS;ݔΕ bVΎIy9`-#7F6`Wam Ԙ٢1^ZǶB kM͕ M LWcb"ŹA;a}!8Os+s3Ԧ [c̕0ْ &NmVhfotZ5Z-s%I_I&08Rs2T$dǹu0lԢ# 7& lCseo`ae)04XmhY7dd,P0Kms+`Q76[@OsH%l[q;`#s!-D'd[Oeql-x T؛fwꔉBKu[S̛bZ[wµ fpS"n!a8-VFRg xLET3CA-hB< TY3(Re,rPIAD%NBɁ$Ĺ1PH0I̦"`3.A$JLLA?t rO"a"A1) 11nLhs!" ` P [B>(S؛ bdS`t @l042!3 I)]6Hdhc`IB laEN?ta  p͒b(@M+*$( ,?4; 0pyTX$(a*c@JLL";"T!iHJ3)AT=0H`=3o U&:, u @TpR2Դ,LR@BZS؄{ `*f>Ɂ@[`{f@04S@jˈLTl|MT*5Sd|%M:dU!PR9!R Bk,T-ͼ@a@Y&)2L@"[7f{)=HĤ HA{P1X<ƵnRc,1#HDZZ J&#K8TLI*TwhcR$1Ёd R3QF') p![ ,v0(r!o'9Hd- (&H0n$˳M* pXM߇9K[L=jw{/F.RVb[z֤jmSڿ7ЫdoU/ ) '}#UJGyqr3Sg]>N2 Gt 1! ,6) 0脘Xּ!aT0{TR (;Y7) p@Y$Jt"ɜ@ sźN%"MN .0-@Y7J̯2 l=Ai@gb`bݘIͲ 6(mlcXhe#6@)R" ` ieb * HMsh BC|*ƶ[FPBJst"YxIiradrKO# & E*6/ &S bV-g𡉲 b0id[1eɔ %!tg1َ6`ʒ[93d rSB3ʴK30 pB2>A*eh'3bͻ`Ά\ۺlgoH,/ee#Ӏ$HϑxsI٬OCAe6[蠀WF~@5e bc)CLǙ*E:ܪԴ C5ѪCU:ɌM v=3C %w 'C,(0*? }& TTJADL(!0aED-i9t:R=M6+R ,GhT5Hk}Iҏl"'merS%c/kI|QF 5iO+ǤDZE?bG_O0Kϋb%oo[RZUz:īhmmM:M~7}>(moņMCHo|_gQG_J m#)|uMrX`L5*B5mN.H09RߋƙaPY7( &2 &AH c/t c@Ÿ[(XN<(6g{P @Y Q6gybR @^R $1ĉ"a@N,4Iͧ tK(:# Bm&oB@Cƶ쀱QBcS@M7Z(iKAgFiPVtFaKC0h G 42B ,ep`|͡ s!MPt%Jfj Qfʊ$XRЙKT#t$+9/tr&̕!{*4fZ!j:=CH!ʨ\i:?ui6#Yҷ3B|OӰ vEh'%ۡ#REG_Kv4ξ2:pNĤΞb&QҠ$JF-Z!XYU hM 1j04B`NƘ$vUcXxNb*%=5;(RIْPۣvR&b8C=@R`f;3=fñNC) p̀%dYHY(AYu-N$%B(J!@]RB`I)d,V&-S@q IkI*hIY1ZhGFA l^\gN(JbD/C:gLQuVҒBچtm;v-h|ߚ׬PgH'w FORV~~Ft\B6t# @5\,,0 1j)![4M 8@k\$nɌݥ: ,9.` (vw@B`!77@:bbRafw$!b=A3Tm:;t5F2`bP -+iJɲT1g@hNST &4hKrҘtm`@hJ``he/$SNty=>@P 8)P f<]!i xJ4ա HBm (hCG*JCN8PKhCK,$1OĬ(Ҿn geNm BFJCB1md%QRЙn-MbHPЎv "8ښ69\xJ2HTtiUeig{ ;"ьU+ @+ &usN!GgHI\CɐxX:-:.lQtn,hqҾadGcLd'cHemWgWNf!T]p --]5e٦+C@9Natd-NʰH8NSdi1ؗ&b3U̕vbҕ j)lfJ(fƘ,+6L[, ʆQ=–B>h &r=&(X.#( qT4D0NhE蝒ż[ ) |ZabU&aRb4Z!KZL4m<44U #0>07@ {sf! sA . $~lLN|Ve ws"En rX@Y 3 .(=9.8@~ot$1`)ğ8E L`yH d$r0n`\q `I `Pkr5Qt6U&T3]0` " LLa1 lchCY LAALEt Xxd$,Q,<,X72dЇ2r4Rr>T&Zfg"t CJT]\_Ĥ,`.&(8T8H A R*T0UPUE쥎UAB3>#PgDY4&ļT!<*m &J H M`n M@)01P7hCPPaP CS$[nSBd2E1a^j&/ +)VwYE4~kUZ4qQ FKS.i%.<'uM>󆌯GMg9)>GR}B@&Cx pR>I%m G@~ f489:1SvF +.\s\r2'=4D 6򺗟#~QlvYt⟝V쩵m2f-ABCM"!AcTv{O(ay@L, `w@ OS!: G)l$#;&=V+3@  3e!T1lf!* 3 v%" 4|)E>#IHǟdTP4kFl Y$PTL 4ӣ)Й r E:e t!̤QB>CCB tiHFlYH].R41dѶ" LCD=|B) @KRHLsib, $,@Ef"2Vm 5`Ye3V}U1YTI>A($HLT0PIʤgA&fVtTQ2Bt@A2bi"W_A9z0RGMz{>iz2T=?Z +Z(Gu ku/iɬ|T6!/u1n%xx7tp_Z%7NDl-OI?Xk}mse z񐅤T<,H]4jH~2*7$rI;K]Oz*H|.%e& KȨFΖp1@vң}u$ȒN ~ H?Wu?kV +WܮY&_'yr4'wdy bPM}Ra"2L|K DzT2o>F}%C 8NRoQ'@g{Vfz/+Da1 tT&dB9$h .I;>%a&Z;;`Y0;YK6} 4`VMC~tv!g_J*}+&4Φk&th-m#2vig6ZU0eRc.{DV%@!@"n < 9 Fg+ 2)QG>{$U@*@Pc3rЇΊLY|]KCL,.Y4HY4+E [ sҥX%ʖu@ Ɉ@fT.xP!􉱕63mNIؿ x<+E))xLC@d"cqd&8M;,t8;H1ٔ x@J\^M1" 5@9LCX wFN)iT'FN*J@FT^IʖR+w2!"C@!򡁕1t^ri?3$Y!!ѕ S{&'=ʒ$L0C;B@TD  Ej!i f4!nG @ż[EAL ,S%b\FHD zgyR%xB "H) BLd ;A@Bq8@ 1L¢ei:G#U7bfIE쥚ŞBKn/wVJtxVyٻ/X"~M.hZaf:R'",o6hLtYkq rCƂ [l >! R7tF x{j['DKh-h2(Eٌ4-J9j䢸GJWHC+ ;%9MWǺ!atXQ6PQ5h6؊r*3hIi+FyZ&Fv^8;cd.6pk R5lM 4˼=y۲l8Q>NtiJ*2,8HEHĤآ T; Z(R( XM 9\aIVN- i@%112J` daQot$ w<'@!3/gF h:d4dʑ- /CL1B@7O P)ЋRM:34Q Q9BfTHFQ&t|&P)в(HT1d iiĈ PTb4:q8RBE&ut{ )aft8 & ҈!KCu MCC,S!CB'm%f1oaYI͔4*3mmdՓ@ag6– j!tHSG7YYƪJ;EZ3 {xV%ǀ}! $b@e04SPBB"@E%r֑Bc;LI '%YҾR;',dCN+;:J:ҾbWv4N-c+*ʹحS*tuiª2Ʒʻ(`T)2b%0NPr=fԀP&Pp@vsߔ;1W")YT49TUu-!yXɾyY"&b3*Z.u4!f5$KBJa*Z`͌`XF]okH|A_Q442:E%@"HLQ2L )NuI&y@| ɂ+'@r b! SS9Lv 6SL$ 1KO@Q?('8t\fm EI OA@ȁ@~ Ĥ.bF,.62&b0I?r*c ^Lp$)e@(`rʤTLG*,"@19TK "ŭ4AxT_B%q%P] v@-<M@rP4"0&鉌iv9n|%X<߄"46""-1rc'T*X(R8CB!/p#((KaHj&̵x6L3`gd;3BXP΅~ɅS 7Q4 ,mR ZU ЩS"XLNsb6!1/)2[$83d p1hb B!-SCLHdHӠ,7@&Ɉ-E#hi wL5S$ɖRff)3Dt\6ZlmQ~ԙs |6Hdž~FxRLݸt?{8)킹@`$(5% j-"8r9TfAș!DL2KsIc X⃅V]qt*FjL. b+bJٮ8ǏhsD.Cieeָ `,Ol[<~]gzQӶ_y G&5UyI(MeIX'1 C,8Pn ‘i$,:JAEaH `0@ ol ,`HcZ&,kb t.xE&sm`!O0 F\믧~=qIB>@C??SqcRGgF Eh3mRafnV{\UcL`*H aX\!4Z`0lbFٖT yBb[a D9EήUXXqCʨ,ꇺEB$UC NVma2hvB 61$Pe{l.Xɉ2d/w 6&9Cb-b`(d$@\ L0 0L,uѤz?l(,O1Ci@.) \y t#+ܓg9H( | d"8q"J Kq (" c An `& H3iA@ ($R 쁀H  # &b0I"p2|,ɀX$^$0LL .|hy(@qU#`)8L~Sb5 ~ɒjHn۔І1oI+&&!4 \EbyA,CL)s?dDD8@ v"6LEɑ?/_EgG9J=63T6 5;DXl@K(}"(%4^ǰ44JFCiGX''@T\1"A+2Gѧ-ŽD~mD TJ 3#j=4!y<XL=A{/Z(mB(B@i1na1X6LP= s!S{ ,[s$$ŖhH,'SB |%@lB@X'>Tu}fc:xag判ڊר]p4Zx0eK@Ok)bR$( FTӿc40]M )x@L}SPmB,4EyT[ۄ(Ms"Qo" sNC! Ql`80X;J@[YC `RL@E }:w@kOU:V 4NkJQ@jG`jJ@Y%I/ !8R#M*Wb5Ҥ3e:6‘2,::z7H&tiShB@^ĘEu%Yto*c-CB*7PlhFz6h]Y8nVr ݐqMhbC&e-_ZD 7dyqdnw+D 2xT60 `ou1Ms[Mu8(l ec!=12> GWKx2m!ыXNVgoHf4)f։T{B腄gsH]dƖ!:MΝ B\t(TdQ`eRt7~.VkjC=2ik+VNe|Dn~')nCQwdXq*[\-xKpYR;2j5fJъdX92 ;tr42VQ2S 5iEo+at&Vqtz2dXŇd61".l,h}m*(cBJɱ6Vⲓd,ؘmYHD $M;a&ŹhT,(S%. ¤2ã¤E wZEZ|ϠILeO1!1UЀ3<H"Z*2I^M@gEɛ &$'@Q&6Y+<$M!(~$BT :M'R0dY"L`t0Cd Y,$*D `ljg)e䠠se8I^ RE)"J fG@t6d41טM!)ͽ%8¡<Ӡ&,@1 r `L v@Jot"O 'X#!;QdXx6XƼc 48$yI RCO&ED7D/3T]SCF[V|^|O2oyFuzt6/[8QMQJ/\`9rl|FDع=e[n>p q/u3ӑpG>֎c*ڣs/mD\IP 0$&-"!1bPn`6c5=46hhT!hTUm%q´CHPb]ئس& @?E {eC`#!C >tC&D\e ~2AG~PQp&51!!8D="3Tͽ=j}?{ΜVuD.WX6'0asjl BIƯZ ߹D儐0@%gB\R {JDIJJ4LI cV.1,FcnNo*ehn[HQ# .ѴQjYL ЌڗXr95W<(Sdђ2ZAF0~v8`ƛp]Feu:6>ey-uc?-EbGN`ѷ+$ƵڟVmʗ<˶u"T0PI’@PʰxRRR4*h TC4STk@iX nH-<&)YX0HB݄V(M-L@`%8@X_Nm$X/e $/l ‘1(~U&Y*]*stƍt3e*\(28@Ѱ(M*I/ i0;&R*/ J5ӥFKthR-( PmX L9P 2]C*$EIPG*j&`a쨒%Kee"_''VfV2!Mi7TyPBx<ƶY8ШTMҡP8d$!d4b Ɓ=԰G Ie!H]ҘVŗzTɱA&g8"XE9&r>HL}0%0*&LX\ Dd&S-Q@Bf @9I2R`-{`J,, 6&h<A@1ʀ@fPR#Z-d 9S;LN 9!g -&CL~ʉ40d=|AcLC$4 T++@v k @@7@Qy%% =" Bdd@2=$blaI GcBL,6JCZmx ra+5Hg)6iUk67UyIS[=/2j/Z0H vVD8]xgƗcFSI$-F՛tpvQZIS! RCMFnѿL i.Kj;y\iN5-h~3?6-_٘/4;[F Z&Ai ɢhQ` Y ԙ3m!L L@h` 9M>&1OVbTbH!R(6!D1nEs0``BEKDDHPl>`I0oOQ E $HLa}) k4&lz6S㓷I-g\ִ-V~jX7jtM:/gEegx'=$3u_U- tc__CQ]x![fi3`afE h %L) Z.ViYVD-" ֈ-\PDxTMPιŢ5D*\ 5."Ҽ֎{hxTE$d'tai;(괂$s6 QpD[MiV\l(DMK7N}j{N Q,&,؇fkEL!f e$FP"Y 1:t >Hb>i2u%)PAM hIPj05Cl 33IiG8P" b8XcdE(@W/)vBNLap2'{"( š&4i# #Rn 3""b!y8`!] IJ-$(:(T E yI@ "3)mn&]}1L ŐKfNK"G*#{B8 {IR%)@ @EÐAP2P"DYTDx@dm@?L}dDwHDXtʖR& H,"M$3sOCj1\suL QúpiGxLz׸N$BKqNm6.B'%aGj[M4)μPj]0:!cY\|цh+5ڨe'ݽuHFnMB&XaD)iWg}:}7[4vdq?g6h uth2HPAl (E1HfLL&=011}U![!oR3b?udTfw 2X tD '|.0@PMʂb-_@-cbە @2g-d mp1,"&\H0$CZhlZWYg'٦RL1MWW7݉QץR`،87Ҭ "!t|Y=<~SEa9 ϊdu8>Q!vzuCA)2S 9D$X0嚕3?=ѕ"I{ntC#D+ 1rL Yk%bg Rn! /KQl˸ŏT|w;|r%||#yGJ77l їA Ea O*Z)0P ) i24i/)2THtj 5҄ٔ'beL$Ji uT!dH'JXyEI$"طI0dbH(v%TYu%Y@c[cAf`vJjAHFPYh ! B[jJ ft,L 4 hOjO4Ӧ; TjOL oӳXa!-nR%yR!/pH;B^*,Qu ] *TT4:DP &IԸDќwYJ.GdYpy}g?LLTMALBK|}RmnM`CT `6IJLvʆ4PM`l3e)] rgsETb;zFbb!!d# aXE DB}ť!* . X؈ b,l4H) $#UjU3 =2%u BS>0tg/%n Yz=t?Lֵ,jΜ))+7Vi$`$쉾QmA8?~6r!tA݇F ]'}PU"6T`0# J'zCWVkx/=K?5=72"W|Ѡn7Ѧ`@#~ ->m&@N-` k. cZزHa">sfЅ=0)¢gx#XTfļ"!9`QIR,gʂi@xP2b.$rn\M MDĄXʟ; E0(-0È1<>VsV#tSa?Sм'oK3ڏѢj@kA!:KUՕ[u *D/Gj#~FZI>wzvW45 "'kpHgǾ]V=^5 m( sLvK\NRJɫ, 0^TCNMՁ[7Cג:W &ꠛ*(2t $-.| 7^|g+VXot$ZTYuT&PfPc$(Ń=&KGEm1^YGny7fzqm.O9Y[g L L,>u#'Ze"YCEhtt(HGdjKN܄r 16M$*HLO|+L^Mw`&Ş6-B(V%PX)h,粆h5SC$RM6Qp3}Ldo 7ѧpʹYN8hF28T#E6v603M6$#C{ ,j4SmC7*Dkh ,ۄ [ 0 @S͈R%)`"9H(vRKܡEGbfj' 6*2U~eK%W6:*I &g3Rg"N>i{,7ԉ,d$:&&mb*/@h@H4A`569/,,LCC& 6>9 il`,$gF./0=V- 'bEZ)*:zY1!e$3Y0:v@M03JgR X6t4䂝Ѡp؍]d6S!ɦV=UcIaT>6Vre)"We<)ZEdE9ZB %!s!em !/䤅7T&)\LqFZ3dQ1Bi3e[[M'ю&소D+jfG- N׎vh+fӶM e;&YCؤ ŔYyYHc)he:$ u>!;fSmaHQF:>ꅚ7]0\'["ɁpxLV\G L PXc*m,I-7@ -*@Lp{ hY0l8@Ot`b9HbHRgF,2]_Oy%74ȷ|gɝ,xG#SZSk{/C5QNcXD쵄yNjfƗHPWa8Vkk3Z;ME40 Th\5od9RvJ*՗YRUBiQ0ƹ6ҸW\t9T8\CoQ{SY7B9G:DggJDII2:4[aD@o"ʀIM(0L UT&$¢X ]Zd3;۴]Rd0nXN?!G*9=1A4@FI /$M$DPG\0 .0EOd)$TRaL]K6C?yQ.ʤ}ĠE~.T9r{*L)d>Q{ih)Rp'{9{ӺNI̫Ic L~"klIc;t]ǕmRcSG:JaYQ.z' -($!ReWa!0* 5\.p扡.iSlSR2lPl ˙W$f}MpƛG24NW󵅿+z6^YW%wռn9Z$xr,*2:  I,YCEX+6Lk-&haeEU,*YF7)͔(aHEʤH/rhL rDp"lʨBO -$eKbMLBr&ĸl H*Zy(h QhNwf;EEY~f-Ith @PiAGB8RlfSCC41C==B A&#kM)Oļ,B^ɕ, pK"l }u ،u]|KC-WMLz1u MT![|{8A<η%f T& Б$ t5&mn&5QBN!Mll#CGOJ.&vt|$30!c%bhib*#2D!4ZVut p#y 1-;pC:L AFUL*H VnSঘLc@1cU&RƩl44JnH0 ,d|VM Ѣ@=ánbͿвě)P2RR4%)X[XJI1gJI$gFrn)#m?M\c](-V.PȀ +[Epj`IMv:]xQF;r> h\^W,A*-)bdYrc!.W<̥l MjK6]ǦSj@ MwN=.S||obv=%y&~ |ڱD=p|B #14L FIӰ )2h3K,Vl Z6ђHw ͻ/&K+}XȅB+w*%+DEط>UQ s%B/2tlY0+oI)h,rM!)5e-f}ҡeEYLA- (gF~JGGNc 1 ,$MĄd=p)ٔ֔aH(&Hhp q {*ĸRj, uR𡁞†\.HUVdيHG6Dbg;P͐fea2YיVyl+&I8 =I( Pa DR`1F01 11rQ,f`c7RX~fxP֎`yXI sˁY\(FZmev Ju6 6#ApH ,U0gN} Rek s :tXl"fZ͖mXwqAJTZE‡"H)li sTE$(KeP\ t%Թ)hichZ!J`u jVCFz$ahDs:apBmf&˳KTe.sA3c)ChIl؆5 >>T4#[bHbOh`eIX P'žB@4J?"CDyS =B2fNlD9(ZM@ʿd\LD J l14^xb Jt{e:E"<"`0,rM*p Ly@9#rBHR4 }U@ B`Qs`@$E0M&# Fn ['(س~9R4Ǘ 3)IEkg@92Xfb chkCI0 ` B'( (K D-+1JE7l7Eٯ'6# e{q,PA,bB`LP\L @Rg&E%cHMVZA@ (9t+QDը8yixυkRwEiGOŠQV|75 6 X;;p u'nTѫ{)ߛ!4CI솩<4^q) L1ػSR#]*Dž|3TuߘaO\$mpMTU6ivva3|R☚ZJke5S !Ԍ}{O;I7c`Q~Iɋ$9_4zOYAh`$vttdgF }06L tD(41{@Y [± xTTHf}Q EAgA-.-&,d 3*EHRQs9@X>>c#! '$@?  d|'c#` cLNPi1:G eѡ-!<8Ng`" X<5HD2xڍRNOBygz vt.%v_xmt7-c@]JϴDewCk$Bʌ)*$hpqmSl|0e1bC%ʇi9^ZC*5b<l+Dh)Z Y%d!sF2b\d$6-.mG878Xt<N-tQk3ܯyd~ OIcjq$G@hwL }p i0I)2'+6CEM"{٢fL #u3[)@-ײY}`MnɺUDV{+HͲ6TEq'p"q `{X2eKm )ht,Lӿ)3UyEI&t(4)*HRGFD\B05@4dXCP`5Ҁ^R`kR3[_k/sXЗKQ&THu,FgLJz/ffZm T*Xk k6Y.nvVo3^g5G#Xp,6+0*B>pH<$( xR h1$eC4Z)ht:T06SC6PipΌysLJš6le.DƖd,ZuhŔU6S ͔t( LP*nSjt4ieRlLYLj,YKD՛f RD<,𝖐ҳlƅe;)pB )OiFwr䤄TIeJTX(Y4cRh2>Zd3Ol.HruPx]xFRGS $턬ɣ1i%1Rllpd8P}6(dC 6CdBI W@źp!Y16 *did%`Q%o]#}=ǚ-({r3;{;eIL e mJ| & @/9T &EP; }ttt6PL=@u"""YEҰ c?[$ O0(79@p(/C qEK D@{ !0G@sob2LO &.h144p h!H-t0I̟dHZMFޝ%E0n_iψ)EQFkOK-&9__?\3,hreQk0D iq^3'OM~ ̮Z<"v0QFn$lR}@p P@d`I!KcH/t-GszR5 NIR=٥9ӷ#yo 2R1oMG$ER>bRJke\cHǍ%eVS4m kE:hMOd9XVM/ꕖpVк[(0B*ۡtt|l37t:$D.Aͺ{r;B4j>pO$ k pԂJQn2>`pZIڳ|tlCGAnEdBջEeSouj^M6x{ưAcGMcFe3/*SHpռRhR˞|:9%EX kTG y#)PIMH]iSlVQDþG8<0,'#FpBD>pY4CTec1 )bzg;X~Z gGel34t8F㦹Dhdͅh[@۠hse,P*Yhky"-h1fѪ5қ]f*FX򁐾rP wwTV*f 쐭" 9h(E`9tآ:&Ž œt,XE )hEK*XSE!(ѶF# 8tEѣxHfQhHf1cFYsc5 ktk&5061,/ŗ@ShKLb RrR#=Jɉ*-ъa{v A򥋳 jKB0֫eg;QWʆ#yD~o+)+ jL,dTc[TBXHo$c{(`59P;cN6R^U:@C7ig$6ubKJ嚢h!%X:c%fu46Q$m#2BliNmPv R>Q5SuN<F 2hQt6rhfN5$heҢ (=ii,[Vrf ՝Ce$Qj\ZOS㱤r,e"<,ܹ)!obEg{<,I }5 3;Zl|*Ѷ+\2VT_$4bJ˦! u㑛G YJ ՙsn3h)XC s) –7 h UYl a_ PɱBɤmWG7p&!.lX u9BFBST &SlP% {bU!Y`vˈ1 Q6@ ` Tt i"&B/ E\d  ut`08be @ʶ L@EnEP8ېtvE D'T0 o&xL0T(XLc _͐&=d];!1~BLC`bHx  DAhւDZ`ϡ{GV)$+yRG^={T8G3DܯŗGio\-phpdh\~+G']vp8|kGN P."dD)'#D9vRHH2TiOXw!9?&$Td-"#MSia >Uk٪s _?>|_q\W|1?? 7PTTC:-@x@S!4@Y@ p%4*-*C3,hh MeLd٢֬e"Pݚ$\)e$QjZ@Ч5g!ee$M,&EZM;-!/gue u9gRL>W,R(N-&# j|.Ӎ3hkh&t=j4.!Me5"h{Zkbs$ƃY%4@`Ba( NAB( tPB-pZ\[_#[i'P=:>̷,Ź`E" qF֏`I0* e0(AiIESFb2q( s8H" # IaCEn @p$0 <)e hSʖP 7(9!4 D 9=6C]=9lpKA,>`p ϲc  "d4\μOE7[~+-0AigL{I-jigCRL+Su*E)F.]@@?;z_̿urɉNN !x4|Cf\d!+#dYYJnp!SRGjrx*QkgD1'Gn/5lA~Jei1(>]?#_S_Rr ł8ճgގ=#E N{qVά8i}ehqM$HCdM<@$]F888,fŦ!|8FJBs٧vj$0{쥡_hU2< Q8hel7|i-tuz1v * krlnq=én]m' :'- iˆszΝ > |/_>W3k_ O67#5QVdΖLnx&9]05S gnbV]R%xVK3Uf{ry(!6JvI𘘧 soe"d8RŠT0mCR0|Lh~F\Z>` @RXy.lGQA@dhSlS&ۺVR+Q]ij_1F92$? ,Ԙz)ZE.tmQӼ<MM6Ӫi4ˈ^_fVOo2RS樖JrM8ȸǷHP2agf4RՈ%y"ِ"j,< ԭ$Q+Y; FJ+|E H$Ս&[h:FL\?u^5VFU@D oPBlIpAfL dw)a]Pl $R$hm3†Z5SYTlfL@ZIeO)Q d;&I7^ʑ Z"(V+|rFlU."s Ÿx X&̤;#HC L T RfnE&k#}'`q*M"nq :mE}bJ:HIik1qCP{A,TEuo*Xն}c F,:nԬ;V(e7FZL*lVeV 2T,Z\5C1UR,Zuk6#zʗZ 9 :MɢNv2%f9dY & w{ xJ ʖ8[PSr\͍f@PfϺ:EɁOB3\ŗ<摸[}0PYKN"9PuGWNRJWC|Y;)i8 6Q8TN% X U)-#M"N FwYȤidh YKDc ,%$Q [)"R@n5CcEP-"炒{$ۉkNlfc)JJC3 =F%*2l]&<-+$dىYRL.N80Wd%fL˷VٜӲ${ZbƤԉh2&K@!.1t3"* EA:]"4]ƴD/ޑ 4`,aHu4P s-8bb\S sq$xB%sL@  Bc $\LT ì@(n ])(TYL`@L   m h[T,YJC8#Ǖ%/҆c0t0L@IjcNa$M/TC|d1<!muV)4@"˰dos~EGdQ0lZu)mgszZ/L+/qFjqGn~F#qoįOv3ܶOSsA-O cY o4xvY΂OW< q(.bB]O5IZ$X.'}8;:B&?!+-$ٓâŎ;b 2cjG6-4W@L9@OCaIk 4Z&SZd&qb)J*B$,hQ ]xE BdžpJѺMHiڥ|RC)ؚU;Lf< pQqg .M4"nWDэisn.{7!l|v肩Fݗfbo<0W2 ё;O4|eW% A(H4 !$((WV7h{LUN<4^I8"MY,Mă>k9o ,D\g˳B N2Yb5@bs?d[,TE@LDw ,Q 2Tl4de$'4 N Q` !| #%&|e #@{dl.m;`Xc6L) | hX 7E%ɛ^atǷ]ͳr6XN'$֎/I[ N7C#,Y=B< Y++{+e0ȅ xq"Uoʻr`I.k4S7]8%chU$lf_MJ6z\ɀ\2X. (efu 5k?lI3DqU @TXC6)Dz/[1?_7~A;o$+n56.XT$[b`D48|4 7Hh" )6T4Z5ӸYXFPhID/R.d(7Pm#*ћ,NVB+Fmh͕Y(*mtQ( DAEI@@o%!dcLHTTh^*Z4F.f@ʆh]u%#u^]" I452(mzk_| D_6*C+RU|U :4KIIREve dH*#mDMԴ6b\$MhK@ю~C!jYHpl ,ج^s!M5j#rTId W[7Lòr,,6$,C* h0b*X!%C> 6б΅,[|LaDGcDߘZ ;A+4 @ŤGcN N::t=ԁ; -;ȅ Qp)43}yIi:HH @ ' 3}b`t-$hT𣲗&(NFg;(³T9"3DDSe _`젣@8yY,"-YrP YMF њc[B5Q!V9a2KZ0Ven3 3gYJwb,[x[e"L0yJCXb45&S$̫H4+  cp <"N$4%3eX&3_#alat@pg@@90 s [ =~!Ol\@Ot H&"YELDIAD"O@"8@@2${7(gd")LNb>@bܠ& YR9X 8(e q)n1&*X@"p` ls4 r$.(}fi L` 4"T&=ɡQDn)Bb i3򕜓}DkԆߦ{r#=gkàx^egҩYCg6WVCK;Ltz|QEi\02LrIB_E!a(#9b@~^ BM]G QM*\3蹫&YbqL1MuŔ`㻒5NQc@i|[2N { w[!\ :%3E*t42MDGg+lE©F.I1Naf1p{]F7QKi88,Чٞ 46i9+7Im+uǔvÔXld m$tBC$HVoՠ cDM)_ϛV:"-M"EQ5wKy䘧e3&8z t8 <-CNl B]Upx} ?BgBȓeHnb #m!4P16`H dN!nV[R$PBX Qr,Q$Y2L4!O$K.q*6 fhE-R&>)0O JE <  X2G ))!O,[l+g?ZIѤKkg?F흮74Jq\N믡Ѫg< Yzj*JZA[Ee7jL@,^e/6tM0UBTRgSREZ #!2َ q%yRɹ!%s9[hi3d.9MSDJ|ЮUV/Rm:0eґ܌MֈZ0`THMD1 ´oAHK)K(e2'*hL+6i]'\B͚!,;,d/<[Ÿ(. (:pSBl6U82l|en.96'B!6ȡX$R *]@. Tn#vFsE)RFNFHYK4F.K-fERF/xR7ҩe"L]6Rz{j 1Q1(ڞPKD>"S@UYZYVKbݨ0bR^1ٚqEvc3-JMlMW&RZRَo?e u@JXYhdV,RCLF:gIpYY+&KfjJ(V w<"eHAa1ęIF k qpbc{u bNI3ec!!e :zf Jűv4R`֍dsH0V/1F h*QBWAtt((`n) Rf/ $t& AUi8wPSѬx40))K-ml!+3Hil AE†Hp9 )KeBʹ) ef%$ ʗJO ~GB\aB_|,۱ST:2UIKF:퐺#6`uBTK0)6Z-:3g'UJADeJd:L&!%kHE{&huH)l- l+2`]("SeqCB\0 h~S_ )( (S&)'Ka!1 ~qf10 𐊟0yT& 0,,hEL ɁSk`k @G(&DH`8ɈL&!tHIc 1H- p~ q!eђe!ss #ʆ:FR(9&@:qP+HRl 6YѡJbЙ YC#M"$-O|aR%X[LZEB1hYbBN)A.E.?v?mT#ڮ}_[GP<;b[ @\{ĴNڣ>LBjp, &[QeOip4aN]\,%82B1FVN v7jڮQlT%c] eS,|헸"0ʳHhA H{R\PXM{f@S&"?;NYKd[]QHbYF@SOoV?F7G+X3q ެQ8i)Fph~mk:qhc,LY=cu(v63T{6T+x)M!!ڴįԕQ5DIQ4FU^Oi|r| x%y0:|I:63%x f>И Fy@ǴY). )ɈY*S/B3xTb*) L2!' BPY쥈줤 r&R+ !),t,fR'0nEP!\@I\!58Aq0`)f\sk[{ck[tdO ݢ_ES=*f 6ΦxtJ<)h]\+ BhSerFewO8+R-6=v6tNn &5:q|z֫Ǟ9$~MeYqVv1&cvc X$ZLdNMSb'F=Oc|G=]Uf F2D=Ba[8-9T' D'0ɸ(e lP٤MT͖l .Y/ YEHwd׉p#6+Ds 2d* *d'd RA6 %*PAI iR))RFODkP hJZf5 hK%} luE#m*lZ{jy@mS7(tU mO(D TR@j&׃s IDr~"L򥁚T*&f\Jc_ʐ mAc_T0lZbVrBfJf&#%J3d,Y&Wg !-%(Oꛠ .~L 9,rb Z6eC7RG]c!c!+M 6,m+"rc;\ buh843urѠ邡:4)8 66Yf.NqR:4c6zVQ–FORi國Fd,&gEFO h =h`,䴈DaKY +iR)WCE&@g'?mucNe!/ dbo 6Ճ#-V[\"YWL&*[D4cVѫ!3eF]jW6]2hOýTY h"%h`ZāEl,>p Ђeު(h]\Gv< 10&^ɴ &m#L=!!PFzAFw6L=&Mx11n0@q1f>Ɉqbls6as   1} ]ad wRo ZR`,k$"hS86ABə)2E#  P8Y+[% $@@wH$m=@ СCIoJ͂X;"JTw…><]4@휅Bg~SHI[AiYN-|&xG+V~&?-߆qubiq]OX7pd*= 4)^{e:p.[L]FA5Fr3=BMlm"T2nTSʢb0ԅ(G"LqcݡCtrɸJx.))r,+-8'_ p g&cY\bk1}T$Z{JÐ_]may4͕)[ܽ Q`Tv&! Jh fuO)`ZpnTFQH*CASK=Lb2ЧLx=s\`2qiXgN3Yi]t(PL-+S6v;-\NK 0X]vm;|ˈu1ߍGLiF%j '#78SDu0S$L@l1MDyLnSNU[ʤ]h%d9Fm D8bؘ%H36IT11N.Tl>&rc? h>T&0sdE9@9:(@sN' @:DBjiSK#%vɿ&>m,S"wPM ^ X"{ W$]AuH͊.fMC+35ai*6(Q+',48HkU6mi麺?XU6ũ-Rٖ}:Aj֨];^U. QX.l jm)̮ivb,!Վ dL\ϬJ:ٮ84|bQ> /E;~EP( 8vTfY%R$~@4Q7H!Cc)MYDihT3TjcH.%^B@ z dALA5ʉcFl2ahM#6X%2S訂OJd (N!'@ZC ep PFnLK-X–hTDkRPHJ2hվTmT/ mW(e*6|9@ f|j@ uS-Ւ`G vʐ3Q)03RJ&fgYHњyfZFe_"TYq&̕k ʆfJCiYL*RdcV ͅU"o+'RrTs @bl,0Df Dd؇ʆSk6Y0T05Q1(hi]%\c;F,X(!fHilVbgJ GCN3BӺ@Y* m, ]6KmiSV::#GB!QHM龬5RFu<))>P9e'48Y6hTVh6Rv5Fs bY$Q(r*#QtV9|El(ݕEBNGD"2 z̡noP^RCb^ňQA4dز:31mV èh]XIή.|ќL͢ $*D !H]+tI&Q|r!kB@ҊUSTh5?WFvTpO]Q0d QH9LB ܠB^Z{ĦH/M`D\t[@XA׉L 9H"`.lA&g [?4H) x6)fo)X<͂)6BH')?2Bn<$BO&{$6oi 6#Ҙ imF8MҀ *HFZ$C5Pw&ɰ0E&g9Ă BSA@㲡RBj) Lףf*ڴt5p O.O{K'-pmJ~ҏDid}*\!}+b{%F똺MqٚV쪂XeESE Xğ&–Qt8iл2 wLVՙCx^LO6`vHy,e&)1VF!7*H0.gtsídL5LkiX |=?M$ B2sc TfP)X>S .>XCLE(g)2aL1f(YDik(f`'X͔`Qdoꐃc*ћ }գ&Vel*D2*!@SDRIG @i%t)-c쥖 }DiS MB" 4F5dةemifU l1)X ms1k+s+@ mo(b9@֞P:F]KfBڋe&_T5MNn*jOtf~ʆ@I'PgPc_RfYK-ZRjVR$UrCuKĩbu.k_(7@$" 넚ta ͠ls,yR);B4ac$1~6#vC) L \h+ iG+91Ԡb%bnnR݌ANihF)3m*)?ѺŖN_j7 \|ri]7,7Q%.M "TIBEme«cHTB6ƁrRP Zo\@Їfw(IQh X %fJ]d&V1Ui+/0קe 2̺鋲;ZDYZ%{$4%+x޷DjB+ ՞V"hTO(O5E}uRV\󲛥Ty0TP[s!@) "@g|N#;2(^X?TśqhA"{¤&,wb!`' &&@,^x@]d/&n-ĐBaB y $H"= eǕ%Pȓ:a&0 I@Ei4?J}>t(ЛZDlO`i١H"8"0в"$R ̠ MiPm:4,E j:QBl!DYneDMד Dd\C $pP]sd, qh(E7TRB nPkDT4z],Y8.ujfٍwƱFO|Gsz*6o9 qh涸3KZ/:XסS^9n=sut^(>[}7.B#kr+Jɏ!ȃo=4\aڠ8`[q%Lm}kRp7개hBSAdB+(Ą/IM[_qp{ZC,k;^cLzy_ j߸\fVFZ3R7muRsȮx h:)Z " 4DRe7 ͊eXƍ#4WDӎ!n wk:6/M8&h-)\<=7!N ]XdkLVLJcZ3M a!Ҹ1>py4ܬ6#!t씸7Ҫ*^3,x';4&Xfݹ^v͎P'4qb3+|-hLb35S1TfF &K53i` CfF'LLY¡즀[hLSVbkM!V>x%x 3AlKJD%yI[(c{eC.1OЁ$2d$;C&ꄂ]@И$<Ͱ4mۺO 9};fPG#U_?t|]8 '~DzxۡiWnşUts 48zHw0!}6,jE4ŌԱicLJÍT9&zm-Z`С3W;9&;A Ÿh#Bʋ jJ(<3 qcF.-4+47P%}b&*fcrժ[ccFz.Lr2MVЍArS2T>BZ4.0zG⿚5I5ps&0EcZf,&|*.d .R!0I8)eN2Fu' YT3Dtr K(S^R7&[oedwDZD1wb͍ ћAVW2&MLJ`S@tPd AH݊Z?C9RCRleSC-)EfN,jZ~AAFz fHc@5q)֜tskk@(F,e)_&T3>C*@Cl k*l K`k}6.ΫmؗTT(l,SIu[B+%ffLb%W6f{2D9<"I1 h @TTL&0:"45c)4$,걐kM{G  iMY4v }o:w,Ze:(hfO(BT2NtM=Yg.Aʆt ňuKeua+6Rj̡ˊ*LyԠFOC)T=I򥢑OR73XBZW45\R)ٴy4z瓣Hefk[ٲ$Dܱr).`DBT60T\xPNQ'}$B* _C2T mwB3->UYZ3 pC3Uv|+2<^v@.t&&" \]!dK@aj\-KB*=khʪ/d)-.e*4 yA>U HW< י@=dKxMBSD$HKp2yHM .0& {/|HlRd{C([C 0L$-ߔ:ņ8|a&RIǔ\3Hbb@ s1AI@:q|tT<(lOąGP Ν&DHV*8ZٙDX3ehLklD* 2M0 &[MHJHcIJEc `|<^XiA |ԼZ(W,5@i#WX*8G I-LQq*z0n[Վ{=LYVluoa+'v6k|J78^)iroҡTcWL'~zfl423MeE84qhrH %Ti{w77C[qrVF_%`Lޓ-iG_)֒*V,eZd0\-}5(:HLU*m\{_H쒠"DeFEYmVnsMJDWh6 K|iIiq(t`UJ.,l)tF3eM7^v]2Ӵ,vDC +Ev"kZ)8 Wk3M7Dk?ckYV-p{3 득JLXH&/kCLpR:W(k܌-eHѤh vcc I_fZ}oj<ʬy%9꛷a*J] kKe%~оug^7>NN*L1jb!13]Yrv?ts9MeB&`U1FUET' &I*f0,E@a&!.R!o.NX-Dzi }R62H$2@@$UAD($0SOI&2F-BuuQfwC@TMIt~)\$&F pu4-`G,h+4pڏ*Vv_AҳԇDmB Ǘd/M)^&)14&DCfUKa 7E !&)\"} CpVSkkqKO RKJl%D#kmT7щI+ɛ``(M!wbXT $K&FmՏh/i: 31 -͜_}H9Ë?jVcFmNl pUdAcAL_E~4'"yI(: M6CJhs/":`PM 4f}N 3cAak3aH2TI${ q`O q&,‚'Ąi wRbC- e_*-!ɕ ieo0#M: JFUM=G 9cDB`ƶ$C\fP1^ tSyJb_\إb3U [\-OE~yRXRl 3*$֑ؗ +&:vC`,ՒVmź'7J`|Ke VT0=Gʖ#-G+6gsʐLIhybJk@9dKLy,M,G8YWHnc$#tpHiYc$R@E΅ bPd`iSʖ?e ʆ@UE#|1:$,E$nS !)CCSѡTDh6rH7Q|B甩Tx6Ѩ6&U'7F4zi3Tl.w FN-1VujA=AR.ܓC*nRo*ĺc}± zb3V `cyV=GL̵ IeJ;j_!ZVщ Y]-"ADZ0W}h䌅fWLI(BBV&z$вL@Tb94:(hRsS]G#&Y@Ev/({ =# B-Bg{vĹ($C L4`n0. s8@$)['B,@X Be&&P4-ε)쐐 s,k _O+&D)Cיυ#wt o1. )`uzu6$af9"A`f-Z!5W]kㅢ$hC!Z`tT` C-eIVU#HAG/V?oTAŏs??Feas.ZA{IhtF:LR%POI|k4(2PA0S W\mfip=m<_9j,+őR㣫M.^ IQ@)7ୣ=3{dJpuT4"$mq)"`Qѧ|@+Sϕ91܌58wMdv\G<dmF骤)y-M6T\eh'WhmK8QY=-UK5tKh,q:T)S.. >WyPJdÁJ+KutX|_ɢsM8wa͵Ժ4>zSkH粼yp{gmGu%`8cTfVY$ BUŕf;Le=Njil|ŏ)e;F9@@t \V _)#xgmH'*C**2ړS.,Y"Ԭ: :)r[[ }bJ4?]xrt/|L/j G??,S˦ZPt_( JdBj C; cp< &Ne1GeH@eHLeh)G >THH1nY)11&0E X&J̀v hY1p=AY"ADŽQuH x@$Ҏcܠ$d EMIe\M6:&bY(#zڊeG?r(!VrGcTuc'hWWG) FѦF̯WȂhi{Z0!>L8 TQ|D$e ,-Q\#ȤuX]uyY`/սRҕGR$4ZV˛W;dəH^m6 4l ^4҅+W;Tf+l;)D#V>B]z'DI-\@,oqm*^$Y,Za$ $I2,!r)MRgE)6Z@E60 Ͳ?Qf2JZ9 B BˊJia ,w=͡զf֙ʤh0n2 *K&"b>؈;DKx )2;%Ce,_TD[jϲ IE :iP٢4YhJ4Jei) s+G0Dzʼ9baA RwI6 R$Kt&%J2yR،5V+3> lFwi>I3XT\rTFe5m6Y>JNܓeVm)} l `!MЅ9Teb3X+Te*3Z}_FZE&ZxtM -"(\oKG7PND +,T-dTtEѝ' N!Xc(AEnD<5GrPZ$]G1cB"/%:~%`,@X@SON\K.LuĽn&<̠,aRy t]d @7n &,,&閄.qs <}!D1{$1DM逐qHb30N#c(D$rr#ӄA G͐/@wͰ!\,#K1ճ!w !03I&*%4:*{&ZI8 HA04m*l&'^-;̺>/G#UthrR$d"5ȧGL1 -[6*7QƒC`4[ƚ=id89&ogTrnq*S V;7ήj#v]%fHѠ^*Crlc+X;Ԓh"6ETu^CpPEXTǗLܪAn4k{7LNF[MyjiGt 3Moeklr,W5ᜱn qqJ['>IiV5`}TF1W4$ ;+ˏd\Z2STTe9r<~68]x4Z஄돃Cj2ҺgmޟTM#Z5pe9Ԟi:fۄl=m/-qokm-G YvGXэ-} NHcCR>~`X;t8<5VYSurdn2HTl:BƝ5tjltxV9S^o?{˂IH~X? n?j̲>6Lfd6A,LA,s()IL?hE|B`'Z{}UĽBܪhSŬ!@3w@<$(dqY;򥀗LI@"G YV^ 0"RLDAn=J& e&ZA484Y,nrQAkZ K; '!# 3FY Frd9e  Ep{L EJ<AnCK -ֶnID$lx.0471ax3N,w';"4C#Z,6%hNp* %"*whѧo+&Z4jp%C+DEH}*nj-WI^NglLZƉ-J+cFfMGd,2u&+2:,+HR:+iH4,C*[R(TRE2c@|$uJ -ҳqM zQ(QRt3uI*%3<PY UV%3rMYmD"1Q+X6ٛ}au;jY4e$4c}B !y["VFU&9 _3B!z-:GUu m[ئY( bhD)ڞUR?@.n"NtrClK.>P!Nb1&2ϸ mT(& OTXQDy,t FCd `-vRqu`%K䛠)@)>&q@,5dc;]09VRR GvHhBc\L-"C2UoHhC1L(*EPm|em*"igAYuJm2p?Ԯ>ߓǿ֣Us꺡ǹ/~Oں#Zdve-q+:͡sT6KF\H2%YJDiI6;&1*-snea8gPn>ayX6'O+UZ5(p]3h"]I+.9 4I]isC' Fic8]Quߋ"{Hp+u*:8DU#!S[Yi4 ة2M0E1 ;o=ѧ hBbg#9bGi$ ̠[XCOjTżle/zQMx4kJą̆giP$ x,2]N**޿<2+i⎤Sc -Ij6 vq̷.=UZa%M+@2pBȘ;vjt`mc5A+|ؿĊV![.Vcj؎+H@߂:13k.mBQϩ-8QPh{AZdJJΖ+㑓ATipƙ9e)/ A?u:^iCɟi?Eɉ|6>4Lha= L{ d,S"fP[hV "fb10k !M"[ @ !$ ̧e I2dH6X-Co+/%}.5u zv`㴑Py&'W$872?')S=Zv8#GPl.Ѭ[bq6G #td2싶2J YQ@]ا,8+U$\ @\;F\,fe2$B)\y}ρG: Rc@ِ+ɓ 2NCCjY K Qs,DI RBu?ʣR:+@}jr_?uSiD\|]cShAt-9o;1Agvd]#9N!pQ`XtXwn[6Zx*[)"APCZ%|"dpd 2c A M׉T,Mòcwp360*Zd4 Y$?Ep?v ]RP;) ,bb6PRH$YSqh&)lRRhsjEʛ-1E1̮)mkLskJ,,{k̭"E+(5&Q[*lQ(V__Q&KRl.b.Ĩr&:}TuE-J7Ju! 9L78Ij;) \3k${Tt Hq {@]u 14!6-}7əS$U+ :zHGB[-=L&u4l/͡*b#YIi8XAfƙI6=OH͔*B ҡZEht(VS(ѫy Bc:4+\]fthe$nT Jj%geoZrT6hK6he'EQҾ R5SRQFu yM L9+ʸ-1r\e血.FhGEO,MòST. v`gP$c9TP5Vʙ&Z[U!5FZ8RVd5W.r11U!R":22ToX2Ui xʉfㅼdfтH]1BFVDw!j/0Ph9P;oXe_*0P ^%0ڑ Ђt0T;7O)9@e>@X9 }blS('@- 3̠ >y삑DfE@m "]%ix;1MJa:(&M#iC G.TJ.j6ͱr 6H<#Mn}9XeZM-K]U%,QrNNh߬2 @BYݩzFQ8Tq1VtXڛ6 w 62|V4-.(9U>,u3nB)[6X']3q܋ rN"0ve-Q )ȎWJ/,gdB\TMF\=J[cOlU=+FY"rBL=srє%->(4XP"?Qlu'PLX7Hk!".)4j@PsLa(h3k6QptBG^9L7u7u֍\mwU*`546"Bxh{)q!gFGQ-.OԃF{FO6+Jʽv>m P>8DLWd.a+,x1XvƸ㏵ѡ0%Zg\_T|2.lRà%ŧx92ெ,w0♁?X3_'%~+r28A,}3thnK Shf|xM XI*>؁ppp1 d/iE`Y4g{O6`!`lT&mq Ź݈zݔ7U~.jrJlμȢEлtҁb-nJTI^ 6RB D_H $9ԦxNPܑw,[j[f韂y [r6e.yR@ofM_86;&/E(EJHT0ׅ,K) mKX0B, .)R${]7A Li{vKɲi48eRdրh,Y]yP$&*8) _lN„!=!/JHQ&TR@o+6@&EoEl]Ke{e+^+)*sd)ʱyJ=x0s+@eh1s+N vY_)6%`_"l 5l,׼%bʛ [ֲͺ$KyY1/dub9@$՞|(l@IJe@EjG?dX5@ S a͔~h`D |X$]&.(;yT0 ̥Bُ<%&υ% k\@=1x $K4ҫhXOTEɠ:*ER@tb/u :Zz9!ee." e+O9YUfTNQ@jSʖgBX+)!3Be. GOOTV2e ೡFCF5=%fu4+)2Hue$l_YriO*4HҪ;fYkdKIf)?R%fN7E%FoYOt`\4hs^ULn웂7yPU h (ʐ:Ϯ:2T$-X ʴ!*Z$RU!Z&*3w TeyL[Œі H5цWBd82h͡F e"hT-bBVyZ[DLb]QӕjU\*u-Bm;@ttj2}6'~Ӭ)E|j1zg[QNݜIn叡%Ю8T:p~:6j :|3h&z}&Kpr4:5\I22ok2 D=PڽFX֖1e{Supⵛ`wi\9b=RX%8ioE#Dgsd䂓'䶶L1GB٘G V2U; 5/icAX̵Ly9ݻ3|\ JcHe{X cf]CW31^c3e K\H*&aZ8Y8\~7<(W^Ej1zlh}93 ߶+|l@*1 9 yAE>$aE'V:(Փ~2eM@qQ"ڀ`ؤʆ)$2ȹP$ȹ@6C4"DJ,tdia!UƸ}U&CAc?EV"XNЧ4"%) hKqB8!BrPR)AM6&E2,&X~YA ߲@1T։ ({+`= }n H\w@_$Ĝ_T@upy*IFTجQ &>l>p`%ՉH5{d[ܤ"^4T 54:+dP 0 y& /{PxfhBȸH*(/?D4SVЊKgAR aHƵ)4!FL,(URQOTB:zzb==l::kXI k[+7FU*Fl^*\F+*%7Qe7Q |::zK"Ь@X:)#e:K:4Hi+YuUL#e 9p6Y71.)#]䯓]7]&QRhǨ)Y:a[I9&ұo$OtX%KTc"݁U.kt.IfKLVB VFjh%rL 22hC,BjlFZі-"hUe"2XȆQV-+XȚ1թo*3X q7#VUgNY~PP&9L6 mST LA:my*d6([H81N aزI Arw;8@H&,! )06|0IHt- 4 G)7Hb̛L`Y 3% wRl t4iIԡ!Y$\Q%S4*M)0Y[썣 \Ef@9iC{Vd-tieƾ3^BI~se\DzLPV~X \QZK L\ZfㄒRHuG*F[\@t(-'iYOr.XHئñ(Jf*Du3BLKkf=eС&ƧW&&1+48嵌iYwWR{&蘪2eڳԎFdiSwki:|-po;P;;Zo.2dW$$㾂sZP♣J_Y? m!B^PHq] k'eȪ+iqۖ+*$"0Ip2BQa8&n!tb( Uf2pU+'$r-˰5QQRLM& ¢\B2QjiMtBG^50dmtuo[]aBgJUcǗ*cKF[FhM6 yiQkc0dvki"\_ɪl !æQ;_`e^BK Rc|sJ`͸]nkQ_&z)%`Y+?&Sl8>h{r!0X 0 /wdeH0yL,)!e0!Ln$B?tB\&!HB&&iC}14gÜ$&[ꐅ8pm YB_(LhaZ!t) K0.4H{jQ-Y,8<4yFII|W{l,C(3 ŧ؆-5U4|o+ǂѡGkݎbz:>v/㌕im^\юL#3G+Ư 3t*UdGr\Q:JUժQ#"˛&#F OmjQ\& &)A=bEᓲR66^!4H 3IӨfJV7plL r!BIZ`r-y^\: 2U2W&!ݗ+fL ).A! oME&S9A2&3ݥn"iߢ-l|Y`jXҼTslJHKC@@PNO ( ^6QNE(lICPJe Y@+m|RMa)l4lcC"hs]|CCZrnLiSP@Z7 x!/RR6P5fJ@eKe\T;|"dw&ʡm[eRعV1| mrj ?)L =109R!Fu B\$5L&%fЅ>eH 5oƜ AWDֶa0ǟtU_xN%0/yP8rOd8Jz[״eoñEM4*o=Iѻ<,Mp[YUDk>wSWڳD3ɉk1 Zx ls h0Y{&IJL SLAOɺ,p]rpE+70!&T3u,{m' Tgl;dLpЗ8GtQk L$6\HYI4OYE%\ cbݼ7qCwV}+U᠎ˢSm7G2uG ϻ$NNm# lQtƹ:^,{t[q.NFK| m{DAl" Pu`@uzu==3=Ⱥ)b)429)c@ 𸓔7('.ض\DEX]z9?B+]0%<~7<ܕ|k$D3%%pI) Ɉ}&6;vYUgp3# tY,&qA:G%ɞ71R93r9zK cS#[KlִMy\G/=4J`N68E@T,1r cHx*ltQ7 "%e$Q)EdC\lm^ pB '@jNRlLMYcAA- cvMkh%bq8N`K,odn'ꝈK[3t%V1n-7hSTZȵԶe >xS`22SE¤MquCA֞|CV6ɀB 5ҀL u7R:yRЅe [E4H^< ״졠f|hThE !lFONMm$U@MoH |/C &[)hEQRb+}?"PJTdPj[) "PQ_yAEJ|BMmxTYT2)Ѝ47!e$3m& DѡX졡FYH6Ѭ-%dmVyhfV5Ӯ;K@n@FeK+ Dtt(װQ*&U㒲hiV.(B&VMQh@X˞ 'Bxp)&QO^&hn贝]]D5\J.}'&htFUIE$kS&mIE 6cjB(kjyT-ڜ־yR=zi *j pHQ+$TJ5uq+TЌX3- xŒ02Z2 E! ,B^-SBhT@UђȖu '> i:-h׼H9<+t8Tu!k3IB0c qlfOtG߲hHTT{  =oc)`T-@bE 1}k)d,e0(l/k"l`.(闐"iC;zM ΅ p٨[Qsʭv)y69XDEөP-;&ryq8ˍQHo_A*VPԚZZmZo ('5Lנa-Wt냠P;vzj.f˥[`z :H MZ=nt% iS3{Y@A!^ό(o"M"mkɯ?KWTsKxW'ܗFܺ9Jس`en#n1vʊjha[!e3.Wrfy %&;e8Z-R'&WfMXZFS#m4P3W pW봯 ?<3n}`i\y O#sd σsb "y@诈r 1n1)XǵmqD!H̥bf8 jeKFQdw2Xֺ08v!r,M d'T,,Tb @VR[ - lh[b!Ke!NV-k%] `& t(UPaR/㘀U!+|5ܦQ@{&DL)ʖ@㺖( Yج%uI*h@–0B R@YEECTh'(DdmD\(E|@H(SM dT2$_@: C7E `%d.T3s6MwdL|%D؟Mּ$h߂5SpxYJ lRNabIS`V2U|%V >ɡ3e:V`57fu q]:d zEQ* Õ$#BE#}2hKPy"ѮihjĬl]5{LiiХZJFJ'+"7yXM:ZErTiGVlbJΒ$7|l5SzZYqhmNLV*ږI kj+O:Mω)BE VSC@TreFyTD{B`̕Wj[Beh)Tggw2ABҶ P-S`I+gF-A 9]1dcD[D}k߲%F:C\͚NܯCp!R%dh= a>\4T!7(,BA)P.$IE~& dǺ@DŽf IH$P Rͭ&nP e@:(V2p<ʖ͢Lt@\xXѻK \]Kc;]8h)΍QxUEѩ([ ZC pʟRB mN U9mVZg*dbgR1W'i{dܞ2O=jj4ju9A4~~|JUp"{9Fi3ʭsnwC",o,e-Z)R\:j8;BFI;C([TC Qk=qO EY[ ŗz#hKr!U躃yYpxNݎ*eu)JPR*q1;*0E;Rf%Tp^-a7ԍ&bP2jR"pLNDab qGvmpAwd/v9tcFn Z7ꌸݠ7YPf,aTsb܎/:~ժDѩ78-/3ޭzʺjMŮiGw`\>댹L֝#S)\ZI1ga?BJKN~+Q?OC_AʔZG!r1m{>2Xz|>Lmw^ T٢4 g m}a#jkMn'8%>k6 )Z);T6湎u2.bʊRM.-u18_}z}_`" _>~R`D d2n@@@ rpk {2^ $@"GGl L /5FP 2h1ў"I*YI 4Q)R5\ uN:ZAmX1t~ςd\\\^q.tzXQѳ`N 5KZRkҖڔ'>$%rei)p%^ q !a+LkDnx^E)S#, -8zu+ՎEDTDhʕ{xpSu4=7RBKPkC~ׄd<0zs >h8GX f@W{ʦ,ʐ2zE==&84}WRX.OCuMY$I1oeCP`gk|$𞠪=K |BO2qF,}*qAt[ٸ50BbH\RD.FPi[iL<*: XQWe&/ 2 hUxdVؗЪJؤ[*#deHRUKsLvrMaD6 W.;9~u* ܧy=,Miwԓ m8A4@.eHt>!7 ;%`UE=cZR$}'@#]3`pD Hi#,F;8@s{ hs\ BÈA!JAIX dX$D$ɠf&!oJM1*[l›([JbyV1Nl Т i!OO4-΂|9P5 4PyHe!?Db.l[(uRʆ PT4.f|)Q[hTI%AD&`( 2l@VhOhQC!y(HNPH44I/aKA@KhP8M ̢x'e`%@[]e4  "rʀ)hu~TIX"7QVRʹk@V26RqQFu6 =6R6!'ѲYGR Ohߧ$ag!]:+H 5+')#}VRHKP;yDjeffߧL\,$u4hѣ^VF5E4HQ,;F]-L)i%gwATsUtw$ u$iE蔯Cm'$l䝱ѡITTRPUĕ4 m^V*cjyE 0 yKwX?ͅjRš1*'`f{NtrD(Sd(P͕.d00նDZhfwY;&Vg} n  T*Uj0ױ c2[1UVK\L¸ZlWV6=C1uZ$CF*!L#hj<͚,2gH i9HILT&DZ}U$ E@5QB,yL&oNH`1v .@ 3[! +t)9Hlc1n,`@0"H 1Ra!i {cXY!YУGo 51wZEDB(͐ I[LTQ5T)1)#nPhiPb-͑>V7]%b;|~aיGGp\]񽬟xMG z<'B~2UmfW3РqUMS ck[%`f=Zz}fڭ->sy7޻\%9Iro%+*?3fF)<&C+uV –4\MaAlH@QDLbɺVd[(O@@ 3ThŬ  ,j&gK*(AC,9f؟O+&6z~ hTWĶ/ !3\O8 P e`fP$U&0L`rptr–' `^qt b`l $^; &&x=L$`oӰ8Gdtԅ:@&jk@"[,ZQ s "JuAhaudU \B`A-@ eN`I@"6oa r%a3tp}InLiR;+y'_% A-,%N3fxʿNA:ԴEo-B#,29 == N<}dU\X-3{_FU- H세:g1uՋ+4N*T9p[CuFPܻ'_+6!V'囏(ɧSGdtA#e`ߝ'o(lp0ski:Ȧ!s5 m?av²ƾNYcOuZZ_k&W .;GVةˑnZ~E@%UF;*`>~to W VCL| s\2tD1"]M ae*k8t4~*;S = \}܍N7BMG$bQ~[:\)9Km ފ3%i?+SS\g,qz0z>Φ=WRpv 2fӢYI~8|w^l3wEdY4\g #Krpe(cSOkW S q$H=ѵ2kNK?];xsy U)|6p_j<9e#y+b X%~ ;IHV( {eScAͧ7Hd$%^(H@p(.l@"8Fg7R42DtX,d)jq_L{OOb#ĝr 14utL6. @v[IFmjOG&.+3esd1cd!xUCFMJ(b|ɺ|NhZ3+s˳6nnU Ġݺ%Dz.˿,;T+"~!܍ 3eb 5,]"n("q6: lI@s2P֙3!G6Es&nT4S$.stcd\x!6,F:FR Ұ(!dM, &` 3 lE조##&YhJ,DJVYghhK%1Ni!YB*7wբ,C;p YqHE{&P;@I &Uy@&-S@T}Ҡ,_Th@9J bH$ؠq1F/쁕1SAۦPQ7cJ].}ҡ{Ҡ, J1mh hL?H l(L%@?š{쥠$v2~J#L:1~;,=/@>N&N l TPu@Jdm,F5ui${Toĕ\5SJcʣS5bW9HE_)R_*B 40 1Ox WJ9Dp1N|'wM rk1+EL] q[UE2xV3;ViujhFZVcbH[D$[s5䮅"̬H]1Z;Z"~fli45lrV9H`l)L`ĠvLX$EB`2A@ `s tt\HI xI xHh(]MĄ $[p#.d(l:aa!gBp!XIl[uDط;+D@n8ИBeZ"eP k&2:sy*Z*'N\0ckAJx4S=_ 3[FPEy pLzQoش8 jt1-bPg 1| `/ x[~ˌmme:dmdUt)Aá7GL=ʅnŔK)-`9,,P ɴ\6wvP2Wa t^vh:4k Ak)4jS?e(SqdS {o\-i4aҲ8;E !䩴Fw͂n'+ғ\HEi;I:R6'|8pN`Q e&RKcKdO5+cN\U4WV'\%YZ7/hIM&M\01J2܉;sLwb]v>p {>MR",!͸ZB ZvElꛎX'EfcWAg 'iC^U)(Y!6kL &)ɿKUaThYXy bS2t}^N|ta<[gkRwn\ MBfSDѤ)O]|$}9`JBˋӝw X$9S_$@I~ Ai9%hVbXtz8|]3PY6^/:]^[ji+4^ZVZϢ $:fPHx<[j;-,|%K*swFW^Xo%j8n\܅SKy (m2 8BM)Rh`ury?A-/{d^-в&le&f_ke!Dkf4jyHv| eAdHeZAC[%! *G!Ae{#! }JH"EF Cf|=:j&\ttoԗG?xF!E ԔRGj{% vt(1+g~4܍!tJ:&&'Q.rku3<ћ4Wwu`vu@01QgJ`d0n6]ɹ\N\>i:vhL:=np-#ZK?)uYժ0ay 2>J$eo*]b):H]UL<3: (|w'/!r_Wr>e=-/KOMkVl+E&}1,'U&A"RCC,@WtX'j2ɛvPT6e[ꥲ*#4!RerH|՚ B F5b)s󚪇Mk_'xG4.#P.+j#_'  (ߐ]'\<{a8&w;]{lDhoF!F3T Duإ Lm=|N7JJe>-+Eqn][wѴyqˎWXvdzrOk1`ӠW(b 2i!EkᨧߪzټqrJ. 璔gmfΌ'vj_TXvg Xv:T:=]X~`o!z9pzcx}֝'KG5՘].o?i=GD`q+ɉgELI54bd&}j^s̄ofX(핢iI4d!A\KaZ~Y>!j]Ke69ӡnt9 Bl6S\PoL;:raoe AA $Qm}PRHbP0@S@@Q[H8-!Nnf-um]-%0ؗ a,ҿ<tL=ƫLbIFtzxKS.3|ѓCXup|щWKON FgeysGYn(:ARvO*Eڡ!tm⍶?GJVNu7m ǷGkKMĒd,e"CӶE.=PTv5}N/ڑ1E}[գGUeI?)W5J'8/nn]}r YTLm+B\HꟇ]7k+*W. tW&Q\Z]ٗ,>2f[Ʋw^.c:>0ά[D]n4 IK `͕ي;aeيb fkŌ.d&(5wqfTU0V[ {rfh\\i4Wâd(7ƈ+Yԋ5Q8}HI Z06JQ2>K8$C3epl" `O3|&HL!#ƴG 04R?Tmm>Xt9P @LCBc!a!1a!{ @L=D)5 A!p3uBcZx D1, H81n< &ʆ>7TX 8 D35F*) {dT3=Vhh^ٲ4O_i@J*@fDzBvT*((9%(A?(t)PX&'pEF@o)PD@ >P B1ИQhE\cT2! 0?t E{c P~ 0$ʆ'Qam†ݎPPAT9!dӫ1$B5ҨD Tkn!Fu @l6P*6ѯ̨e#u3EQ~fVm {kiX#E*I#u YI-+4GsA^W.HQi5k ,ru g"5p@(4#g%J>Mbuڱke:}HpN

#H sg:s܋Zb*^p~UEO\&K9t[mrlN09[BnP גr4L\^R)0܂ ac5璐kɺEct$ &.PB|))#>P52KJ^.Y)4yMEzIsa/[5*1?iƱ,G">gdB;jO['T# ^Yb%Fn>M[؅Z)lQUOx^qqV*g]7QۨtQ5U!Ԭ8,w^:(FJ>ڦ}+єx3I,~Oe=WUFS'mU$+] 1r|~A:94i:66\JSvmE[>Z4*;nIF?5S;Q>oם@Ks6 S.b.3:kjS4~ }_'seRoiuBI^@I,/Kҡ+#)H]hqAVvƭqi9[% *HcKGsFM^[,MweyfqٓCW\6 2#Qb^$ 2+lB*3)qz 6\!g0LF_wZBO! (8:0?1w 6 "A̠`[$a\I@FP &f fP:EP$x(B(ǺT$!!BcšBBTME .9T"$ȸ@\AC@Qp"-*!KC(9,nL`\m*X4Bm3pVr@j9fЍT'8Y3K*ʊSad5Hk !U:<,(NYF4GCNHIXI$uH" ɤ5V&$|._J e0'L+Xvkξ˟',ΦTDA 44ζU9B:5Y5LR#)RNFUUI$he_+|m_)>:,r;`hUp&4A n@Sʉ*V&Or$ti+@[M WM&vQR1N* 3UWE5 \#Jh 3T+ 3*U :$ʢ3Th 2UbC1}`fwd5KZd6c{Ftź-3 &R>@ƈ<*ƶ.5dDXT@{$ Caq|Cx Q4-ǒ@He2&'XL7c(cP3 - @Y@SPH1v*YF i j b3lրs+(sfdb'½`Bi?tЂ8T"  2HC~x4H.A_OX?< V=,ir*4^Ț>Hoe>Jt-;.2]1C6gk[?N`A7kΌN#p[ZKfD\?a(ła-ʇ Q:#ULMV?2qf@sd'=I+22T#hj[IMn288>LZ'hu:ߨQOD7p/fy eInWL7_+-e ii~-kPm N/;O\ҩ+eL#-2w3o=2)y^D.('CMTgDLɥV+l~rD_?S ],R fOtD2\mFN;˱7 ^}?OUCdbF##ERTϧU/\ze?V(9$ ;ՅFWY`>uTW~2ǰ ScW"RLCBOk**5 nȩ;jAN :%a< jLx,jt'2.k ߧy7s]3[eԹ2 ~X(L\@0DX~8@<ؠ,(,TAMҢa 2ڂ}4jw(Hq @ &RRETsi:G|yWSkSwWN\x 4 4`WLaLlPZo?qӓtʜHXQ߇<ء&#kzXR:.%NP>kW.|m;2E0d(DY<]<.kIzt:UۜQIf춴[7HϸJ74x'ѿ z,^H.'|_+\ϥ#u}7"x6\}$W!mSnS6vQ>]cy[U> ,V>cW\64l #6zre:wBn${{K(<ػ?lمY-͉$ bH+& ,e  $@2(P`'hFSPI=BJZ{!7EABBB?R @ړT= 45T.CHcBCbXG<*E!nʐ pB8e {{HhSILfzE!dDŹA q.(P2w@ @GyB*h'BP0ALP_@@TdQܠL0*m kHha}Ћ# !hD]BT*!p mMF!K@6]KCe 4& JIhd$eCۓb0L^͠5S|AY#C"Z(MĨ`j+9 ʂY4iPYkRpC ɢ:wdh%sM+$hƒpi[+Iv4<5L*٪g_O_hW$DKPXQ̋y@>NƗU#+pDΕ QĬh" (@&d\/:C+_)K[ wZ?p#*@W;(|ur*`j|MS'P+Dh;,dRi.) }rjhfzfҪ112MFEj:I3>Rtz@Tnʓ%ZU -T춉,7[$C^{,Y2Xh,7p" (Z>j h4&1 -=_CR&`Ua!c e(R(&$Qg"tpRbEHÒce I {%` R2L$ {'A$KK|D$K*P } , #63 %T;( ",Y`^ED\&Xl 2QFSqi.-Yn\}6kۇӨ!! YiRN5BS_7h G_7ګtB FbR˂ 'qI6$4V ѓUAQNh<-a6$]QLH]IK \ EkA$b" nQ>+LS|9xYeǷo<}=w4\;U? ߱X%uªp 5JX!pCJtgqǽij9G9kTUijĉRѹ[r H6ԖMje S0);ܧ~mTیW;[:-u"H{G4GOIlfZ,u^9}+O4tMӜ|]cek>'G3/k /&KKr };L5]3{FI|p6dU?Sg<-:hG18,H_p2[%sʁ.0K&eo }Z @^߄enHinECMafPT" kj6$)tOettPG+CS`z}~υA2V5yY>j{<v_JOL|$(6PAi辽vQ%=EJ /3tDm??Ǜ5jһDj/?58'{GMe57\rϫc)6n vTA0N.92(CF/C2XqZ,q._)̓Iv]*&: I]xW,uD E%zzHRhwuNXś, y\.v$&AiXe [^ -F5,5h8E=p|*Gts hSodŖDQo\ AX@@a0 0,0(3@ k (5򥁦T4ʖ&56K06${[9HM߲qd2 JT**B'@j)Ps+s:ei h({jpoTi(u44 6V"{C`{+C@:Cn@)H%S ihL2/%+lQh Ȕ -d p .QȰE#@M  &HHAHh> ӓt}2JP1M*2 0(ɒ2A 0",n Gu[`bn!5qYnf԰ YFng KHMc4yQ!ny+)ӿ #Dut -m3(hӡRN%u@9-cksf hέ*FNE5hkYN gSKɏ:@̹e{+R˱ASVMm 5MM2 VC(H`{@b@@g* ]`ž$I.>RO8@Mԍtr;:31%B WDKG+xɗغD\Z9*Dp E[R&0Q@^Q U6dnae8S.g,:ɞMt#i^<ےoAlQ@UiIoy9ZgW(ӧLPμ3c5 O e.f5G e8 @lIe|1[wA 5mDZa.1iSJ̒0Let~,1i_p pSl{'o=x>ө:*6yFOUJ-4u2.5Ev,]Ku.*-od#wMnD-QNPTMP޹^Tp!71>РM]J阩lt-p;,vĴEfxԠ}-8ZF,OolIen2Trnʍ#s+e5:4ڭUoR:#5.M> D^S^Vu=v3JQ0w?x/rKOx'lLtesel)cݪ!-Nݻvh4E5? Bn2%65:u n,KUQYPc+Ʌ9Vx-vB2`|2Jm>Oj,5ok kԍyjg2i; W Rp{]M n5wԾ?:}K\."{k[<'bZ~ORtZ TѺKGӂPH-Luxh!*x~q"\C8 ֫O,GGY|cp-`z|4k3+q-Bh.C@ǔB1 Ah-6%^C>>) -=R*!IU-7JT}/՚G,}ZBKd F'}4pB+>(plЅ2S8rtSGn^8d~l HؚqkN¾Lƒ\zܨ"4F. kdζ岽$Wٶ5jRljDZw:׍\Y:= 4p4fܞJ7J'K3z)j*6YM@.MJkZ>hvǵRGUM}?ި+8xژMdN'& Gҷ*'v}%vФ%{qjv-K7:CEݧK-Y'|W:uRѷ'G{?I=2`.f=amdJَГwBr{קl6H^T'̢L%Wʸv%t;hs^ur͹xY66ZQ5ۯcv@\ؗh cPE1Cq<K(e eC9AC[ZJ=q Z '( [{%:.!42HhfIU 4Pc9RnZ2,SD} bֲ  !d4rBJ@ܠP8I@G(rPEZ*iP@G($2qs>6d &CR߲T*'y@KHR:$ Q\[ DxeC@PPF:e(8+7àƪNV6\N(Q41yVOʺ3dJ_QL UUg՞UQ"SOh>'+Unr6%$Z!.vnDI%'hBjDdsbbMZ6GŌ.*(vI#"%O<{ x@rN;egcĩNg` {R(L'`-th@QJ::r26HMv><&Ze:~% _fٶF9ݼ$qmq w^J3׏"# >r(׀ZO(n$RԪ+7=&iҸ:k]MKvtO_]CfO e+3Ɏ3L_SimJ6QM9᧵r55j1 8OFlY0|z*nA˜c4fT˱d >. 76#<%TiuG@qhsOnꔥWVZMK6@<.9)Qu|V~)v>Ǧ)Ff܅;[5=5&#ڥUDUf&d@4 ; }.8-Nh-ͦreݎRO\YUm7 a!c8Ȏ7(K6]w53ly|3e7]Лg|^_N+iŤǺqfMm(ɫG-CZl\;ו?W^_RQӝLn!/u92j0埣56#p^~Ln.X਋qieER.-9S3Rp|;SI{ٕۨƳ|JR6{܌$NNShhY#IWi+lXLO M=c{gC0E3ݝ3I.iLFrܨݡTW!z:,ȼH8K}#СL3iZӭҋolx]p}?ӗ<3>hW!qFjgHPnT;8JduٶXc樚7eslL+jTxyxw_7>_O1.pXƸFt0y@)l*!' ,T6' 1)rAbRcRME&0T1 S}7 IȢ5neݗ4_cY$a{C@yƕL[vU#L8fƉ"|H^ vԊKnFu 64Սks2fXc5s;I\ܹMWGulźjJ!@!=2+fIpzj=tKHFVIm0-,F2R>J9u <_vˆNE|\v8`m9Rف ]JI ir̖IGgIq,7W^4Z*45m UDYzڐݿ|{y" _?K`7 XFeGZϒ .^~: : ņؙT.y_3ʨh}&Yw_,Ud2&W7͒ 7X7( ]eE_Th.^ fw.)rfȪ9 &럳&cR!V<^;N])]y\,h>zO~?Gdٕ̿'gbAS!)Ce0bU /` Ѐ$I(" 5>9Ce&Y@ h&&5 ÈJdd$ (r(N&1OH;Bi K)P ktPkjFp *Z$s*S@4U<&G ܭ!E2'4#E!fMŊEC)&8@t)'@[@ɶdA#I@,^.6@1d @9@ - ky& v iqq2<0)qȚ!E0VHpsO7 J_Biݡƽ JR≔GRH|h\R;uCTӐ7ԇCk<[lkFU.*a`4eBCgW {k bl]rjV:jӎ[:L3%FXmS4DV1+d%kENɫ>beKV:LաȬn{֗n 负(.ӣJ%:LIY_ 1z_zގj4m,&]5 853%sM: sTߒ?n=^M4[-F\2@e:>JktCRān8+,h$zZŇ IkŎN/k+[,لgGFhm{FveĹe8VєjFtW :1Ԏ%u3YqKCN FͪP 0Skh|3z'.D2}OZj!/Oᆳl|p8OfʠIi oɦhw)WU+rԕ 2 ¨E&18.R&0/cK(ZnkRnTZEŒ6N&jjnOreʡ?rϙ6nw_aò':ÉE|%w/1ɓ4QuOLK1fQƦ=GBH:<#g:}RFK[#rTkeIE-{ jA'IJ&N uƎ~3tĒm>|j.4xKUMπ<_S%!_P =4dM.00Taxxdm(;~kil𻲿c2gXf|{jZ ]8ac9Miq hnRҏ ϸ#L$'%NF~su?pYHug۶OMG۟H{幟p@kd!e!U ?,Y Q 60 &D4@m`@h?tX$HM%Kk' gÀ,6c/a?d6LJMECxJKm&SCFw:Ī bat ڒXƾ0}І8(*CfnR }SH !ILnT2".` 1S(&e@lXc?Der(k$ -h@ {"J)Ͷ9@%D0o DŽ%o6~xH@@o@#f@PE6͉%K\R$ 1e-=BCC n'C@"͊'Ɉ6fm(`{\t408p%KC i)`hE]3͢Ah+6GCN+˞EA24L$HY3DΝ @YI XHΦ.D3*'Bq*Z6L{5K ɺH,cu,e 6鵛D~3}-| i=fzDQlX ')^0 O RxII3% {t"R P$!2xFLP#d_аCG1f4c&?geґ`B"ltM6C}T)e"$  b1bL v\vL4tGwQնk ]>Dߓż3XP}]ܹ>ըφ n 8)Sl)}42j04-0ȩheG5ji?3iT4Q,wp+XF'~UFRqUnMǒۋ4Sy}A]0[]ZM߲$MsqfVΜ&ZfdyXIzkk7X!N3hG BUJ+>qcv1Scif܅Q6N"ZI- mvtCUĒ.fͣN^mysg\l3k!|tq|sӞt-X>6p^,1i11?kzGC=unB#q>83ʩCۗ3ūxz:a#k4ZW5TN3AXf'Bq>EA Ȉ6~QRiΒ"+geM`I*Adipb+R?MTbő{/g4Vf^Dz:dі rn0c*@nI}F$p{QY_I;GYk0~{K"Rg'׬H][A%MZ@{ˣܮRұGl~Ǥ:gGSfRix\8\|S?|i{Ѐ pGiU:V:,`.xEc~}JdGv S%:Jec='D=#QXSkY=+X겯F7{1u5t~;{>Drˣ\8av0echL.)YHmgau2CjdY>IF -tIEQcCYuq!fRMVk6$\7dBj=r䙜A*ˢBmL0Údx+,>aSLHmLh+vK+T?~IˎeF+ . #d2ɿ!T *@`Ls<Zx hcF&i" a*cHF M܌)++gp &ߺ(,8 ļ]SJ(hC2)E C T0 N| <_WP"p 09BCHq OeIS$nSp' 0 @Gd y&mɁD^R`ټ$v 9P8(ee@[ɔ 6 e@YoPEƶҕAhH qd6nl&7@ot, X' @MV144H Z Vm ,+60{(!f,hc]4P" dDʀ>R({$ hR<E#B憎XNhoXYun%F:]bRf"M-aRcHBhAH`RIRdd J@J@0ٔ N$0d n0By L ,hA W$z- Dӎ&m-.# "ud q C@9 YHu%>B1'@8I'-Ŋi)ki|*)&k覧nAmYOczN]i/a̽ǩ>v.YbpXy*rq3:t)uI=żOt=b)Mp-0Rn7X::SU; &PT fܽ9iq0S3ot^޵[{l VK'L-&7~SO>Uu*,õ#ihN`⸦RPfJWٱt ،#)ǃQLfk9߾S%RfPHBlv 6Tt,rljL`vRNΎP ]ǯ8 Z)N}Waq}DZFqemZvGHL2gOO70lGI!br@Uhx 44eWj陮Ua䀲pyLa\)} WB7oK9X3SjЇ>VWQ0o1fO8krL<KQ*/i\pϏͥJg;lez/K#A'95?a50%zI=ƑN ai{!DJTV4\+>sONK"Y6K-/ MA|~XѦ;*T⧹-:\I=UI"I%26&NB+<;La}Fh$y\ÄLзmmpWx5yy0-DWųn[Xtm1aįn/;zX0Gg<8ѻ#t⹠HM^NjsqjgC3ˆ|JǰH٧j4MUh]GP\w^&G؈eJB*:$R|^df-u*iSz1YC j9 ʚ|Eֿ(uTG:* :"=o &~G`Pc, *9"; - @ 5(! [rk `9=b)@Z<LE9 ~NGy@1#cJJ(,#Eb p>@ooM`Rd^*NA*Zyh ,Xd O+6HY0.`X͡Mqq+&c.0@0L&RM4R7i߂  FE@+&R . 5Үq+]-I8TĤ͚}UrP:ma#? LQO?KKu"p!8Pmb0R4j- qAO[}fZbخY*eK`_!CŰWFzZF67+u9GM߯rN+SZNqrnXfrSC5YQC٩ ' *ƳXAO4[Y*?c)]tt7hM+"g6Wf86v)@lO>S6%3(K Se*byHa d  0EťK-2 kX7RvY3 6w2BP[R\2ƙ518WZz[J)np~Q'\ǝ<5GS{`ÚV+&^┣gKGԩJŨoO-4>eɝQuZ~f{'Cn(sw2`h-fl-!SJTgN$'nU49biTkTӺ&fŒX]>THܭhx^>EQ\|wDg.*kQ*tμz֢GR6.Nl2@GΟ\]O.yr\<-r]>V[gBY07GDc+]4v+/*N;_4d4M9iXKG&׉xeA3sSJk5{_Pjid.Փ|mx{1(UӴ98}I╮ &=Cv,;}HTd[^ E5j/z*S)ηQV^9idaM#حcKfuCw~Dv*<+,n,͜?u)Q0 _N.cv hwrZ!~fh**қ8Esb>}Sޑ.=G鷷eRp{8-K/_x: fz_>[UK\.7}uڴpx\ oxf4tcE"Be$M[y%1Žښg ^$L/䪄x!BM&h(ԈlG!s'|)V8u X=-sL V<9*QR϶O/ȩNW/[ 7SωXqpn?Ng) -+ }HGBʹ-زU2jz:+0^dp Qft. p܌#2u-5~}r.QrZ]Ls=WǩNx%`pM xI/ E&qa9&EX![h!.l3as$a5Eg?X\bA~;4㳯0a{ءgbZ:Mp][Uld\ktu#0"%i ob jMqb7R^[([ѮF9 ݭQl@۱EtԠ^.G|y=Vŝ.YJȞ/UqKCcڏ&gmOK91&+L%*8nw+E_>w_yR>^(oZ'oH{^1(ow!k6ѓ瀩|Uc+4D^IPڱXL1L+liB48W'׽;~Rc E'Y>VmSk<@\ Q7WTcg1Njz9ZjTy2F j1s>ҴTWMconUZ/Dj#AĶ<qyeG-ԗlT{|lϢEGnн-VUKH7^`LLTC h mnOCJE,/j|w.&䯊:j:TFTf~6&W&۶ S2XTiB'TTUJ+1Tt^Ni6PllN %5 =WNWfRbHsՐSlqQFmҍV!20jZ+p#hF8"a|益p~mfv-5pLY|j?q%< oY 6"X[ HEl3"`Qef,c {;pB#U ;)bl{D$I#E)%nBt&d f 3%Q*c yb"Fw'LbkP"Odd T"@j%@9o(t|dvM6@1SC,?ӻ-a1r0,96'(H ̠v,G1d@}p8 BEDdpfE xEִl6IbB~=@-! 0Ko Y06;h @A )8Y0pT4ؓ&s4:88J143E7N~> m苬dMQhI &- &eKEWģE*hhۧ :4u2ӲѭfCC5v1\F1*c٭T8!\o.QU9R) @ʙp6f$Tq 1՞M:7$Ьj' qFUouKQe]ZFn-kj#۩ X}=I*KV{jAYli00J`:)$PV/'d)>$[J6-l6%fTľr1&khlu3p.|Gʖ'b% d i@p3Ho@!2P;IElp/i1Dr:pmŸL{;y@ m( i3TtL@vtsdB3hq Dۅ VA9N8ʆX)lt)mkZSAaJA#eJW~T3D蓅,Ō[a7)Ŭj"v4;I+X(63|җh宷d|U. /i1 UǙnڀ!] 3kZF?PG{ m taAd49)[(Q_8NKw|3E0MS:pm䂥Z&[yE?k\@sFD>8;an(wȾIZr^l*"'V9\h)CՎtɚNDeB.)E6Jt {>պ(6kN+Hqj>Z\_ImM|6˻ h 1q#)T,;mk qdc܀e].Tcei[f jU$a?]*jQ>h18d_u~5ӟWf)ٗym^O5߇>EjwMS@&#\Ij4Pv:+k+r u rk4.Veq'-3M{!VZV @CQ~3iE^R.i=9Ly2vIhޢV|P Mm6e|/`"O\7t~U4V.dh)u}duh# ƊKsvJ9PeWj5qPhv2wk~HnV~r82Ep4(62Ve> IIrLe~&ˑRg,)u:QwơW&46ǃŮёeSpNWY4t~p!qG8{c{7:zs뛹ȶG}͙F=}HsK>f٥Bl:R{Uġ`bW'RCieml/we)'Szow?xYfQg&7M"DeX f|Sj]UbӨiz8{ž5jk8'?Q=.}X}MM Gi'sXb>Oayr|YXuk .䧒ROd~L d_O`ǽ!5I^6+J| ^oljp1ř&.VSeœiTnݍOŹ3t9Ȯx^{@\ ʐ.Mt)BtZ}s(OU@'lhZ%}!;2lC+" -T: >6٤Q|^{ Uy'lC 暴bG1?^W`i!I#hh_,DϙlU&2Cک1D@dD`>"b4B5R#@kg&IB|a.!D 2-uqSؚdxvgx31"fzLPD32ęfo~I{B &J0>ƺm)40:e:ׄPJ`Mrxs!)ir&7] 6n茠"E0 hXo<(mD.?e1!m@i(!o*m6 0$/@QI",TO,=0eXPЋYdtL,L @w,xPcMu- xMKCOH݂N†Qe$R7Qvc$R7REcZ5S+6CR+6ڱTR U38*Z(J"9DfZ,Jvl+9@wFjyg(nwYcuRlJQfN 9$P`;جW@q&U, اkˆX˰*\18#)ka?f[c_ 8|Pom5`s ŝOzWu-l+K_fz.=f7koOtVt PoLw.=߃z̾?7χ_~9il/M&7^U54M#j~Y#FH&=y)!«E,v8ލTjFmc|6FBSbe@ժi40n*6e_L,Tp?GiH5283bpgx#-x^Umc)"8(ڒǁp{٪$u2#]4FBdw lAmEӄ9'KTH#Lж4,!D]FɂELq½6MqgN=n #V6MF6##_K=?|s;\ܮch[< VrNoj=_2H٨su/hzlWҼQt"˶1}5f=cIqrIrTڊwzֆG{tsjorO;]!r5smY?q-?4,sWyܾ%]?ND`fOAO24ZU==1.аȷo9PsOt]7S!h)ūle3':[[KfI/C}kMzh-YzZ]z y큾,wD^f7p 8H'BV<sW벼lQ3e_5hBNs cO#(PD|Gr)B((e [0Y55ɔˊ[scc[oI lac\pK3%y[ʋ A1ATFtJw}j%\ PWm1N\ҝbYIWH߅{'Gp9`_GWQGb#??#YèDO@G*̈́HLxWb ,3k"b1,i&RC e"f7͒%XmYMtEL{*~<xH;PMʒ0stP Ul$%E& tʽ$2 M|CCZDe10@0md&ae]yC;m)r SVႀ(p\{ s@ q q܀EŐ^a`DD #6&B 4lYmo8@1H(o@۲HR&H%H =\ MIL@8p L([ B{b(6VrDY0&pe"N42aC$*Zx†𥢇1(Re x8RƍTqxYZ6Qc$4ʹLB͕f/Դht煛ECY4Pƺs†;O*YCX!D90f6s+;*ZfCV1ܬ6ef[62lV1f!=qeȧjy{A~n,jIB]?!D3*5Q " tk KY?ܣmVMrZ$|HiF҃Ħ4S8B+ 43V{vHǸj\nHj"@6F:D-ՌnAi TU =JC-#CH>j>bH@bt\) $~AH`$ -!aHtQRMfe>LYĐPf`{`Qa\m +H ̓td7+H:"GYvKHWLLZ +()BP6yRP `mP"(N!1( !TfIIq-D^J X$4I-j46AXVq ״RVq=&zQi}= 77ؠIۛ nѳO -+hκ;UK S{vĭ;;2UeӲgD"4ꏈN-."~ kѺ鱍uZ?;#Iǔh<^=H.@ݑ 1O&hO]x=L3źgT5X\WHʒD IAK)/tҽE*pç('diR&&bHt%%:2ØHgZq<-=_*J;~> ܀S7pfRӵL,uu-R+xjqpZS5(Sv&fԩIm'GG\ ps>`,viǔ=A(sFCG\ro~vAKHiGq.U}w-tUEhuZNCU6\^7,vx#ok|ҫLǓݟS$#,CyYE8IIE>#EWרG/fk4 v`UXbnUf#YqUwכrbނNh-켇pv\N,4S]1Q\n#?m6W<+*|O'JwH꺭 l|*on?h\RY)#M ;i 飏8ƆC eES=gt*9^!-39t1.)ez$w]eۤwz/.'Bq=Lndъ;Eǔt#^5`6GguA$j+v/K5Oրǹ%)I5R34-bҳF>?qiUCIn>uE~&Z{{>#q*}3nCˇ]ZEcGNIcG7:_~Jx:|lvcobzú(hK.6-ӿ"'MѤdTvG<.;?R|ÎwR~$REJOG 1}XָОY8=Ž_Zm0b|x^q٢Qk]CE{/O7%u=guu+a4jձZ$$픕5k`/K |1!vh$Ѷ~nZLTSr5:rQ\!\!3kW0,X1U^n#*E%BJ%r+JR[9 *䐆Vv ;ݕC\CZb11DJ|VCL:t.1.I)*,d @(Ld\Le 00!2@@I@@' RPQ $R,#E=m1lգHߨ8?Pm?o]hp?e"~v{{7r(S$_fTc2?%d4Shee%NYB]Zxp7ǕTF5 Rtwۋ%c&j:h]tzgS̲-)U~|wJt,s|P.-TδZ G.#*ю6FU^d=Gl2I{(n.lqRZÛeUkb GxuW.dǑ*aچ[ʼzE4r$sFjWnWG9[~JЪH7X7p,SZ[$n92bܬ\CDH|+H9p6Վzg(Z]LBkPjݸ 'Lsbhգ|qVzmO˳CmſٳI} Acf$r0gp7MTwO*q7q \3qhwRҦnp/ ۅ,.IևT/>t5|' Ñj GDѹkWES{'$=пr_,j? OK:f`TN7]sxfL:P+Ʌ'2ʀ8dYa $?t˅`|;d\si"2 4๱,珴 ShzI] =p0~Oc:$]#S鍕ٵ?2C~1݊zv8  ̏./JovZKVp%jĩ+{xCɛ*mQжg 8>$#]5g<7Q55|s&.ڵ|Jv ]>%~3C,TR:4/YF 4*P' 춞YCkY鮏QB "Y9g֍L#ÿF-?.4eLܾt[MDzi/Sc3z鳯EtD/O5wͳ%#Ya)V#:T.L Zw*/@=kݩWry۳UvN`>h7 mZNNA^n2<5RJ o%U:ȶ^IZe^M͞5w}WZ!w[J/e3BP8CM\s&wF[UEM鬤 'YcϑNf'?;Ժ=0\?6{Mg=#htOm0Stgymt9Zlzng6۽#G+4#=fiˮϒJMG2Iwc\qt]GjUd(33Jw1ضy2PӠ߇NJ%gUj76vfc7xqHQ`cdaXa8^~QK9+ǔ.bՂק0a{>;E(^6enL6=;&ř+(b Ee6Zbl#CFнic#hMj/7W} 8&cY>J jClǬwag)R?iЁ""? Փ0j,H;?o#3^ɐ0O;1h0h@S& XiS~C*J(x96NeȌ1HM!X*&>yT #7TЧ v)RBUTNfsFe3sx =0 4R k7@׌ @"/8M}Á)a H{ 3(vL?`u@$$L@ $sk`fU!;a1C`M[ 4@ `Y*R$ldBT" @ u_I KB;,&m 8,f *H2@J1ʆ(pt^n11s)41~.YHM$`jE#m'X3]:i͢n YXj".Fu)P *) cT1k44:*A^@Pr /rAe2Y_[I(#h uKؠlCAV >7h&Ƞ <*O*CS[@&-1)8XԑiNKRm^:-pj1;43QCEXWvN!v1u. QO(Q[l,`̧:!*XXjoJ!``e= |V-*  HV%Lk(\(3ovF3  l(m@]3(%R.{e$MRʛf VH=d`0P0#$ ,`'D^!&K()N$r8xsFUJ}Lf()nL29gkm ˚#Dwbۗe4wM}b->N5iRAm(gޭ m *m=@ JM9n3Qi*#7|S.tmmFTAJM5ާ>XKp3X'WH~%m>NaKݏT{ېޅJ?iA2 X5:2+鸕]>mBkT.3޽9,\ \ҋR;FWf .39S1 K~lFةphKhOcRnţIGr~R& _ Z$w\sFR Yv_GOi7:}4srNjSP}exi괹 o}`GG >Z/KZ`*x9mg|HM'5va[񸒺3 ˒]kwFc}uR/+Q&U2)rqˌA6 J J9 +" *SXdZ1im`i nHͨg5*0俀6ЫjL~dt-X=*NOSsr88mjiA;G )<>'R'Yg#A?Wӝ+WS;TVeӖޔy:zna/"1x .8F{bǃ'_ӚϦaE)eR<)I7Zj4͌.Mhmp< !tbJNF42 j`fiϩƒLs<.mLӛg̩ͳBL +~C>a^Z|V)ox$.GTnu:JH sOhZbI0,.Ky%2Otd::T)R6t *M c75sϦ ;,gcFS0Lw6|VgMІgf^ZI4A3e ӼfX1[8۵i,k{= Dxr5ٷИ5ihɒsWF l2P4s/r܍啔z@^ =fu;P$dq'+Iˑ7\4tu5UF6-[{Nq;N4u2!}N 97ɨ+9ea{䯚ɓ{p 6DY>s F٢.,&C2:\nI ƫJH9e9&aՙjRt;4QĜ8iџRIyÊ?Ԫ"pP`A(b!dźL@8 T4,(iHA#@:غG1.X־N%ʤeT 9B$U J[T4H,KREB(v)Rcnh즇b,JDe&U-u Ÿ|RƘmt(@[LXPR | @=.2a0 =@Xrڀ/p'7(2&X̧`Q?t$  8$YX 6.$$4]7֟ka.PMT t*FWnRt>[8-XK. 6&  6wJ /"ble []&8I͔E!l `= >@}3xg"T &4k =M,ڿuCLh|YJEbf5|LNY4Z4nV,i8ʆ; >60ʐ(6 4K/ť*hFmQ'Xe4g}RDʵ sI%NOxQAc.EԴ AY i*)P*1s efY e&9*F2&|~A(ב)(0 {eUPKV&ě_R@ xZ@%`+Dv~si2W쩟9d.)4?VKd64cZsu'+GT ] t%&uMڍi7 gR¦@ z9Q41F^՚{ivA[ك&&ѺOFxXeNў]3-e_4x+5*u OsǕ JvƐ9&َLRR߱Y+#rtUيQBqU]5f!&g n6 얛 ,=ގVkR}.=Ҝ#L:̞#V1id.lyZ;rBJ*p35x$\+ 6SQJq4ҩ+鄷{Ӻ~^˥M'k*SŒRjH P-|rZicv)J5CzO6eVE*71DžBqqY|KG545_?utuXIĚ5ߺ&^O{kIJGIgĠڔ<\~0_95є]7LZy]:g}*:yYh}G1PvU /}&9DYɵDT1qjYf&=1̚Ju+r0ʌ\JJ&vLB[n0nAWDcCp4eayo#ZF_!L-۲NqڨmR %(/H.u6J OS(i +'>|L0g:]jL4ˌQ{h5SܭoW5L .l6O_ӟ'ӫaxw{194y6e dG i9&SGkӻ߬.2Z M^GdΏ\њr3>`{iG>8Ԓ`/[JT}qÄcՋcÙJ"Iu?NR2Y6)g+MY= Op%,sW(dzGxk#9>5*4*M6 #ݳ&zX6: Dg˵.T [z>MkMVUGf';q9&&0`O$4_gEiWaۥc|-W|λS,\QLçmT<|{P 튨7^N&ZW+Da,8IF4*ķHU|F;swCLǃ-gSx8KusjU.+5:U6+ݐDҳD)䘚& !(]z=,+*۷kpPX`5ɚQyLVpM}0n.P{IXId4)wGx'D:H$AS㓩~cHUA,_1 }4~ P.զy$PXIٔ%2h;&8& g-f$&!Ff9Lcb1k!1X` 1&0;U"ƺ*D2ɜi /v?7G(I{ .B`Xq+ A@&bHE6NNh.(DJQě C,d3‘SI.@-$Rn&aC\g"=10 ɠ@'行Y0G `€ CZyC@P0졌6*X]Mc,iM<6m 1y*(1nu4R4 YHIB͢k FU}W< 9Y px'f2 PX?&x)PuXM!X&PWR uY(^<"`rBi0S 6ҥ*O y&2àO ؠa;4SxYCT&nch?’q*dǽY_aRl R%( /RA8NU(ʤb̭)Q ב@tȄ[+ 8p*EPr22n!^,t^$ʖV@y% *A\͐6'Lb0"T@BtP ]$@r"0Aߥ&u.*%G`d3eB q̪1@Ȳ~lt $ byI% , eʤ&Ʉ6!,Tb"쥚D&D6&u .$g+K8U|."몭< 6)#5F g{ 㷔c(;UYU]c #ES*&4mve3hR&&9 3  G iށ}'M3?JPڸM#X$FaQ5iٮbhxÄ5sv8n|<3n~f; ݂_4L-SfXTQٿq(v94Φ4Rk@Dn M۝mrSs\còe5<үq5EiY19F}ãVq: z&v}6Y>QA- ȷM&t-BIQ#XNSi=D28q.Qevu,x5[fSKki-Kz#Sd:f^m3tݶ{)OkYz:Ή"7?Ee{zMVr4]LFPt͜8 NI 8(T7}I])G\fa ^ 2q4=wӟ{HueLHd.wfi*i3QFc IXN1iϰM_NCNtd;T9)Gjf:՛KhW]E sM"m'o$<} D5\\ptCRXZB!O1N8?\[%a6L~NvU#L|XNheQQvhPӺ]'i<v}t͉j1KOAOQk6&W%(+:gi?&{]`w(֦14L dLoDVa&ˋ,fsG=N/))HِX4LV51q*w?$P9nGhm+ɉ-3U6 PޭF9#hHZ(c :kw: ggx)1>+o}Q2muqT|n\3 ;kY8gf4-еNdeX?_UDkU䋗GUOMUM."W$-ɬĜT*2J%[sVw,9GF##)kO&QTx%=}/٤ᄷ>'W杜oSkX뮏_⸣E&4{({>㨶px@~$rVs\G&^:Ձ~]lB5.hR߹XEu_G۽/i1@yN?9)=J-=\|[H5b[A o6Kg:qH3 }֎/<uxa{}FyzFYdg;J-+5i)waz/FHo]G*vK2ƀ.M .Mdјē6F^GHiiZIi&c_ATICŅm ^Wf,侁 C%z(+eVy2_`ir:ڪIZb¤"y#\IS49:|vH8.xQc$, H 1r& e#)@ 0 Lk$YXxY d(Qe 7=`TMԍ6AA–s]С48 :,‘ѡ)ek졌{^Y4GC2ECCF<6<! ,%e$;4ӯج%jyhī j /Տ[~X[Xc ? 8\7;@_d /# ߸\/p EE&?%юr.ob`q `nb#2H} MoY&`}H7@dm"P4oL kCLHh]j TK!ʡT2I<̩cH <Ŕ\$Qob | 4S60y@6Poy@|$e"–ko.OGʇ6_㲔p$c2ꖹ<,2ktjʆ@W"gis-؍3F&MN⏔şFpdp^vݮʣUsTMSSo͡6Iϲlqi{ApaqmVr%;Lݸ,7p/,6e$g2VF/h7 GJ\3x^} {*RԉkK,|K7v$R<Iv>@iĭ#/Xۙr42f +赁(KP77Dfs4{[நIMGk7 U qH0GeFG.?ߘr˳yr>O4 ]ReGWg}uچ\ spf~/lnoA{YP}8=y_g>=^m3jzIpn}v>OAzyN /+MCe>ԓЪ.9{_B7SU Zi3Ni2g*0yQj\Ǩu^,$b&jcӑŭC]f~߈U6CcWV T3tGS|,ӯn.uӫ=F]u_p?=lˉ2)M\6yF{:Kt{`M.}WեggɳY XxYhh\I=鐻|jRCo/bˏ&qL-1 2WC54ÙeٯœS@F[GzW-4} UJsdm!thi>~JTWʏ|IUb8:+V4ںUý(>'uXQNPԁgeqjӨ渁3j첩S2mVz8心 lcuC?u.EKj?X97 L{3M%T;j?ʌePIR,6Au1>SZ͝UQƩc|z6JI+&igs*6sEcjH Ԁ2vζ٢NݦK@ Q/R[Qy6+jj#w.*j-Jkx挹n/*sڨŌjL/Zt^.]WHPI_it*Ts` rW~ 4ϯi'I|:kkW ]FjC0(Fo+/l6wxqzӣXlM⣥fgn 39jrR-H0I^BGtTF|*"*;,[^]cYuWsjugïZSMFv +NJ-~/+uY^iTͲAF(|QքdHl$6 ~O[QPSMq-q%(n~i1Oei4rSYruz;uG8@6_AU >:GIR9u2r[W J癲[w,[{/j[JHYM!V[-;3Ԡ \1ф$iMy1zx?@,Ұٔkz,5y:S>c~;Um*f:.k.n>䵞#&Gc\{x34AĖX*Xg> 5hJVx1K Uq"vk@ l!4MK:lŸBF4В<+D*Ј{U@ `V);4!/o)1Nh$P BЗ2 )ex26oRI (- tGIbq0-d[d 7@@< O&|e\ En@žP2@Fy@]0$9H q&@lPiИ[M0܄\muM8cH<4ptZ{G _hL ,ʞâH!M Œ)q(l,Y0,~)bK  l{Y2͌G 6l0|(` e%&T42Tى%KfcmpZm{/ }cJ fA )X$"5 ȱ8EgXPA옃i3!3VNw*EELIG"ɢ6@|}U*Bp 3~I0H Ɖ7Sb,/͖̹*,1)BƑ&bHHh6vHMZ?u6R@%0#bdL=4  &]!b2$Pb' pS.#ď[GD7Wf~#G5o$1u<[gCOhF;s## lϦ,KP%mhǑ$JvN2b}1֥."W9gT6^ ),p@Cg S-9/t{ ŕ- d"ێEkSv׏Q=tS@ȎRpOJ) &vNXɇroi˛7(rox[h$OQ =>^P ZU.MW-h!‰F2\K<ӸnɊɺfͿ.TOXOQKSa.ZVR:#' ^W>6۲XYc~! u=Cket!(fu%LZ7lp.8xd=,[C[L:BۑpwUBnaL[XzI}k*S}FԝPԙ͍F\2G2^9tkk8A[}jj\0L` 2]pQFBTR99"%'T7_б1mEs> dzՏ7]?~`өCRXXAZDG [o I >[hpxVUKO 2]2*wSsO I~6)W$pi辎?[_ a1#_G4ڛ  xGztt鱴4gR'~ɼ9?S&UuvѪcXJŸq*ܻG=?cȹs1qLJS1XZLgWcMtb[U0|i89DWNGClW{'|Cu-ugt*utͬ5pQY5k?StufO$\ dQRttXrtVm%jUu|mt Srvƙ?R痽5\NtS+:*PLwi2f~R)j~HMt叿<سV5!|>G-4yoy4S |,,g8Vb$2Xm }De  %#4K.1iTahB"±0̐*љwV3 vL,~nm { C) sL𥔄TlxRZPZJB\?,m(cB\Lĺ BDX,Y I` bP^Ga@ɺEP"@<=M@'DL R cB/tra@.aB`1VZm+ :;& !w 7$"od&rP$ʖR7H'B[͠`B@%KQpQq JɃD(`-͌  Xa!ͦ )c(c@ 6L*֘m1xL"i8h{ RCX&2k.TAJ6ϺFeC,0{,c–x  <ms)h,? U S#0XLa*Xq)@ĶTʃ ACG(F UO6Ih,`tyE *6!KC TU$2 lUPɸ|&0K&|X0lS@\a1]U\xZ!|\KLhC8Lm@P/L 2 IdBjŧ0@2LAnDϲO`LʐB+u] q"pM\i cA' i   鉛+TAQ,8IO%")X6B,F,`>%IH\9M,^*$@B J wHVC )0=6ZͬDnY&K:CȢ{mt~18G՚fU[E$^dۦ}>ib:}u@y7d͒[/[Iq^nz' k dU#e rvOUtq22x5i|[kNA?.Ÿ1ck2H鎤)jYPZܪcSm|HSZ*e(=2ҲbT?&샄,X׻RMS(q*:FO<2LzrLc[EW,6%M\9s@ezD,qKnHs6Vr OQ~'h::߆JJ{4ş[Y`u#&. 7\Tnj]fpY)vr2-.cUl)MqLpk4M׹6uǺ[,eMcPC-Kc]{$u,eC*2 nj. 2FQԹ~`JTV<*|^ lAtՅsTftswą9VvE܋'jm_cK;^!8*)e7FYjJҺg[$d$vdVm}gӺ?#52Z{xvxL]@DP3C5$S${OS*on?-_%fPO%?q̺v'x o*̐CHCA?^0iߧb0{/wT`kÙ+x,MV M3k|Z]^v3RQWse${::54Ƒ-93F_k4^)cZg/K x8ysrJߊ2IBF]:uviI-yzXܗgONCH`h&%tj{#vxoR;|G[Qڍ[?^lx4˶}A$e[hҞU魱-gNWJnX%`,rdC\Nj@,  *ɬѪMҴƛMI-ϳCNgXH'mۜ g&<\s|Aܩf5]tefQ3MfǁP[g,p}##n:Ľ'F S}#u:rqڭ&F/Zɨ7:<}ru#䒼[&EUV[ Ҡ|$eN,;9 ]U頱orbrՙ6 x U-ږnFRΣ"PcyCȑ=dbcZNy"CUtl<ép.⋧l2tA 5Ik֢R}5Cn>/,Pd}D9HD R!-eh1+H6²XAZDV?d8"&;nob6FR) x ]&]Ї;38A01"LcB^* $;1‚ēx.Y&T@˜@o(]\(bk, @({s6^f1d@(A (1908: v1"1 ,ZQ`"۽`N>e!H쁠wv( `9`$[ }.)2 YEn+) },2C64 m<,I4x–1졎0J1$ (9-@DrTԱeKXώ)r{_VJ$_Ơ8D=\r7pAZ4d`3s9{_fo*>a.-!s͗&0Ѭ3\q$<2R̟K.NQp ʂ(S9lW ݧGe'Mn5}:cA[e8TҐNOnW6LF9]B2/!]cڠ L3iԍpj7SPRDwzpR`+ih%ɛ˔AKSmm;=H)|k2:˩**`}]/\Ԝ8&F_$d.mKQ ¦ioer%,>l]| e}nQMO^,h5ճY*)vO\/JnM($][JٻޣѪh\v%Ũarz=GӾ4\7G0V'[y2K݃ߏfН{k062#+Œ'\PM39.L{3_E̳p :.e6wJN.ݣH꺾(Rʔ G ]:yE=jx<>=?Y7M- n$>?Eׇ,>!=Nƈ, @^\Xaw 5/L&Lo>!~ w b{fYh1P]:inaigRTgU-? ?;s@Gd3V0*Q`J@:ˁ9)/͂^;jf-I ]+ύ9[F ^6 G;U#]Fn^l{&M;H hLq4:%vdLѡ5Lq'+c%F-%mje+֭,r+J#TzIVuD 긵RƲpPT"y +|0)Q=EӫԧLw 9#g˞8)!ݗf))FBJQKN 91k&NjklEt9vB҉z0=s= E Օ ]FtOL,nJ2>ҒR>~Y^ZwtT4p 9<NlҞ_M.*uj~IF\]4a6hX=9\$y JP};v`E;VYPέA|8͑ҹϑzfQMpxHgԯU\$Tr}d (4&^GS]u&U$Gg鴭m*`.W_'j~m* kX{ySM O>Rk+Gpg,ZJvS\!3+V5ۧS/{p;Kro}?ӞaY\.U-T]#jWֺ--ԪIJNI(1RHc{k3#4n⼟NYaQv afSl]katBC7BP&\%ʄ:kmikJrj(˩Q9O̹g#c[Pv9uŗ[ _b›:} 7k*OU9$>CXtWƃWgΪLgٳ! .Ks<[&EM~ﻊuG<>E*nLPfia͡PlTixTƶPX``wTa߲Zm̭ 0NU"BM=8iQ SR)pRb* *X I HO)3Dĸ (e#3mIQKfy"ĸ_0lg d3&p,,wl!|A<J0< 0ŐdI@kɱ]k ^P"L >uy@5 k(ߺ ;[0(8@X]+ A[q0yIH$yhD.s 6n+6:teCC&m J$cMWk(`r9PCC26)pRe!t ,^f_fg) s,1RƃiP8eKBiHeҐE@41*ҕ8"40eH~h4T,R,;(V_) š9CC\q(}Eke'B--E $&N0@Xq䢀e2~) @-!'bDEпJ]'JPr=?tXaU.Bigϟ:iٯ:C2L7;8^WR9Oz$Y󊴟EcZAhK >5/tzbb .Z}U>F>W zsWSOt\+юh|ؿW{#G=;֟J4E9`}IrWT#sH ˅Ix,-#KI?Rvy Ƒ`#ut:{^vۓ2S%='C^֝p1ǵOX>W:uh|m<hQ1GNޝզ ='$W_y_e4 zhݨ洑ʱlgTXOd' ^A*4} =@J`-B1Fh!}&hf=C>pWrLJ٣N5@I/WS5zll=crIrut4\5TQi5FZMcT[J 7\JxB[L5lq -j%-N4aH-8 _J1G -}1&E0UQ/Qv|tJ=+8h%;0AN.<XݻGqqKOhu.l\ƣbv ̉ZςP:$gWůu=&/H)2VJUI䗫>FJih455]Ԟ1|}BƶZtMfgMe<x377X)j1yf|֝xihԩri周|?$$^/yx;Q,q: '/֒Eh?=9B }G}.L%|ܽ(5zik.+g}Ujjg.m;@6jsXKyy%wMg8AHLk:@X@gv;Z~=}ܿ:V騶"JI)[=d3=LΙMԜv 52?gGv]7jkuVtW*x8GSirqK(Y^]BJ\\W)zuzG@2`=U2ϬŤ[鞞:.na5>G_'K*mh+IG̴'A4*u"Gtyڜ :ep̯61y%l.FPpf7BVvXlPlWD1}7B 6K*%͗:VS%qeΠx#|ڵ54a>[xN~K|8m)[#tZRZꤸ W4Qgk,&W0 Yy9vϐl>H+̬ڳɚSڄm2rcren1XBr-N.m7T&0|ܪD`* gX'h{ c/e$6Va6VaY (Ps( < 8E6pcLEFlnFg{bBZ3–BʆRT6h$Z3rh7v1 G!Pl{rAXxLi3nP sde$B]9QP;@x(v#L 7 $` 3'(B&ܤC!gHi"&RT`w ap`n& @I qA@0-16 t!HFP &(`fH1 ,CDe`&I8R!3| P0&O!&RL͔4fò3C4S`YT25D(l3eXX\9R D\ȲH!I$7DfЀ."l L@ِl /w .A9H {%DJM yȡNrL7ƑE!2bC&Lk X1^)!FU$V!*!y&U'C~ VdU$3+ Hb\ 0qtK#߄bt@q vؠV{pgP&sCR&,MB D0PApa%6PV`f:tJꉓ"$>-X+P&8 8@a0 ; EnZ-*$xEdwAOE\$lr*SMɝ8{jB ډۉlqq[=\0m;QԵU*){b} ēRj8 ]gk_mn)⍶Gq{XlcsNS^2GT1iXBw*mʘ׆8m$c &x^Cb&;A<Y'NTkקFHm8C,l,aYg]1ܘxxJg iŔmq%:Z*'>Gdu"qu4ͨA72MXiTǒ5Œ|-7?"{'5ھQu=z%p~ PŏdLZMQTC {٣H囿aiN(khfp{ d߁_hdr,j`av1G^no.~Or~[r>WLtFIa=~k$ʱNWRB:`}VXR?5<2O]Щ44ۅզQ|/JF:%F '5YJtx_R)5Hc ycRGi2z#3\A^.;jE˳e#{izKBkm7\%=-q-6JNc8QF$+$;{[\;}fvm'dAǍ~7Fr5s.q$䒱#T/}Zdy'O;Y:QԙSkYB cĮN6dž>Fk7n&dSt,œV?szvZ@Or-j.q]4Z\C ntqҶit.sKmkU|&OR; NrƤͨOb\3h*6haLrE5B'' M[i5ϕj~Q^sˡ ۋĨ9B)L:zDUgW>ԢyG'+u4'­22oGN65rMErsj3m\4mz z汴p -qZV|kBwmˋ_YG(8g _.SOO[waܬrfe!>zN>ψs˫L׬X+NGP#k3WsI$Ԫ %m"{>;E-E(1ZOVMK o8 J.WNK^n]G`"39yNr=7&zcr9A{q}St/I)Ѣƀ1WSݑU+C){ gQ8"ܒ>IPusa%d͉X^Ź|}~=Gy86Y%G66+Ëj4]Geogy&mPbhᆕS)JI VG+rF93(WSH^<^_.UMn\HӈllgDžS|!?#ŦM9r)_x_+s-ʧ6?Fy*7)2 T`d66ycd [60O!LU!d`%R% !%R!h%Z%ڴDBamܕD28T0' b)23;p=eٝl! ‚3l L ~bb=E1&!A0!67(; x@x"Xbm``|EMwsd11q)mt7 k40) 0$)Ht)0!$db$l`d`7HupI(dJLMH *0br0EIo E7  2 XRn%f&k{p e6phcMɌMB͔i g"4,[(–PƲ֏ ;)l,e!@NRla AlJP%KȴN X A{)M,@otM0n @mQ@@mdP;(DٲM PƇ"ȫpQE MR@R~J_kB%А6=7 GbPQI1#+/*͌r]o]%!?(6ٶ(PX5I.II shAnћPOr`-T-ԅ0A!=PQBƙp}, *Ʀ ͹G)zVP*P̑Uty5Y05m{FfeG  3j[_f1Z8o }+jS2 Nxnl qqQY>Lm%⛚hmJo-/;*7[}*qN\4z 1R9ڜEeVc,}I%H՜EءcHOaubQE?r H;~Ws e"\pX& 8-cX3s9$MORͤIu9C:糮9#S0:MM8DžӸ&[i|: 8ǞNh8N[_ qh])5QhI›Cr^j{+ZbvBIIYk-uJB7ӛ{*J><)Hm |D?1=Jɍ#9`{d%&'7ʺ@VtOLOQ G5uL2sȼ.i/z/R{5D2&mWNo*KGܗ<>kO 5ţq_:jq{iɰ^-%mWe!8J/ GΨvgch}6l2JnU5gb=ds;VA!^ݩD[IҪOQANxGk' 'nmhuje8υ8OM<)Yk9aw*T{4:W@֦mpukmgS`^^AI%It{:?+CB$|WGk34[όT\ҩFq?/bXpϫ0zޝ]JigHQ̜.Gi9ڹ=?A=s`%))#IϢr|9dxWk^ḅߦFXNɳN^1텟iq,xFc>44E*O费O,qGtKtwLk^pV-_77m]H|6w+)b'Ooʸ>^)g: -#ǵ='c j۽7V#Q<#=+>i0ihK5z|)BYsW'fN-GYmw?MR{ٓh>^:ȝ#1^,1ga9 -2Ae鴚uQF28ŅS Q6{L3P@ Z"dݑV>>nS pV>K&y~;꾠`hU,EgGͽA]OPc7=w~ {}NQOe:c%uir0л8p"y) E!lpP*Zr\Qsu]Mysg]mGWYƞ{|1+>gyx"ܙTqvl{We56~s?,0k699dw#Wɨm_]2ISGן<$/XUʖKc)aX Bt/w'P5`5rƱ<+BcXyVlxp*Ddƃ 6VDHƘ ,"DL Y-2 d 9&SRRo%K3de;†P6 HQC*LĥfLC@YR)CB- P-ABC/X'C ?T)4[^9NY;(`pNnS(ԴM *El ɾt[)EYCAh_R< MHo )LR% b]Nز\ppwɀ Z HH@"P&BDv! M<@ 3M-g4IToPWNJ@NKX$G m)5DwZcitaʚ؀*"pXHʹ! l*m_-ݳte+STuPlM4Rc E\k)'b成i|^5itMu C9nM& <ȷ;'65)7nscj.AޒzBSk1WD,j3ގ6u:5cwlY9>鳿{WsXncۖA]1'(C,wA,8TmV;vaQ{=YZn͔c'5R}#FK&8,a(p Op4BP^bMFh@ NQl2FVԇl|VHGV*7k DrՏ6O:Yò̓13ϧYd̵[J Iobb|}ʅ+FmKt4kuD:>f{Gv#sqD8pW3]hj8;Hʌ.3]powgNN6'QJNa+.&TPvV~v.LY)?r짹.w7hW-2G dQmJ5e,Y86ߤjw#IV4;Rl3jYU}N)tt^z-?4˪QqGgP8}==Vҵ2pÛFeR3|~ ϋ%;xŧǑڣz6?Lƴ֧À`[3,uQ|FΟFҝER4lh"|,ҍ.]VeR>4S$r"DDrO"HőEz:L-'Nkj6u9]RӨZvm ž:1QN$B'tt:9]$ ]YrF-G5ڣA{K^hWG>xGkTqDXrx=C Ky1k `:<7}ON-!9?KMK_kvN}=J5$q[1r >T$.w)ztϚi8;]?Pڗgt:!)&:G*@u=m=-|WF>M8I~Tq+iI:?H:[l𺚯=s[g{#DRMBzͥMq68Ke%.HVqI,~O_IQ4tC%8tij%g}MkȦ!ǟ:p{gxFgQOY@^]McWߤ8`w\mϚ>V8W\}2CXXb|W-D+_nx}E=zlsK{FWR[qpvI\XO4sK$nHwr]:t_'_ݞ:6@芌W'P7ը $O>E|cPj?3)j=8R$, $_ oЬ[\-7*w,<598!ʌPclW]BG>\QJ:@ǀNc7 ~ ƴA5Ő 0t^@ld 0f@s,@,NHbM Z`X7$(w8Bm`T2Bhnl.c<)cCq0cFBe"(eXGc41Vm k_ʖׇ*Z1†&0)41O$f@E(@H@AY h &%`np p.|]TN`'C$0[ PqE[$@(Yz( kp%*aiE:o( :?t^6M ͸L Ҁ!ii RN-tP8+l  R`D V C3nP dIP!Ea2FK,G!Ah*$8B`dXp[`?*q7=ұљ-#ؙҜ3gB _l`b c7^Qbg":aDlg ipƴ4.-T" { ( @¢K )1a6tzIM#G m=hJMߙk\nl|-5H4TKWn/"La6"Qp0%ctSN[)pŁ[Cެq|m8<fo?o.aLc[M߲j:q9|*d IME#H8CUJ; KrǷt`2~mm[D99NBGE2xU2'`7Xg͗_]9OurH2[rv%v %Lx3~^Fv͈[C4\=)H,ؽ__twSsO矄͹ѯc=g>`| ӇFG]kOJ+ӟӸnjŚ33(uM4>Z4huL+^_MVf5.:qm,p\:zJ]5jRYg|㱛 rbɍ~YאfF{+' rSJ{j;2;yDdS('A{:fk>FUJ[X:[xpaÂaHɂERԾF2 ,rVg 2K"3MuaO~EutڊuSuR\,ʓҫkXjj.MQю0{UXQX|Oe nঌҼ;k'_(wOSG[s&e԰;G(OѥmP;+xRV2S]Z(ݙ8+]nd V;:#j>CWeF]q镨Yʭ3Mml%i~ )S|?Gs;%.|pѩJUi-sH ɧp'Y L&ޟջvVǷvc{3'Y!~3ꞔֵZ7k72 >]ZYxLuZh?tU -3NU*+Pj@+JD? F'eJf}JrX>[V~/t_IKWNGq>9]zIT'wR}Zګ}C~3zNzrmqr,-[GUm.&ZM4euQ9?=.*mLx$4Lۃ,TǧƲ3{e|߫ԭHӚnkbH & 1ї2Y[,M(n&QtʔU!cݓ$g'ٞP=ΗN\H"oͶϞY1m ^^uBOQٙZ\ }5- Ä́.IXӶOmG̭4k Oꦛ'Nh;txW4_K*;_SmVXx%юQWDk #!},VhR:m8 un23SeBwwcOFۤ qpeJf,| mi:-yTQ$e/i>=ܯ%lfKt=wJxcf^;YJRy$d+ԜdW&R7U̞֍'|L-Em:`,^M Us| j[L)rg o, ׺ G5^<2>YמswIх>Z ?'1 4ΰig)ҤCK7'Tu=@J[#g2+gVx;;9=x]&4ym.Q՟S {5®lޓ@Tm]k7OɓWkgo>u- 46e,IֻVJ  RM)|^9_}ZuK =x4xkԮxg1+(adzW!3Wl"&by^|Ǐt>CQχH\_Pg|7+7:k v^t<>SS%}+סi5'413zz 7Z+ډT:+[Qu=^..m N|H2Jpm[lڄs Jm +vMK7QTE̒CRLJdl県Z|rhʢqt]gWyI3˳:N=#e9;fr%rO)P[&+ *% XfTSq|ATݥ0mm{%@y"A}:>XVLZ!N{+D1ǵ+D'9Z"F8TJh` #D e!}(H(%&<)EAC)pe,!Pƌ) %E%(CDȈAV,LS.1P{_D]!0AM 6@=.`x@0,')3HbIb@10  0DT (0Lik]"NB L $s>8Hnl Iqo)9C8*XsR*Xipd* 졌{D(cC!C(}8 fR9۴)c41bf:OTRpFTo`1=1h )c afE +aQ d D;@'9A$`A $ZCwsUAeXaYq)P PtP><"ijlS{A`2R+U@QJt;&tXtdɾJeb酕؇bLM9HFJ>s ^t&-2{ -A /uctDBlpIBdy@M_)Xqqclis3gFa- a 6,}bE91Z M?sTImtǪLl 9L7LL4@ E?e@Qb4TLpX'_4upŗ33٩;Y9 qܓ>}5;5)6Zcz'Pc՝ ksf:!q代iQKUh10ӻ[ Is+jfou- ]qpJ(Znvt73CnhXbyU%Z%E(fMۆFnZBI$Qv;oQsi>Y[k[ q)4حEFBqgksNʛM<̬n!c7/9ZipxUQ\Sxe}3evBÞQ|p݆V:mm:W:zu1ȩ<4Yˮ9TM2k/'w+hs _ejH6zOͥ=;ioB*kE&zAOmv?Dqizme?ze\ W~;&~jKr>!:"iX5:?8pԺ=7iSfAy,ٗ:L{%lڮ+=gOpL[]Qp?׼ST:~-`C\vŨ7/j=|ڏS鬫I- 74yu-3zslaV$yF0TחdL){:1gqtt.6|o e.VNV/ 2ej:֬)o8=>*dmOѽA8J]em@0.].:i\~L!8^+֖Utsk5+gFs˚rRqd%H=G9͖x|6{l7gWjYӴtqd::*#4eIyH@\>{,tySFRhŹ$carHhuweRSL&iJ]?SkYBᨮ_gj27gipW^Yjw :~aǭ<^p.q=,quOW콜)ltyA$8]$gjV{FtU3QT x{sjklxcI> 꺽*szp}$}Ch'.7y wgѺgOӨV`gju3*@u; k\ io|^Mk*T򃕞9rˮ~3$oQkJi8^½i GӵN.8'5:1y_GϞf1켉 Ap|󒗷H:uMEGuR!=Siq$q*"2MVzΖΥF4#,}ʓ]_[]ڝMB~9(GlONJ nV}sYI|iJq$PUG\`b "JaBˬQ1kHm2TpyƔNnM-7y|i#s\̕^ K$ &L Q`8(&Ĺʖ \# Z>ԁ'|: t4?nʂ9@5׺{& 0),M֕hTiDuZ#6:hcI60ưJKߺH֐E¤opR`D0rp L`H@*[%%!Њ,b^ e,hZ;eX9 d)3;cK*=;eX4"n%nFSҘ1p$ {b+.r0!%@@(f,y)P۲[;?dA+G@ m L! Mi$D Ff )l/(ft&a # {%bc7 [)fX! +u%@pJeBPƆ0 Z:10GR43R({ 6e8Ĩ(s| X5غR[ 4>͔=G, l,5$)e!*/ .0&H #Lwdq EA(!{pE;,9@.e4p 0-e (rP t,ęAeυ@2 (& J[@Td@R­> xe=X!@qtb)kHT+$6ɔҔE7jnm1`QQ6]O*)>ʎɮP? N/eǶ% qfg|QShvR3v5_zt.L` vK&+,5v uf/I..Mt]+Xq}8Ü* ot&ѬA|-NWSj~Z Yix*ȣSDgP\wY>PP~gPR5p@TlZܧA굪jaRເUCZ%Fp8_ak5zjI 3 -|{6OKPl5)65FȪ=dO`XJ8iᜆ]bNGQtoN+ha!]kFFm rNm1_GPp.gM*8QN+h鋌lKVp^=Wθe=p.qLphk"R: ͣ8+21:g" ݣNSZM3 VQt9^i>QF Dd C7VgGg[#PCTV*&Mu1ėLԨ몲ndrq-3'k'ٶ PN]ImGE B'+lqpʲ|3⼎1&-o)%f! B[2 L,;ǔT`y< 110$&}7xMT8 ЍT9 ,{]hg5V5*,sO Шs$T0w)b* k $ ԍaKQ6͔ț$-`ЧʖBȷ)4 {DZS@g/PHC3KE!hK?2 Ȅ [rH@[8iDJE[@",>n?t& H7@I@q O &qLh!CH` y@ a M Aon<3I>:?ލ%^gbu=K5 MC$S mdrM,W::KөIn㏨S=F9ȹ2j#tkRDXgWm6NũOQWLs6qɇf&غ4HÝ(Үڍ`rVH2).{.SRUtu34UW5'>Y?u';ak'-2 rLAǾ $QO J3['@NW&+Ů ?n~6K{NGC֝F#[/J]&o_GηWT[hi'#ߟ(n]&:,c~-N2̹=Ua9Pt~-Wj-Aݸx\+H%=‡ C$<4M$Oz*OcLL NM+1֩zISp֒)-夶Y7KHI$r:ri~/Ҹ9UiJ|m~[Q&mץ?4Q(<}[vI]Ghtu-~^StzC 0f^uO (,q# &9q]F=ϣnF!Qe7nG5;nClTqgڇm`UA4_EU} ryS# =g[S]+Ycy.b&FKKIsvx.*j*p7̏V4bU;Af1S,XoCSvW&MlT}<<v}GL K|^A擔'Nb%Ntp}EZj#U|Ϗr>I_[TM\o*s}Sȏ$%wU#RIR,rHCkW.Otnt{c(^GmEWjF!gt*Sr|YmIQBl T h{,[ R"U(َY(u:r_38Zgߔ hp7M!$ܵQ%LN@mHVJ`= fֺZOMR2Ź$}7QݪI5CT^v }IC0[Zkj4Z24ܻ@@Pd&OqȬd] jUtؓ37G@S`ihJSqGw0TOi7t7l=M5O—;݇#H%-v6ZklSn3#&ۉ\6a=coѷKF׋uXcŸيX=OX$֯oBr(sGjiҊF=W^Z؃VP&8pF]xZ*!)Z5޲DZ wH97*FwR{F sReP2A(£ 4c&$(RQ9>(No7\+)x&|7GZ >YrÞ*g+*cgAtt=FL>˙[Lӝ7?3 oY}Mk~5ԠqPQBȦOz^8Z5)bY}D8qS$y~.n988]#NM<1ާ57~_ZSytn=4#tF?ScS>]5 ;R 9l `S;$6Rr}kXK&ZɦwOڨ}A/sk(i[Qཔj̀U :Fy$ܩUQ.,6g8N /)FGzcu׉S|~+i!/+3>;;+j^Tc:%@[zyPM*tfFcSmNYCGFHiK[s#=Iyu@e% {:?)IR^WMijS?ӟzķϳ/N\>`Ve&FI5h.U;4u ͫ\7mAJ5_A< )Q x!WD2%?yZ6^~ȹ:G$yYi e%,nCKv%PCBX![Yu]QߢIsN8l-g%yslYa(ŀZ$" y)ZRT1neɉH"aC@-M pa*\,08Ik&&^p @#Gtu2dk{ ͔́͡q6+DCFnFlpq>U0 aT=8T¢h6ƑdhEP"FsYɝ8tvtZl \C"ѹܭiFf0{}Rh߲8D4Rb>RhMCs' B^ABrR60<(( cFPs @FHDb0'4 0 (V b;aI!^Hd& "|"OiT* E/`/)eNJy@ܠL]! qp S(r-`Y!1hRPtH7d6͖l yPc hsdYY{Kc*cu &Tk_8ʆ5E=ʆ10ElbT1pCnR{]̀ƾ ]lH\g6R&|)4Eɉ\ATKީ"Eu *^A%̧C dPP3HV rDt"@B@S ϗJYti @< mpU{'C"Q@WČNldP*Z*4UTpり Eq64o8DZP@@LDtNo'bOdP46 | LS}nκBd} KoD; `l*F@Q@P%( I 2ΞRΕMh4heh_UXq`X!Q%S1$&"  TL(6ʡ i#%RbǏ〘HdT M7Ah.]}k)KKL =Ƥ{e-LZ<]^H!ţV?9\bPpDgsțc0'm?TʒT@M(Br/"2M٪rLռ087no}7~\dKMd|H%W^ dr. enx|-+e6ĂN$eǾF 6Y6p7p)RS M Z)5:iTWz*0\,ǔsRҭV%iӚ6)dMmēYAk*AY,Kb9]>~y4Ǖe,;Ɨ&.8t!EmIV.NVp4>VS&d]ɸ˰.:GsTdXdMf}җ!⋤e@'J+O_Lb42g -M5'G_|(eME+oAFQtKU19]X[f&,y!$l <,=\4|5ӺG=-ӺGRшIͩpvCϒ6=%/~Gl!.<iTS]+y>lԖ-Ae*-cڊNV^X5)G'x嬘ݦgQ{OƦ,mFq{gj!^ŗkaN|=ʎNas"nr FbK#yqW{@uWO[jAkL}ʭ=ϓ|֖pSM]}j u=߲4k"=sqh:-i5{wW+%:?J7V`>UdĬSYō yl10{.OVBua8QIVyoSvZ-%vϤXg:LpJ=5;'[cuFḪ'7y%Q|E) 1vK%OϪsfhM ]ϤsʏOQ3MEߏ*AI$umYw+4C5]-7Z(xloSzxSkjWkfȧ.;7Q:m3örqGS9Ѹ`r&U׃I,ˎԺ" 6tm2 JoDs(x]j*,Mp/zɒج7YVPa#aL1O. &y^(ᥗ&~Qyo v<\XG)s b/)1sIH-.a*`( @S)` 0BJ&0-Dm(@S@jE*fN fhcP2=90 0rBh{xV tZj d )NzyMt4zr}|7tz=%[bx$g{LTB쎂y8gn:@S/.QuԾ'yz"FE'1|ri_cucL6`s6Zы6!l#;me Ti(Sp ^}(KAhK [P;) Gad`Gd&Ps 8@h6 n-D$FSP&3@#T@L HMn0 q&XCE )m#aiH @Ws'8L$G\,J@([`@ sI Ա [:-hCP@݂yeeKZ6QCme-12T۔I {\m,LTRC`m =e : g1T m eMe׸HDkp%*AeoʐlщN%3´NI* L 2l hLLlJb΋*H.0(L.%_ 06K CgZAe$ `7t D M!::~WHj]`Ʊ־SMESrlY]#y#:5"Vw18U,B4Dz Aqr;CToB{.Vey-mRRV,{\\V~'9$F C|$wJ7nֻ g%\M CA+/QIRI۾jkhiԹcCXe^pl8\%u;*y Rpp qGijR aU[OnʬqAQ )UDjsRF/uH.蓟QT5nȌw;ZIpkoʌԣPI3d% +.Z>Zв5ѪR9hRO9ZY1 |z.Yqȥ҇x |{^[i .sD #rG|bܿSP4hdx#OGRki: ok 𻡣a^M4/ZRjONQmVU n>_Q@5'h' FQ៚y'E[CPoKOn>):{Ե_5SNHWyOv{^c*#K!P&S.#5?qZ*Uu@ $撍DҤ۝Fse Dd\q9Qou<(|=9"\%ͳLy7LCAji{zP2 ]ߍ9Kݜ$nmry7K/!'Riyek^j_3]Y7+~3tUkb@ ?N}[;\]~uU Q<|e=9և !l)>Aڸ=gH l1Vu;ӶF <)s`W| GeӈRA{ݺ`K4 r-ES6=i3rLsBu`?g8t^%JMJ4vBiFfBRrqBn耷}puiqz ԵLq0XϦi;XojDgԬj3CwX<=OCCGGMOrj%=JH[6Ŧ^:qS? oI~g9-=#/P3P5f"'G!C`9Dط8RƘJ@(d,Kde*&G‘pD$[ɕ (JQ0ZO"EɒCi&XAS@imbkf/uq!ihfyK47ȺV>h(s+CqT9ʻ)|ECݧO+GHyoCt}7Q4ApRdt~5'utz:Ophl E[>C}m4XȦ4:34dV^-?=N[UWi -L|`u1]|/INnߑ[LCB*\=ی'!/.i(^<(hBJ|d(hb\fhPL[&8ŹZTا4%efz!)Ac !0g(Q`H`X&D۔dopFPKra t$P$fIL``sd79@ֈL b "BLaZ ''-D!EEs#b,< o [:{Ÿ0q)ĜY HAEn1lBiImĩbxP539YkDe kg41>KC $1<ǰ)eX0;|bӉC &yRcGu s'*XIUAgG_Pax{74 #" @Le17E \b@ 7&OKv@6T K6Őp `;@@,Q(Mc%@thٰdHD7)Q&l`X6`Vo)4h67Z&KA1.%Uy [A1 jKVZyT"!2ȼh@Ah~YhOc+<ߴѧZD`<\g~6֚7 F X)|VЦTG$R5Th "O!|[lTOQ): RTˆTZǓ'/S-tVQ]XH7U#?G;^)ݴ e.f2\eSvNa4|q3)4(QMG-_bX&>S\CG,ѵPHԨf:I}S,l] Z=|'>٬2'CH2pMNn]J\']֑- rLJ5hMF:GAN.*'6*#С71fR|6|^Z[Z() \Mhi)Iƛs8햱۶j>b]:1bXm&acAYQDeF9w2Gun~~)i-6zhiUv:3L|_Yz/]i_te@.Lz>4s]szy[|O__իIwQ6ͨ{fRa s.5}+QSuYߑx^nHp},3R$:aLԬu {QRFnOW;Nn >< ֎Xk+&y\c^JA-} J_R;_3VQ,OxQQ7]{>E(a7P)ԿͿ7MKP!wZWݙ%*N<ǡj '>\r#qrZ>G3Azam^IY:>OKK!i1ƦԓLWOfZ+a_3]4=6La+ol٤ZCBrHl#/0"ɷK O9P3<\.ӛE՞mn$3䝹5ohT/"ʜQYFze\)m6 9[>CQV/iceR[ɮ =?BT9PeΨ*U=VYg$![ ja}<ש 2Vw4mQ)[W~oj;~ zC g9m+i ,3l[$bvxH,S۴HyI JCA,bB3C`'8RH @ n:U220Z41ӉThLߺЖia]RFN.NLB"7.Thq &6r4$[%(I|yhקe'H]RF&oƩ@%tCKΥZ3^/` LkrK2nG(ao@ZLbl@ soH DE*"LF &Bm80E -#[2b蠲QAdN %CԚAgF DDߔX YqaA''*& dIRB2XwLAeIա0~ʐi2]R%R%aZ&@(,֌)(A FJ/;zDk\Ro.$fgZ£/[lX> J;]D~v)pkRldFTLnp'꺣Yも:3H!K`ZO{&.NߎYK[=CI.3rI$̥(.5-6sRت GM&32rivYm@`S \sspS{Ck{*LKr#Zd~@}L`})G&U`d5q (7)[=1gNjwi `v۲z2η{O^Oˎ>?ItWmF|INO+>}wZ:v ?4]^2T}eޱG76A~[ud# ;uC|?Ttm|QWhi{Sl'M,t")YirHO+}Ӿ<&Y)>'iR-- ^6X?UόN>Jn|r̎!-(RYujT֗rT{ȣ"*ÒJ6Rٰ$`9Yg:rFo+= *9uR UrSOlOP+T/rV.T<|Yu121s@U mGuS)/'AKm>E6 %pNV%ʭ,*ϝm"VFtZ=rieu)06ЇNLFäkѧyZZ72~2P!X><(trԣty-`l ncY(EnZrJ/#ni&pkjXمUbjٳAҝXi̬MԨpUӺU:t+pt Qt5tȘ!%َ+wYx |sIB3^24$- #LSK@%ك)^%#5HI>KC 1/DwI򤢃({gL^1q(@2SB](AT5Sv.F4T dQ4 hUFzO7hGJD9MrR#4 d4?dMt ӏ䔶Q/j{m-1-i\m- 9۠hߥ</V:Xb"ȸ;4s-s7>#:nѽڊz&qDpz7k=QQ0Dh㋔6zX哓U=ew^%x^[_ j:Z2_Sy%{yM&puZye̡Gg>̆M ~Ȣ,X%g{BQ㛨hT"T4R†BM1}T1nh" Z*) y!&P9A@&@H_2. &O B"I@PD PIa .;_ ʠ ꁠfB@UE6@(#(I T` ^S) DŽ8:@DzTQ@͊Tsi#L4h5T448:n5hYCCC#cQfRceCMh{2PƱT0wPc] 6hy " /xj@Qt /?Kt&"I,er@X2Q@QSL E&wL J37HDy ꐁsaPSH&UX.$̢b|UP/`@-΋M!;x*0! {#쪄œLX7SHv eZBN";t.OigvW#˚3 kv_a 6fNleJ)eF[D ᲶRҫvj|i#7}˄\ ; 'k{=E|rKqڬZvp\-)TQp vFXV8vɣ>]S覐U]:aw(MbG9''؜t'4%c}C\$Zrj8qV}<2!hcLyZp&U$[jMV Ih`qI9pT4ϑ+HABW@j 7BŎmxJ-a> "X)?5a,9O9s FS[C1^phpDrI-_@|J=^M+ p 2ʥߩԸ;#1ID_]ҪkeÑzY)cM_H~ zOcuk8J7c#: 65.h{`uSLOeqzO6$>/-3;*<}7}GkBΦO^GF|-n-я,zދԝQ /9b-_OȾQtֲ"FA/m1AO괘yq&R=nRfW{Xa()]3^`*zO~#}kпiIk^?W5QA5iW  w`OKoHwQn"FDǧʡ;GxMR} Н/312ybԏRn-2Pg>&s4ɋԒ[ 04] irj5aL_6 7 D%CN6ǞvlƓ垾_g:ŀJMQVyPOLRrgLYm)RKڑҥPRrN󞪧_WT ɓצ͏ GrC h>jj>'ߺ;μڊR4Ki6F*>'];# R<ćps"$h UIk43:oi౫dtnRARG^".{` p{/,v4*t42JǤVQ%64aQkui>DӟGĜsF7efTK\d^-,m8Ox\q(z6WtqYCOk-+ q;#15='66׶ Sҍ9 ˖so',mMU\ TSH]K?V)_c+9 6r8uӗ{:MS١S{NH2CM/ FWeCC ?S@X~ @Xq+ iUB(Pg( /8(DQ@U܎SJ #i 'DU$WC( ANuZ@,:e*qM E!nq!U$T2bBn|&ɺ-ΗvʴE%a#Mg:Ek@kZp(^Rn&Ƞ&{  "S,{&_)P3E .$ 1"I@  ¡P@HoB l94^PYm' (%Po)4);i\ LtrE"8"VL%8RP)X)eK +LMe@LږV2h0´ 6ZbVV *w<*Bl{7VHSXbR$p0%g| Tx^L3L#$?sM,%/+f{?Df4Po۝$j&ݳSƁ+1VG4CX̧*U%-sng,BlE8{*άP)H^67RG| lɩej+E_/}:M=¶٬.ĻPqt{,Da,J#u+Z2᱁Kon݊Y/ eh꣍8痟M=3X.iq] ¢ Za*$)iGOӋ5PKt#[cCXkHT/c`CakTbH}0S|~XsX⎗G2!Or+H=8U C+2~v|٩XmsCOYaor 接STϱv>AYJe@S'\UD(kscF+8S/re3q 1 :գ?Kev~wjqq EP/?N\`pT7$| K ˷'VROD_s!eoIc=v~^W4Ԭ_ZߦwKy;sc |oJ~:_tl3EQg4ӺU}P Oes*':PҼ.~]Z#Ѫ:0rWC;gVv[ck.kO2=l HQ]U>m>u4١Zghfnm x,9NƝ-WMu~-i$=}6-g[]d4'O)ֽͬ#voע~44EӓԌMM_fW (`q }Ώ;C1STy3c$"Ύo#C*"&q9nv|YG"M;)4sft`seQVrfC-k-vȳeۣ dlEN D\] UԏMֹQF%̪TqUN<тQEApJ܂YoQw ~NjWEkI VNM`f EQ O aɝK NΙd_6OD)93F m'gtLҠee7JqoЛЪG,73EJv2lz7b~)Ij"IL*-6j$SzkâGUX\1,NVjt&"ƙ[G g$غԘ,s騮Ma?Mp~vX]y-CgR |bVV 6f-`ǑbO!l'CyԔCͮEQr>1вo 1'*lT@$P:/kQeF-khU,=T4y$6Qc*'8G9s-vtj G 4=/\M7Piۺ 9'Gh&u4׉q xh[g%l[jb6 .:M6#qt:ewSܶ'ݎ:4?T *#Z1zz6|($JnGLcnAѴ1s0\;G<6,5|NoS֍8%6h[ǿx1]ZTt8.QǤcsPf25 Jtw]:,S_F~)k`5̄ dyCedAQ@UC3,HC";(cX,b\ hKĨeEݧʖR&78NE`,i!0 ӈd=ť\Ű!(dp`9(D&)y`Xx@,  " *q="{ `Ŭo BaLĠ 8tE' y--.9@ q=b\BS > ?L /!& X' X k3u ֐c  k&1x1kĎрVl,M0hvhchcPT44t9YP: aMָ~T41*,;]@Qt(]0dME ɸX!Yr06^E&`PMb?uT"^I"鉲#6@MM"X$M Όr! s hI VN':L `uiU@q.{nЬY*B10! $o H1(M^#A? cLydB p@PK(P@!&UXcLUHo -P,P‰( +<ҽSͧ%=N]}?YORwTm;]x\s~/͍ǫ>We':mAx^LW(Gy_õ:k5k=ޢ:+6O'bǫJhWz'UPt i/KqEq?0ij|hm]Z}zT廅^e'xcO?UӱzeԚL:8JxTiW'Mr:SBz)s<[ki,pg߬ߥ7E7?YkӪsGqseGN(KSp5vL7fTr^7GWO/c4 9{_L,#.3Di=MQv𸚖 ~IǓk|#t{d~/UJz`U`bo(PڭeX [.:[sHS;??h W}"B8eelO+zvϥjuZqG#cY:f.`MZ_crϖ͑L~-6rS9/ڍU'ctmppYnSFJ9ZNU%eDumh{ZH4k/T+3UG;RLI*W&3#iZruɅJk:ZEj4hq$HZbW$SH>W]{*wIl|/C-j0G4g֑ t/GkQ]TfQ ^{{.Btڠ^f-~>㳯OhגQAR=^LTŮ?+5`Wdiwj (kNjw,گITJ1*GTr3 66)8ԥ?4+qގs5:'=ۚ!JǙG]-Rնҝ]JI#3_GPI,|q6:SnY,&J=6|V\nu7dJli\! g^=39ZHi*ivyqPq>HpDŽs9t2pS $*T.2ésͬ ՎI;f*^DY[\(jΛFΗ2TzL.'u꟨atmiP17eJ44NqfMTl+q?h=-i\dܟ|?㙳%b+Z(heG;GMo&!/2;$٠c* Q)]h1!Kelt)+; )rt R(k`xSwNrBtG} G`,Ch쯴5yx.Mkȕ[rIZGeȮjKPphr卾~)"w< ,iz8Ziz_RKVjыݾǒ\ZE('NJ5u4%wc=:ڕ %Xtw<1*=֛Q|Ja1!sA,m3>"5YME 3ǔ눔ϕ !d38 (etY82Ї0 ny)) s`Se $?䋠 rr$ PP^T( gl(ZMh0 &)^,`@˞P"b Gt$.2&lp"o)&E^3[P)B\O% XdɁ{"Bͻ"qCJX$0JڀKCATƲu- cjH 6c^ Ohu[@9"CC4Sy&D4phfHPs`%CCu Ί:0 22־ R_od 5@V@rI"M{E`d𪀄*gt"H.xTqd%_fHT5$̪HpU%H`) tIE .*lSʴH8IBӟ \&< qY2$t+w td8M,c\e!  ){( @Xwt$@gP0wZ; '%A6dt6><'B,:a:@S'),c̢Ƶ H&U"X@Ur{}ԴD CËOYqdhK,;2{Lb`* 4RyZd=k-$kLL5Z&CA+L3pI0aC*Lp1Pp1B";EXmeKWISE)#Wʯ}5fgcb?uˋ"~<ƟbS9ъ 5͇*MPjk7%((ymLm\7%sKy} Siupe9mJ @s$VO$(27i8XS蔒U2NSeUD9e6iUhuShjm}FsmX.M_ ĆJLzHu .u֐Ӌ4im78eб5ٺ,SfIVE7H٤4itct*΃ޝX֡B\˟UN5Ly?N~&:v5ƖÁW='rjo$9GiQe+)ia\^{ ;tWUOI8\e,/fLдQa0lqdO-׾`}V~rhp &Qz45z',,n'-БWt^鏤ȧ]p#I=>K}Y|~d1M@9ZuR[k@\+"3h2{YZ|wOUh)P?EX7T,,5h7-n_Vў=$\o+h1Ċqy_9\4Xg궩2o<2M'N[mP eugQ~h酦imݔi6ʄi[>?sZ]F$nQȑRiM#!J!vS\3i'0!g8(\_LΚ0CVkӑ˯i}Y p+iY.suma3 '=Khy>Y:5]%j-(}#dmk~H烞P3LIS\*;+F2oZ%*fmVI*Ѥ1* NK3_,M9G9 ҡdM0g}tGF~j׏OJp9oBheL.'("6rm3Cd J>&s#RQVTiʟ.V:~iJ.Ӡv8 q#W> v^#!'ռa>+ RzƮ"Ii;7ɹ]H1ERF]> b;!zF:F]n;q7RӁ]\1ѥx]nG6L5VӇ]l=OL^t3OuըclQ"&b7j$;t{Gsr=IHSJR'& BHbں-dNn:'G ujmZ5ʹ~ɦr+K U%!3& yRLy!.L;B4gte)nVm2(VX~.(.{XMwt_` ɸ^m &A`ԝa(@9$EդV49ui^ T+.{(`DAe:L@ I+B9=WBCgS^?~˗6XnxG^m#||]yOBʺ/N\]&ge'̭CX?m8ed\A Pe[,ҦrUDB/G3VѨw2.^ ĸcc wEƱd5K\6\QLZgGAiTv^`F\M_O6y'>"-}2 |؍?u*K]PNk6GT}Nu?=y涅dc_>g?[J_\_zNm}GwRIkLw:^MFkO|5ZM]բ5o r_$5SJUcp":\VJT!\Q=CW\q؜_h|g>-/R}8+O5~'<^u:k۵% t~ )-ˠ4$d+M64_QPTGɎHʨ}C@Np&,l9=Il=w Fv>^o65bpf4xfMgYLuP UEtj95zɪK捝%ɣ@՞ 0\M'<#D)ݣ642EW$6tZHǸv`\$'s)aDfZ"GDsO n\Q[r#L#"llTŘS7 cjnSR]x!\mHtyVbiK̅rn;^2УtgMvdu fx^^ViФӣmjN cAߣqȮkG2Vs\\rdAOiHTPJYS޹gĽsK23TZ@Yqj.ѝ:bwn r2K?$E=FCsz;d#9O"AZy>G=N4G);gF/]OElkhhh0w*3_>5kIZGX.aWf=7դfNfU?R0qbd\ΛxG:)k#;oP!'ғ|#8HOtG 䵊WɋUBj]Itc)[]v`~x 0(=PXpodBœE%b.l1>Pvu:xdxY^ cWs9EV9\?5MwhZ#flP&Q oNSGE$!,b^Ge&lfFz͔97PBጩeN| sԠw2B/`AsfeF3x ^ 97N^2oE$dXD,@eXp'cbP=Gt FD@3t4f2$>P2/ w [} q( ;q=ԌC BKP,2JŹR.2 H2< k.LƲKhL)cLlv:u,  mA͡>yY1p< 1QC|P N0 PM 3bVWySBQRڳcR2iǔ@I 'B({"wKNeˠ+H@ X$7ϕC*1yE)HªNwbU$&Ź $9#T ϲ` 1d&ċJ@"Kf,r$f˓`P$ `̔/|&c&aaL0)ӓ!n#^ <' wtFBOd-&SnU%@](}0Nx,u؊e*F,%&bAY#^Ah ͖nu `d T2 ff@6HL{-rCxZ"ֶЃ pXi ¤TK 1aѢ T> DKS>Y)*K+)٢4i(B>gyl9{_'PVNfe~!ǚ.&jՂ.V\G9x$"akIROQ. usGS 4+/Mɮ`̟e贃H:[f [irz+Mg\AuG.JqJ)#ׂRQ\x .MFelɀ ' 1ǔYE LwYj]ǐֱc\EZURpsLzjѿH3QwOuq\E*_fIͨ[P Y&)r!p\-0#M)j#^};%Iu L!{C $r~q|hz޲m2 ߍ3t!z&u6y+Ǎ*OVR4RώQVtc)BՊ: MZGV lj;"z8G*D5!Ē~qj t8 j\=5S<+՝1 1n4eɀPDkL{RU#+tk iRD+(f7SLNǻ %kMpe״ӦCZ~(br'FQH!n(.z`]X#j2I){bvƢs86]X#.D{D8͗GR磟P h[:idSkj] naw4®G#p#m =̝& ~W$زٛBj.'a<{Mƍ-<\?ϣY=g|\2gIjE6\y4xq:'m;rϤwѽztx:F=O4ᡭhU j <}[AB3e(IlcMLo{b}G-%=AP 3p8>H(TNF6 Vdz08#RdD]t( 6 T9Xs !M -ixZGD}:7ǃ042v6Mz.ֻeOM<0+=C}AD:dڅ9{OyDQ;Κpegՠ4ĵ.]J~,u_QҰP9<-7GvAt8γ;4Ұ=zxYq$+H#n:Uf7k*.(˖]\|NYR\(% s(f;Cg) =K"H>aMG~k 5 ۳rԎ]S.>)g~,heʃЊF:8IKVlh,Vl  𡖌]x &Q|hfCP%혜 tPu.dA@G?Da/(&F e\@msd$ EM!!1 1ы0 e$TxI((fsd$]"?'@P0E1q7@ q8G,&;$o.29N)=.0 /,s d uę4P0"4KE!ߴOieH"]J9P=>lw(c ƊY "%CCPc "K N%oJa5dЂLMb$!|*=T00rt"v>ɤ+.pE[eo("@BI4RCEO$#t"ʪd\ɲtD'@-0NH7V[RBLuI OU$!O<ʤX&$tc7͐9?uHg-Z<6C(۔Rf $`Xr,(6:$(k_yP: uP w$[TŐ`Sc)tfp,oeC 8AֿmyT1q5Qb@D41sHdĤHR]l,]PDnp*Ya`0e&@4 })֑!dFV5T' 2TdJÕI2eh-㕪d2"mhBqb&1o$LP4 0񹧂\;tڙsz@nF G^+Oj'Fӳ~i8"|IQa}CzjV%Ǔ~ӋW`?|:Qd,^)f{>OOQ?k:GJ'A^eg3ǑG#0P[p0j..̕i%v%=w1 q %cld|vmI% 2LRe.x6EQj i~x 1I0AM$߈H<\Bht,tPLmCj-8>SQ~ЃOHw#Нmfi\L-JGq4R5Z_҉=+[WYµ9y>C?jQ ՊB؀,~\U7/rlۻ : KKZݞFOvyW~tfݥO<*ǝߓkҽO5ƛi\L6^8cʷc?tiw4Dt-4LnSxy3bW_kŖq݂U%.)[ZA"u[/8:#)v6tEzHIz+$v{~y,K. EUm5fW120B!qt/$#T>[A?9~Vvq>|W1Mu C:]f{Z-qO5h`Zi>+UkzDtY˽ktǨlgG>#<̯?W.w FpGK),lGc+g'5=R*:V#x7uRJZ>{5u5]eF (8<.LEQ&ie;VN"—,dKE5!P<`F]pđFOܞY['&U6Gӽ!Rn-8B疱%Q˯*Hcp!zADHs=Kš0!}2@{ i1x@ i1nUDȿv 1IS%ֲyָ1 laE&S8/sL k5 >ԁMX&O)-Mq+ mSbO?,(7#LzL552h5U&Igh,sdĭV D&Pb paP! &: h}7Z&KÅ%Us*Zfc$j͢842q|0p ęVXIiINN[F{r :j0)DV#LN,2?M{̼>OYs Õ[?Tj^hN7[&z0Lm:/$S|f݂& ɀfc(P͕Pf[jn~XθOciR׎H#E!8[$M'Iko# 6$jU-M LnmRg]48ip {?JWBORPF;]F>{MWtt*%p-&ZGuez*_4Z&9sRvo}=9ԅLIe㣃zs:_` #\^LƕjS6Y'RtV->O Tѝj99<%~[};}]KjZ~\Yh~!WzSպKD2i}1Μd[dcu+d^A {*bE9Yg3+7H{ AW%2AS^NHW #ro٠ өwcuB~"Y$q0}/WӪ|=eSHpy f.`͏2fBױp%F[Q(:)l;'>GI.NG7PU{zDjiS l2a*Xܤy.Fx>hAɞH߬ԣR+pخ' ͿԍP;V^M J 1`.q9Pr<~>{guꪚp8Zkj=p(퉖lɪCDCJ#6p36 c]Jëg$*V5jVG|&YqF0f v&U+%w5ǻW 얯Ӆ"^( uzn%pY9ks;F6@_cpE#ƨ@`ePVjFgj C/6ؐ4q]<);fGУB1*mt|R(gԤ9u4fGN s]tcSFlJc !U<`|Ee!Zf4H]B)AsK#O*0jjIa}jՐ%V9ɾN0gWuЉ08 ovpp50G Da3Թ !ԑkҭt0^˷NkG(Ve>χLqVvW =9\M[s \W8`:T)Kt^]L'?Gmj= 6""r8Vt:+K`DQ*t)ۅ)oͭ#xb%4s9>L9f I渲mF;}Ӕme3/֐lǭ+8c|{kTqqb}ǭ&Sv՘R7:L2t2 wMRtag$ lD80]$TUKh⠭MA[:/Lku@ g+ jqÓ/ʼnY*ևn1rg<۳h+(0BC'h3:-,ꟻ";id>O:zɱ`Mܾ?tGuG=q$$QI$MrbfطRLɺطQE\`̬܄[ZTj#Zӕ4Q&$pR&j5ƣO#%cOu u;LnWejSuc,D>>MYPE3`>ə8 w5R3Rm)긑؅ hP$͖VL'$Tf{L,њ[Fw͐P ,<aO q@u22`& D.((Ƙd+.~D0$3T2[0) I0 %! e~  q*)2% ]"q(-fx@ |KɾP] rR`-ݏe,B %Hb@ $kH pP0d"^ P k8R eG :WX*({k8 $u:'@5I#T4WxY4;ڇOCAcEBnVm6?R5d)c|&08 n2 P ЈoUm@"~dPLI0 ,s@)\q Hp$HU@ d@R-2袊L '*-Hh;#2w|vM Rv;=Zcu͙~"Դ(1NMj[ Vug:N.u}, -VH=[e5RGKJ(-J_,Ap`-`:q'%t(Ѻ ?HUT˞949A+U& KeIQmN%h76w c&.)XtTRW5ÐU9n(G"mVQSy{$5QD(sze?U`fqVv/K m<=kߦ:z ~gXr9?Zm2\J %u.\Ni4J(3z6i,8?e qO'7ԍ~huC$7 y.*'TEǐ2P|$wMYߐ9 ʖOg6KQ^TuuM}N=sZO QۇK3vD)žX~Bc+Yc`Y)?JJˤ BrBz{QGFt}5_bWZWgOz7]gA=R_UTSpbpeюKSTu5]ڦ9vljcyCm'} < B/wSu^C$leh+躽uX>WˣGNJaa]핟:Eu t~y֋@G% g+]f+I~sjT} 2*?.'I@_Y$F-N JFKh^s)QOjT|~s*KD`۾]q ,"wkjLn^^XdS3hM'ǫז\zgrfmGQ/y2DIYJFVq;5/2leXYg\:gkD`'+qYa#K`Wcm훼t,j]PĮwg|]xrΈrn!]ҺCE oRG䠫rGҺeAM|C btԩJ8Mhu;I3x_F]A&hit^1?&o"=kjS}&,q ]Rc21.[3vGf]BdIT0V "f%ɺtd0rTuc1HnGm=ټÖ6S _2JGiqZHNǃ,3J͌`=,|_$wGɀ/5+uNKvFLPjX5ph*0Yܸklj[h29tmsꃁ,+lP;qC9]WԢi*5>L+6i6کZ2V$ ,ԙ$LIMٻy)^YW,hjϳ2VN٭E!k%G@Qk]BW'fnE龇ˢm`5yGuQGIFW|W o4jh0hJoFJm; rth%6G>f _^j\\tG*Mq bJL+;"]c QHcY(Ujɪղ4Q!k]բg6yRhjv^̚˿.%ϜkϞO*ل[$x l%2. " K3? FZ )9Y(VYHa 3b&;(e#=G*MJQu< t`t; 0Å@l͌1 i(AJ$@=,f\L,@X3QA R1=2((nL3kEB,g)$Z  LB,O6J<t~c?L6U{dw@s~o0H{` %cD}PNdߺ( HcDBT["cMƱ"rX8lcń͠0mCEcc 0T4 ʑmwRXmt~ȠvC %&h< ,o`IS,ܪ $J(t.B,B(42%(9,f?d@0)0B 8t!.uʤ8UP{!uT 20(e4)6E 3.Ԍp|[ o B`$)ƒL2D$) EL`8@m>lR%&.r<Ҁ(pn t 2!6C(&RL:NFP1yLp IR,$؊݅-^fG%\LX`lfLB@6$43삃h<Ƹp nLTh#,=&!P Uf֋ A5B2X8bn j FtK*%A,A:@mt^9S??Z i쾹fJ I㕢nawŹqNY{qI5ݾ؞Y*G)yr8=<;v_@rFj"y냕9|\83 uq^|uNQbuᕬn9sg79;ݻ+Rt)R-ֺUn6NzbqI.NOApPZr8ʙZ%:hi[)CV/up+qKKzܕ~M5>L p. r |&(Q 4:Ʌ=Ѯ*ɥ X&G JKiS *HN'QՂt{z\nS4A,'b 6n\CÉYWT\bK stTtzvvsMepv&Z%c,5Z,[O={rVoĒH6 63Vf2FUR5ܒbl7.ti(IrAӷ|4,Y7 Di \9ꎨ>7[ivz;OnHNe&zj:)"ҢcA$.VzVѣOxɑN='KMh6%e)rx3z(09@dGNC>75;]s%\#G~C+8ە݇I\{?գ>_Ɍh3ϒ\ ]yaq۔x&&,) '`Y2+e $ ,1b F}2H ͐& q*@nyR‰0XƁ'Ƙ6E%1 0-#*@2$-b4SbcZU)W9L D c)!ZdCܭbc~D&e@--D@,͈@6ܦn?)PRfj͗fxPѴXLץOSZ+?M7f:=#چT0Xr`gOԚ.JCpy7%,=1E՟H{̉+K>rGwF?voU#US14+4գǑmikՠG? *]7ɶMIª-/X$8E)] ӆ18h*#8Sq୔[5٫MԽB`ـEd_W>Ru'uADjW+] ;b b0`&E\]R[ ʗ&.-18[G+E}9JEpT\ĜUoU; B]p&F_ҫVPh G?U1*̓hkuNiNZ{xKvIп[&]ZMć2H |N{/'/y:}*2$A E4/1Zޣ__[}wF`bŎx YڗgRkcu$\L\vܺ`p6Xϔ.ycpSKue:eN]`cr<'|.u>5}~r|y:eJ3?zβcq}YGYm](QC[7 .,ϜԟP5!]1K>h}I+u^}'iX8'>G8,ۑ(|QLz].MW|j+T<|:3k5blfb\QƯsJܚegQfJ͊-$90~)g4 ].v |NjARDkMӳXYՌp|atQb'2Ic[Ѭ%lElWL-7phIrθʻ5Ա{S6D"^^I3Qjm3hfVNG#[}~Gt .P9 u4MrQvrKס~Vݜ5%Czm?O[ nӱ flԤق+ՂeuGf,u"KkKV,n&ƁGd1̕5DE13{eg9$SeA LqnQ6# ֟CM-YfrNг3)?E\#`lks¤g]Smruɂtx-mI{̜ЂFZ<]t(QTs 6΅!ƛATR/oE]\vLep#!bՓ̺YhDTmmNPHH,V}CWtH8TU(RL) Yh([%!QY9iUe)jM-hWh!jlEjJl)YsE8-+^ tgMK:ڇm{C֛9el>Brl0lH+p wt SJECxR!C`fyIRFgefFZvfc@ld~6hu\A7T64gyH $8@ dc@ n} ǺXHa4HL `] A,6 AAH0eD J_hSb e X8@O)7CZ=H8(fE1d% y@\@@. N?P[H]%R @0&ydSB$@# 9@ Ǻ0"`\K [' \K y9H`)16b覆5hY; =ƴbr0#AcZ $;łiIcZ9,`EЛ,*HVB79NɾN9n ! .Ӡ7@t!:i&c` $s$.B]3mq7T Ss(Ht}1$^ (0FWYd{2Iw@ŘLQ=B@<4 pU cdr.1@Ys|EO ${ P&BD\apm0!)  !Pq1d  D#0$RI/src^2X@D1H1lwEa:-P cM(v5S6NL @$*46 4SxVd+LC mT) *$e4&>q D٥9h x H(Ͳe) 0 b! ED03T1u3\6yb'תjt`秇ίEV6w+?DiM{Ytg>( V}f\?Tde&cQ~=N2JIOYJ pHZ)gF<>DӣRA|_2-EtU}2m&tC$ڙ2:dTkWӷ|ߛ2%VH*f oUkH !B0^\P%FfL4"m"6l|:ep;KK ASMے@Ͱ7m1KtEBLPރ!3Jˁ p2)*-N#QۧkAݹ-Uqq.%s^}J>вTnya]3ΗZӵk?uԵ/z=<eV_Q߲zzp=Çp1bPT#+ %?sti ^BhUW8;WE*SRӬ-x҃Mkdh79Bm&wA~\EsskqֺЧA(^ӇM>'ꎰ{k윽 ||}ؗ<\^2=ͳg3u^FVtyFq)axl>[9fy[g,Ro!Hx9Y[ĪR#w%r ŵҢˋ 'Dy9TtDh0"S6R,9"4NtYeFjԲ1ʒLX~OT&HGU+OgTs{X5Fʙp`> 4zI*M}vlQqR<'m}֝e5mVR @XJG<9r\29|PfsGJ>RI^%+5X%ckjrX]Be#}P Zih54H[VA*ޏGc3Sn -YМl[wԹ:| Yk) c-A|vpKBrPd=D lYi&mRn%XMK0 VM2-JkÁ˓:vdF7cӥϫs%9:T+AVjV5[c- l%J)F˩fp.άp׽m#VMqYHl 1Is5uA,ZE-'Gԫ6WFLUu+OGcO^^Q?KN~{S\.?oUZYvC=&1M!L'@XuŸE`(YAmt"B <@p)&rY4<~;'@P7".9섀X $: wʤUL# Y0#OdЁ J)En8Ty P2F@2[ #I/  @5B`ÓLVǺAUD@D-@ T slPP#  ( lUb#Lo@[6 !-NGd$1 i0JDpBaCZOdֶoPPƲ  &,k[iPXm2!ml C&T@2a 1cX`13E'd8Z&Isn&2eILCYc9V ),V ɱN4@c?*zT:3TpƸ3TwBpHY**ҬfZo–;}7:1.for[Cg{AԛUk_:L,c}Rͨ X/+í_/Çv{v[bӳvshzSOJվƙڻֶRӗͨ׫=<#)5ӓ#kfuQg)"e>k(m%?H) )+ ''52anR 8HINe);1Q6 Y1Vr{~HF ZbS†4fj30ZL?E^SKj2J8,uk [ I>pK]2jOܬPro~$=̛?L<߽vqǓR'OEuԀQpxejpvsx6xls+$ytmk Jp;@:x<=ϡP[E*`HG|O: Շ쫃Rp"V1|9zsyo_u"G.[ o惒8>kjiCMTl\IԚX`y=nS.T9u0W=gǗ=#-q&%xڝKgu6g/V/-K%&%a<2;tXWnZnRhaj6r!R?Jd7jNV=T)dʄttkTy㹪HFtv[tQH<чTQKM;< р+ÒZtN8״w-Mg%o̙%m=3+l 6YTI6v:~`Chfid_Ʒ>Lf&AӋN2MԬ/p%l#9+e,:7 JΨž"e:O.Yf*us|U"KX3l )ư\YfF3Vi9X HqVDiI' iF`k5ɾ 4yޡXʨ=,rLcGlbU}Jtjg7$&V@,PP.WM73VJt4ӎ n#u³nNMͻ0K6Y|+F;ѦIxX2MLqYy#{dsdBG_z^04 |g|?Mm$$6:zIY 1*lҤ ŖƟ~.G(鈋3fǧEnEj*qdWK?a޶MΛ KϢc}㺢YCe eY&VNV0lMl*efj!Qb0PUN4]@Ұ춅bP!iEYNIاZ791N*hLJhe*XH =NZpP i˄0])$JLXr<ҭc `$bY6PI2P0I]R$i)1]|!c=DEYlI^q>M+q4ڮǂ1+>E]>-`/Kw}[1mgi܎WW%K266N1V7vtb.O8K.JʶZDc"Ul"鈒PT0[ERi1u\F;'X%B"I8JJWŰ*'AюqrPʜ_>6 Pc[Q,g GcAYퟕrn>:ӧyF)ͨԿJ98GPܾ?fǙ͜mNnimF}Cԗ8^~LO̦ DOPܬ^`'+mO*K o+2 ŇD2H6iDQtBʂ;^9H{5u-D|&Akcox;=3ޠA -i21% Xzݱ@=>=zlM Wj_lJPMIчS3,[}v3n?Jd|B '$z ( OQoJ(UM }#(: YJThs֋ \ac]hX$B6ShV8 IhŲd_&$Z_fJDF3TҲ7\#EyID `ЮCI Le&2`*mwVi]Ƥlpi~9+Xъ7VDZi\Q\jT4jlVE^TFJ$ئomVEr-Ԩւ]E[:z_N7Ÿ]tt 8)Z9G_IXjɫwҡmoFJrͿi-hp1M_y2pf-wYFu b/k+UuZY@]nLT{%Կzm uuj=`O]H.xG/-67<%>]UW= (m0GJ#4[n.MG^=f0Z|MTBY 9~G/tYԾ>ԊZ>py>Wx)t8h^ݵ5z<:f-&'#zWe*kۻ{ptyz4wLدq;=׹c`։%FL9Hc&GIX(w*$MYťz \,ykн(Hh]1\SYe,%TPmZla`5%!O+v3U8k6cokzOJjQm +?OM-sKj˗?,¤%289Dži4]ŕ&KAnT pVPslj5I6Fz+6W6\*ɲ%I6$1+Hu-_"o()x3nU U͡0,͒V~?b   ]u,:L{3'h:Sy8H b <$"䋓&>..22`JQ̦1n  M -ф P3% y@be  v @( p@: }P0IS{*#=@PZ#0 Eb1 E-ot-@H&3t,w)4"H8J&~Rp\cHH4':זh(0͒ ADT0fm~Иm&RqaI@1a* '0dF@AM!/NX6n0YEEDrnn8&Ra09 @g@w9cdOd3J@# S{C< [ CCX;B(ġ.$bf10J@Q3@ !3k&30IM "d { Ӏ]``bH豀L">c`Ħ&ƴ@N.$Jdu`0h"[S{ 9);|=? hLHhi0{U$Z6T'@m@@1`Yla4B)hv ZGAdlNB0$I5hr`1]p13E7DK6ʢA3ʙ&L,DA!\`&IU]RZ3sʛ%Û  -瀁a9@i\U 6f.&wVsL [-J5Qu] QӃQ<Ϩoj @[#}/^uYFv08$ZDl_UҴZF /3Y?jMőJ)SϺ -=+Z3 Mgݶb'\auK46ϣ_Ѩ0xgNXv'g1cZZƸt7pNGMJFWD$ڴ)ÚerdI>plm{K)|3E' dheR$-VRLAMJ kmH}1([ q\#*QX2FMj5bc#;ϥJh4Ew5֗ =xr}wS4CSN3n& v𚜞6-cngJtԆ]1 Wqd/yó/+G3cZ}zn >zWuF;|&6yo('gu5/c);sv G-c6~*d'MoLwD3iU-"I}NHY~M#M4!=I}@c(j0i4 YF|F>jW:Ni|>+p~[rpG?jz?^յ5K#~Y 5-2O=V?Ь^ZHw/iYΘ~YXVLrzCt-@ow_Eu߉׏<=< .1G{br/,SsX$MVf}S%Yɩ\k^nk/17G?i'*0u&mq?^.9r~/ٴ`k*C+E#09UAZSR!ntK͒lPfzAC`fAdhVLPHPYU*ndx8( HMFR.ܙɁ { 9(  <`dL94IKAOA `{Rbd= qS@Ip M 'lL,H ß!d `O)IJ&Hw|FP{JEf gcA)l'(Ay@^!!4bQ`@80-'eOD J@%@1cMm (6ͧCZ#[16J&rQBD{ ""f ĈqPP8"l!4'B*ct4MݭEE s:K}P2n=A Ic"H@{ "ꐈ`[oc(m@2HLE ؂@ U!aZU`:@`LbbRoiV*ͼ `ß1< dwPRO$./ ͮP&W2%1@m C.n8I&!2m0L dɹkH)p hHFoU;di@ł@pNۀ0w–2#LcELV*2 `]+R=IO5JĺL.IZGd_ivuӇe\j@aأ Kvt %`zx5L7;7^=,XdS=?V *h򼦙Id@u*WmYqm?˕Jx%<FPTWƬʖn>,k2iQ%^kŞKeyJuX)4TXm)ZcYՎ&iwぢlcF0;n 9pKB_[Se\EWl6ΎJjWb4 mB'܏ct)c".|1wVNk+:??rxvtQijRkFgp>C%-{=hh#׈O'&3Qh/xnGM-S$C/2)+7.O Jir_k>_ԴDtOflS@3lTqq"~6pHD()#[+#'  bFsMvo qAU3M'-Th>i8Pٜ֦9&مI5wM+-alϫf|-XZ^=V5-4k?QǩtPѽRi>3ͦ/°㖫Tfk.n> Ӵ:I.ѾӒv8!}[UV4ԚTz+Hhը/xi>?Hͭ^?H&AҐ4e,ϳcM2v_PUm84Yr\sB=}Fj:~k4i5.~~gq,\4~mGICC R}:ƖmўlG)z:ԻTz-XhH^VÖ2ĮHUA#j*+>~l% |A6vGE?:Өk4)hqOz|IG.ur|кo៦QCMcH}Mĺ=^h4vu~螢ҳi+2A _=$^:h]lX:VnKF4D_~EF6f);gy%-fG9>kK'Ut~e`:8If4SxWBۺGQoI0h~擤uI$?K8ǛJp'&;֢j-'u6e'Yi?>?%C/:OTmZnǍ#w 5YUşb-ؤRjmPQ$#5,M+9.ct!L_-~K&&c!|? 1.#Ò3tU;1P#QaBږƐu !9 *FJͲюC*\C3>"P4gwe%ͿnЀ@ò Ȕy |e6@6H h@)G[I#0 BdhRS i쨐L BV~!(='( te&@,JEG@AHQ"|`i $Ohc%YHb\fDvC st$&0L L l."e9@YP`Za &ёt"N~J(]H} E3<%@g%&[IDQAa5A(sע0 pd avb%:aHtQ'ADle4~S$rEb'E a,A@:d(1@2< @1:QH@x 6(mu6`CkZP[@b, -TcI?dƐ-`n.I'6 sTH<@ $@!7n0G& 0H4t]P o6Gc (l)d:riO=gk*k),x\>w%~seei7{$^um͒'P 7S#KDT݊%Mt%zXbnRρu-fX ͖ta<}䜕/&i٦pVݝXv4u[J.<D״zL!+[6YKȾ4u@ %ubR:!tzi>]Y wzwd־<œI?-S:]1 1׵MHmZX\Ey4Ƽ,KnYM[6fվRSkQ?jqvMi{r8Rhii?x^sËv72HC|wΰ]JʒT0/XG4ն|O:_Tzu:>PsT\s{Fִ9ug螞R+j xa"y:D𼗑xGz趖Dc`@^&r\? r|ݳW5zo jd x|kwE|Lt5Acm_RIi*>+aHtz'NJ3__m6gouϕ&Sht[:]m/j?WgK)p? 2iR!Y~+)^c _:|_kxޒioLiG¡HN7JwgNҩ(44䶣 칵Mb>έKDtzp47?vntNz?e73S}V(`O'zgC4" ?_/77;=lzF_UtMtGQy5eﹺ<^6C?ᾟUP6FIM#eߒtXJ'~fmTDk:goi6 5Iq_A){eGkl?XKKPVs_:z6_㧻j~Y8g%jGI iZ)h|XP%Ȱn6/*-G;6R3UJi' [ 17H%_lFg QS) ?T$H@P"@*$dJ^g@J@\d@A?ٺ`i@i ^P;7@ d1`-d!Bs(Y PQ8Y2S)Dp&$2@&ߺ ?Jb<0npΜ2Ȏ?t_#JxSQ p ‹vJ@(@s@1 $IeHpv.%m@"ȑ@dan 1B!3nכ2AQ@IB-$+.d 8H89E `"HElMA,MĠmBS W1*BS>T9@O = n V =@ @T:谰Ht@H#e`fPfʹ͕!i %Sت%M^L;ț$ 2Ź G1{r`npғ{\HhhGaāB *4?߅<TbY/M\qLi5]pAYe,Po3:mFf%Pf64Bap+&YG6fn6Rgu iҡvgR3'{fBc`KG6%&aM`oAvJo q.*nkY?w&ey3..ٺqsk]t.3k\ †2$Ǒi[B4Si ~56Tz!t^Vȗ*Zh+PG<Ty9_FaRǺӊ6t)CZd%H Z+e6Ψ42RTttY%GDr mg2eqvoCTAWP׏1y]+9,Bq]Xu-l/u:^GBIuRM'.(&({z{؃b͆u:tGt^FeŲKʞkRpB{9gHP׵DZvA"Q'hL6O&4) PV ҕg;YZ;#] "|qER*v۰|z>AcIj9:gA .(斢Bpt4'UVoH%Mr93AMH lj%Mh0i%rtS47T\q稴"Y~9)QvX^|-a՞ G*VWLJb?tAHÉ'ڇ\B;4^+% H;iQ;>xUkF#yh>~Qnu}E=6e _9>SPbW3S[?_GԨ7OE 3鿏玧 x83j䆚 Om8r}^q:.k6li0I&%fϠ#:OK5w=˝eG$|MZgnOڏ_OMxqC|9x+')zVz(~Rm LŖ͉'>ޟK)Uuzv{{0i9yI,ϭ ~AgHg2mKFGq[:hK>_P:=Mc^'Vh}>a]Q4z{Ȯ+—fܤu9s=ClLU~Ie5\#ʍE:)t4ԛf J=8|ZDҺLcWtk%~}ݜiS.{iˎ!~9jqfW-NeWEzn\gApO+xXr?u:lQʱCٻӝ7zsm?vsʼ):>{揑튤'ԟҏTj*WWX< ~i$Ԕ:OzucMZhkyW-Bn?=,=ǎN辝lh:Xxnį<~W~*y7j3Wp$n)Z,|iOP.;BSn1rcY-$_yKs&V UAb,'Ud,TQ6E.ȴ"Ɛ/w{J,.SvJI+6)K[НzLݻ8\~M-R*qJ :f:*lN&JȒTd|;HI錧w@2P&-'0L DR$ME`T T2>'(E D\& !-A@ l081D}S""FScEv!'40GH$؁4?D [#Ctf 8c)1| E`(, * ?t PhgLHpFD6yH   %d"GGl EA@&2?tS(E4nmm"f @ba(؄$2fSHdSd+ x[%0,8:/(  Eͳ72yCI3+.ͣLDb| ǎS`^0Ha I@@lcLplnvi`Hk$ JbLP2`,3`(E(&:&ƵĠTÛDSX'i d`$({W@b.Ar%kr11H#HAAgXr#4H@Sp h9f8{-²X11f&o$ FU{$ťF'b,ʖU~Xi&L511 vZ&CLed4V!r H!nϟu-SՀr7B(&T%ɷ$Q[lw~T6P&{Y(X) _ꡗ7KZj0H)fr܏Y?:+1f|u>oXFG f\Ԡ4rtǹAJ.t{< lA[DϬypңq!y]oǨwL5 +j; s!jhԴas)SE=C"|jdGQo5\}!{ .ymPu"&pRܛ^]]ȵ2V?m6i$(SwIRFs\P[̣P\_B-W8vcPuLDp{O3.)yx_ޏU7yVԹ_7-Cj2n1=eNVqy߿)$x|2qk3 D ZcS;.:">JUC ԨrbXL(sK'iu:G<.%yxtZ$ߎ)Džڎ`ZD֘+Dm&SL#7L`w&mXZ9JܲnVuC!VoCN5Quߏ)HH٦WGªo}8#tά+QiŞ6J#tך.mҳz7hw8Znφ.N7kfjυIF6d}G!z5*PSj=_Q^-̑Fpl'RԤP^Y0z<; sg A?ᱸ vflj54bE<s#M8[}J䂕iJӶeP~캢F*[IGjI7:Cユd93+HEQێ. LxWWG_.Q 21CJ-BBCŪ> ꡝnv~BE,1>t-+6%gO}{Li+һ[U)z^LQ=ڏergOE 51ȣ&tƩϋrk\Z׸tޒCYfQa{`'|wPtf|V(7)S>;S`>WgCz*äL+`|N @_W%+IPoC}!ӵUY]ڧQ PakK 7Z|Qc^ӍJr 6Z[3u~Y VzZfתDYmO5#0{ɶZ(R-/ 4MFYqK6M<◡G&EU:±K]/phrca>ߥ:u>ҨiN40.\zhaX# hݨύ%{)@7z:6>\cU&7u6w4)b¶ɚδ5iRn !_갬n&hiI]N8+M/]rO[[ADC݋^7K,,#Y1yME U.Ӫa˪V}G׈fϿ$y9Қy?o}^6#U}ύK7k!4c_gFOwV6E\ Xgob祣ŬO>E^ק}Feo\jSfBz]fXd?ھN!/])VMuzO2a7_4ti,%#zTmmq7'73u)SW'B+ZEjJBfy_K%];Fdxv4)K]#>OpRgX_E:'f:^^ȸq|Owv~Uvsp˓%i֙9IB@VEI(DXX$-[7t[m*CܬrXճTz3A5 FO봎6"6|mcKLr:hGE*}2<2[ᔓOV难~WIsO!{ ϓςx^#R/+LŒu`KBq2"ɲQLq2`&08w@E&GkEv@mˈ1@ Y0 L ٸ@#Ah E A -( 2%0H$@.@0J#Ad6 dŻ"8L#^lEpBy(/@b!1~L $@! (oֺD4Ya)`&d*B O !$n@f; & `͐_i̞PL\& yLq6Lie!Pa*C.Ftf t\2M  E?td1tĔ@ q8LbA`&\R`Q'JEJ(А4AC)cL+ XИ`qb0'dKC黉֩dTHI )cB)OQ>lV6}<<;f}JZtU:c |j;˄g_U |!+3lԵ[%R̤2>8jW9|3G968 i5%\q]ц ܟnp)GwB .6{_ ]vc\ohujZVY\YaԸˋ<]6*sXB6鞜g 6K 'rK&ӦUQsOxde2N̯bs1jvKreJ{LKk],NfToPlnA ev;[h'Bǵ'%^͢&`,2a<ZBm9'>DnmM0߉i@* t'LyjFi.*5LkOdFCD)Ul|!pkQ}<ΘeS52Vj9|u26Pnfɐ0Wz΁ӫ&XmqyDgGȌ󙝳Ԗ4AQ.O;$7s`LӦ. ӳEPaZ5SHuB@!+Cytޜ*ÛPwahrʺsͩMo]%SRzZo֩Zf{#Q7 7|׭\6mLmAfIqWW.z>O_4(6~ 6qXW״p/ڄ֥:&Vm?_?2fzfkt-Gfh /_.ym~pkW.lhA蟕ӽS 2@e73|d􎮟:=`/]s%~ǧQ||pbɓ^N隝'PԨZnٽ5zlxeGyaptu5:PY8hsC7Wg>KQ~P׵ieXlol7'9^~[.=nḵtnWSvAt53cO6uڭ(й< s, kKSG[,}OT[fќ.\3dk/z~5&*u*oӊM冞U7z KҶz^W{m.gGp< zKэ.ֵ]/I^1? ^ 4h<~=fHc0зվY_QZ%lw^ַO)94~x/)k}SН+CWR::`ΥPGW~$%GcI[_4q`$%4ɭt{g={?vFX=+۔}GX֛x,^Ukf-Ѻ^ZF6m`WSGQ7,|Y'~z;W=zy1%~g?eZs/Z0:Lvڏ>3Aɧi^-<$\Q]]~&Kp;3HXq*?Qjl4ʼn]I,8Tf@XU'tJm?~`/+NߊdHǬqy=\0Eg^3AIn;U_|NR#Q#trެISdF/UO__Obl8_S)|hߨ:> ?P>jN. >58MŜZLb.J`rPA).PЛ`pt&.I@-=$š0AwHl&󜠑8@R%`$"@0-*I)'!p $`.L)dHHY&n. %!wvT $`.'(`Jw@{ $\ $"ahm21(N.y@X%V2P( . .@" L2P nc  p:PL o)$d ĠA $ X _@1t | V\Ǐ{~Ҁe.60239@';$Ÿg*X[< q+d_E8) {!H1r L 8@ L$ a1!0>baPe$L3$]%$@e+ 6@s[T;RBcZI3 TZU' 4ӕUܩCxpm\9;G|1ʹGWXt<=!VtG }m.`&z3_-e'Ѻ>+Rp=ghQ܏U)ozzwɖǨPK9ڴժݓ!jQ~N^ɧW 7MD uσɪ˃N{9cAQ_6ta.WL\.C']}tn'(62KOx=?Eu[y.9:D\gwK} Y6NPn)eItU.Z@_lꆳ\\te-C}|:I6bdz"R:v؇kn\LumnnXX& tvȫDI5ei$6 rRRM\-2["<3/dJ=`⤺t5aӲ͑nW<9&Q :utQ/Wz]kiuZ/4S\A?!>!qoesajm/ҾL[6M!<-!y<.Z)bN~ (z)KU Z*5 -A PXa>Ol]螣i:6QxHl5̉:c$3ztzQQ}zt5sal彤x_7咅wWf05ֻK{#y?V'*>.֘:8o^l̮Q\5^kWdc\/Rw^GOJJ;Qbӷlıⵛs}yJ; }J0i\"W F ?EOQe8i[ky>t+Qn<]*Zm>0?ŏYj.#꤯w%G(n$ZKV'FǾV0/BO&{$6Q( 1eU}P%^Pt&m] .I"9ŧ-PCt)a\P*b#8@&o@~>e[lnP#fmt (l8 2%L <-,:#$T7HtILra3c]B a D,@O| vBaNPH3 Iꁂ@HhM&ZAp`V !,ݓ\-Pop- 9 .9M^D& MpI$ZRINPUOn{& N,c(&@YbBX%4$@  ?VCA1܁@(&$2]`7IhVFY$uH͚d+DntcBxH?gP wryi"Ȳ@ c]acM9JoN5-%cMn%.R80d^=l {5Ϊ kI:Hp^V"WIP>wzOX_3 kc=>Ln-G;i$%f *pk q(>2hQ| R]R&tR$Zl촊40}Bx"6T]p=M9)r#O˪Ǎ[b_StEzzm%#OOQѫM'ߺHƏSXrãgîsk^JWԶCF^8JG]Tr|3F wPuglh!wbUjȂn)8xJQ2MVO=.5*7sR2Iit:u澭V"?o2 1'|$Cump|I\<}Tu5h~(JX ty.Wk+iSq44crFqB樮7J_Zus9qi2G]y.e1ȱ+ł8wgtQ®jp.|3j$E<&8$'UW)Q )2]X#$gq4Ϫ4tyIGGc@2<眘M-$5S|clI&h3j5iSxo McЦ:VKH#?6NW-7 yH5[.i)'[z3ӯݿb+ʨ6z}n޳tW~\ZzsI5C" 6\rqP08~!5Ķi. 窍 7KlX[l垢N.^Cd۵G<*?ץc$˽Wrb{th׬ m #iRb 4]XȖtT4uZ4^y2_'YN˱y-YYMӓTdGz/IK_F&,.Oƽ@m Ǧi̯y%'isL}UJ}%_WLadm'^O#[OaGȺ?ot/ᲵQR;"n!\\?C&gs=_EKGe*G%$dOWVvQjIiKHOts>Sg8=7[quL1L]Nδ'VS ͦWj/O,x҄~sۥ:M75%|!`kzF:혟ezԛR9j%/ឩrjd.eʭpyjSv{¯JMh5uƨcU/匡9d_7}g5* MZm^~ sM:5 4s|JŲcWoSmK#zUOMTee߻q~7Ԗg}[PC.йka2y8Yݣͫ)V_}o^/J׭hSLn݅r}pfϛ_%/Y?_OzfigSE68Ogotۃ6M} q.{O;SQ =C$}Cd~YV}_/^ƅk-sf_Hzx:y+ >Uzw d5[q EOՒ<jr]tyU6JJ…է-YO & >H 7wMq|}Yc+~ol'b7G{y_ʵAnGO¢{2vcS\!CeȎDsF] Ғ4]+UZZU4mM,K}dOe 3xO誚b$Yx̏#>a5ՖLB/9 Ƹgwp uG$D >6GAPI}rd\贒.N?7k r.7ryȬoa/^?5B!1P{ ; $@ 2@03$\ :F8>ϢqG ĸ9:xڦ~y,2q3ǽEmY"A '|q&m(w粤kYkh=4:*D /E?eP,xs4Z'iG?Q\>1agJkH^AC_@Ө)OE_L]S_9m#\;?qê{f<ι[>E֗NA}"6o ӎ\#܇ n,pzxGL4p:AK(`Q:lD-l1hhͪN)ii3OM8n>W:sɥ"wEtSpf#諔1XL@+܋bmd>vdii>d(M>Jq'ޒXӲ:m 6|Yij}}%0"%Dh9Uվ} [<5,J.* E`{r`խJjl4Ҿk⌢Zm3!uiя :m {z}4wrW:vYs@pmnW F[yX[JՊ4W cI.PF_',N7lDh{:G eHC`LF3n7X6ǹ"TtyTG3?/ԥ]KStG4*IQm>Dj7h`nD+YFYuwѱ:js~1Mx"%9J%-c&3X vt-uGg-M+3f0-*fZD'lGkGrGJas%)bYُhWY\09|PJ"5ORf#e%9\aou^"H.OsZ:lݏ2d\&珓@?Wcvt॑nD)Tg/*ӡQXn˚BmPjj;KQs˕嚌N2sG']^ZUjUh?^s_,uWg"/zޓiu4Z0ڍkP<~./ՍH.OS=Nӹ\8쾧A,R-U~}4̣L|svpjr﨎1UԦHi>)#T)#үnu6<8؎Ƕg:?MOUM Ȍ-%ǥen?NUWXzf! koS7dj mSj 0Af+ɟzus8_Ϛ.7Y:JiR~lנIz0qˏ=>~;Wd<ͧL-- G1ZamLrp+9^Q:_&5i]yуmLcQxťsHm.eh+sot?I^Ѻ d|\SວFz=ơ!{#c&ztoQ,0K?"e~ޭktӬ9AtY&Iet~.y|=L5]cIKNw5t`w.M?9N\#ǢwwiQ[{{x'̲i2icQ6~ƋwjKdi_k'ٵ-,ݞg&<2g*zw e-`9/e*?O^KJrGCPW~gG麺eoTR/k_y!Wn?~DOf\0]w7ZwVJY6ەĽ9JoN޾SjY԰ʬly_YQ &scΥ)KO<8bSΏSh}b# ixԞO`$eQ>&pH^f^R~_e˛[ j&YygԽ=ΝB}0 /&>Ox3jiv>Iٮ_;DLz׼iGRA@K5Hk5B bzGK]W.u^ pTuOaao4DR,etAJ~_z>c= OY%tiśW/d@HHmk /(qI9ۉ8>Hg(`Tܔ_d&d)!RcklrI@0PIG[\b&P&0ÈP%*&Q$ ,D]+u}EŤP4@K[L 0~F 0)2+SJ/,^oqN-tNmv@~ [ ܠL @k\0 S 8`U(H.%*8`7% |> m6m/h!1$'`(.Ka;L^R& H e4#AК7vѲ*LO1 @I[H>M($ J‰>򀠁$J]rI.0re;QFfA<dGY>W6Y'Cũ3MjR`fхc} PvѤZ\a-:0zC*7Jn–SPh `LD䈂ea)N N9>Jˣk uG?[G~{?I<M qxۋɢŸE[&beP"Pִ(UcX!akWEB2Lan3BzͫTm )^$dc\ittQHA`]J6|'z:6hM\8?E&VGN8>uYQY%TΉ٣#Is8'F_|-7ŷDZ~?BFԢÁ. rN'/-*1UlxʴiLN*4{= Qi!w];lԪC![r7>PN&vD,sEsL.]OiGKmSV]ݰ칵Nn]px~Yrܣ= E0e*vazz:!4̩WT9,[ ,v-Rq[]]9T{m<Io">1*^oQgfugκ]%~{ɟk'&r{.IcY$]s4-é:H lf5=$,hS9F)#=g+.Z"fZyumt`@|]+$41òj(E)m%ucʟ&Њ[h,I; >~g8[ 3{.5&ZԸTtM164Zhв0!lqO嫦k>'pFLha3@[Cൠ=NT₹]?uC\CQxR:OWUT[DN9g#5 %Rdg]3|ԴD' /gkO&IeZξ8aǶ(OO%(Rƫ56v+u-.U$(M%T+U(:-sp NP[MU}Vڠmh}W]g6v9O^^?! 11}IVo# !Ek^.NwR|)BSZ#h%%wa,R0i`"{\yye'mk Ro= 430rxr)#Ox]Uӽ95j.=g>\Jwg/noL~[<%9Cj=Ti5WH=_a_$z1'NG,IJgj7JˬW;Bʄ|&=fB7Kݷjǫr-nYVEҴ`l QgyQѩ}mX睠%3FŒ&+O復~VGM4'oW,sf>*|m^*l,ty^^B94=8$jMq f:}E,P=[:pJV8-t>A>[] %o5:~"CW56p۴;/~/>Tw^zXӺ*uu70ÛH^d3+3c(mcmKRŏ_lŭ=~4?\Wԝ_eO!-m0I> h_h4y#]ng[5]&7U&q_9& YHN+,KW7J]6ii|vyϖë%}r(ji}u:q_'<wWewRgqBG[~f~Pg 3\!Ga<,:MZ0 k ~\w3ҠogyW=?t?PQZ\|#i}\4_P|BTR"n8@e@n&Gdb@%.!9(  M4Xt]0,XBI$Ɋ$Ȅ61eE+JD"lQ@PQDw"$ _"BLed2{eB,G+8 eAa.2P4 t cdF  (O3 L)`I`i W0 P69͒\yb e $옊J Ҙ̠ @ iR1)2,oJ`B8|$I(m0gAA!1,UlP"t{.ܐ2,O( A1I"P0`,ZR]tGcZ13DPτ_h $@L1O'fЀLSL@Ea'@>!1 [P+&ɅP\?E d"yq@sB !+|pG( rǘLabK`i$ALME&CN&oZ5|ZeHT*!0dԔ t@7(SXgeE-D99GfCS*N}ms 4/:j{}j8ɛ" b3jϱÊ8ErOA+6K qa 'e ɚN$R26 7Fjp/$_Jʮ09#=A T+w͕2ѧ>]dB:ok]5u89C㞓;ipb{+ϜWɋ 0D9dɡmVCف[ECaPPaUtv7G'47{濱?V?i߆ DžO`pJ)pla8/]=%6 +tȤ- (`mE.M gV;5n,rjΝƑj~.)s(ƙvٴOR c[i״ q-TJ_h|§8V Va!Z~,=K am:dӽMVfTv*HV5>ٰk.g'O\ ʪ1:5#VxÅ,acNLL1м9|}F\$/JG܏s2o 'uQE(o;:Z] #JWɒR̕+ϙ1J2:'+#Y*̨NJͣF4SyRݎFN.o$&mع:cC)FΈDN3-:#|b0fTm<l]pe5#Z(I!eҡųJlV>#.-DԸGG<0GVySz!&а3ҌBl˒΅ 8YA9:4i4ۻ9e&oL4b]mSCd@Psp'DrEaDYaӘYFL&;,/yIȍ_VoJ}0N(Yġ9$:ik_)ɢ~`Ir,gR(Rhl 96fr&zt̫Mk5 @i 7'd$ՀRcMrdhz_}TMp1\ޜ'r=S.Hj/PӮץQc! 2}2P퓼d.*ܔL=[4AK&Kĸl묜\5v%J%Q'l"E@*0;JFM#z:ޟI/*tag7ˢ!=.P Tt R{bl#Ԫ %q47K@Suh2 #GY >GV˔ʭx?$j]ImBrmHWL36: Nwы|J@rl6\ I݇RШ芬Cq}ɻ5iZ];oe8.ɚlZ*jW3VدB:i+Խ?ҝoFZjlwpʜ%85gNyp5~vQ7YE}G y:}ǨY>Jitv^ӼUP5yxGnvTGwzgnΗh!yOOG)nο9NsURWVuq.y58M4?^m_'Q+{}%+hw<>"OK#[ݻk0D/bKn85ߞhq5#z{=Mz4ݺQN^`8.m&G!y+|of 'Dsul;5* Ŋ=8ϓ_NI$=Mu:KEJKq NlUo>7C5>3<3U}:J?CWO0_i|ޛYdRU>Wg:FhmV<$GCSN?,Gi{FjSr=KԺj.tK=fIQҝS4sx'ynMr}WW'zOJfK$//e)Mf#ikOS_4y-}GhL꾿HԠ~_7G9eWMa%܀O̞9>fm'}Hi-1ؖOtNj*j 0mSl}IG+|֧>RJ>O4z_P4;( <@a''g]ɒ]E]D>|O]iҳu, H}Pu4# Ӓ~s8~USZKyWg庘훣@%Z9¢$LfM `P$M ).1#oPmd) Ġ ?0Ml8!:+u*I  6R @8 H qV~8'fQR@l} @D LE8E B1DMfDp3(6\ ~ !(@P$~xLZF@ ' 2@I 11rH,,@cn'@pBT.3s7G2_)`$a2{ $ݾPZ鉄6K t IA,;P",O0@2{ l+`g<~SAa@8B"@S" e yY%0X<id A,b%`Q$xEfI0d@ZDmX"LL^D eE3)@iH2S;To{%)8ZHLAe ۄ`AH(@O?U=m >` 2JJ}]TVe-vn?e /ϳ~'*R`~~n :Hml L- =@+Tt.p"D)*{-6*[qf+u"B.KYX+wAةE$UfS*YsH~!VjTwR4?uH򼟌Wt Mp^]8f)M^48@koӝΦ1!sg30>s~Ks1N-wxJ˂x%" -2S4SDU B"_.oBu鰬u~u=-Im*pQ%*0Fz2]ߋ 3`e0!uF)cT!lw\2$"cDZQ፷a1W 7qtlYpyU3L|Rp*騰_VSė1\MJAv(DsASc$ |rWGiT6Wrn_o.=IZW{كtM\ݵuي\mȍ*-ԛLndsƮ#pKuOkCKIhDŽ-S_GOI}_J+Pd"x~WcmFiK?ޕh=MMx+?j4>?kaT5`ngG&ULAQ = 'ceū}Ecj=%Yh\|絹rG[KMFG:)Q8gyk/hY{JqlSqug ;?0Mn׬m.>KsG٩>`tWهO)])hYv-=+gM]Yn^:;Lv^vfį*N2`|"Rg6XICKNƶ)r:#C),/lHخgd kc&˾0:CD 'TQl) x@M4غak3T15Hե6'#a9썞z4ꇵqR䩞Fm\ghX6Y].L>N@q %v;j"[3t4 9&od%g4kSgd)RB]ZEk=IÄHCHѽoIOP{o?`3ifk=F{4:4+Te7'^TL:Mf,ȸ`E  tFЙPs™IPu.[Ԧ^C(stcG[ZiWO|lY "ۺzcuM Ixiq{K ߸^Vfnzb{))k՝S)YûV2ݵ`#PUR~hT-?A]cAo|\ѹ--c#pI$ҳ]?QX7Y146cwfFZcu%rSTRT5qkv'RȺ7PZx+E-&ju,-pDʴtt:Sl#)37;:ZEFu8ԃ,ԣCԋrmeܛG.ӏ~tucGi]8υqʹfUF*u*DJjv\|vi&Z%5.OUb ih.y~)5D2ޤwL O}R9jpeJzZ7u.wvr\~'Үi;?/Pi Fz34u@(7}1ii=:M3{A|̲Ccr\Ue\ꖧ!zO% ;s:h"E츥'^:Œ~ۋ/9,ޢ>KzH[igXΕ]?I_q彦|/ܛ?-k+q-Z&%Z8Xo>UU-t#%:/n ( Ɂq db]nlgiɈ fܦ Lv@T( L 6ɺCy &MHennC!&d @8@0f%@?W ' 7($t cCb9H( 80+w=TŒ`  L+Mn$Jɸ~OˢfP",F @2"n(˹  $&M@H9m@$Xce{}SA ,E./w@{BL@@&?䢀`pP&`KO7(lHI"gN!2b2<{Yl/ŬHaݛ@DQ$&0 $R< .p-( IY3td_[ni6 HqlPIͧfko 7̵HWF+Xh13DU'mqql%6즾P̺wBeR+SULFy#NT4GLȹ> a!sO/*сO+RiE{˦ao|2mV .NO=U- (*gO=D6MwGm'SUGyo跴jtۨ[c|dQ/;Wkk\/ݭ:gd;|Vu8ux}STm/Ǝ:g>K6항?6Xf~bB<aZ\ovZ,u(6qhhM2tӮiiY|r-D6ڟ\ӝ<Ez55̋)Isig(Nȟ7Z3iwy=~e=2>kSOkQh]s7Hu: \qOU&V STR4xq4'#ȗ1-T!Ԯ\LCQ`&W)EMq+j \ a5 Hͨk%jf6Sk@wcI*:b xѼhsZptE)DZ4S%m 4oceՎFhpx] K>1ʧR3* |W ,,SBk96ttږTYIś׸FuEh9S5|PpB cpr `unNl0 s8 PF@;II+ "$ pE:, d*$=ctsuKkkIq!qD` s4)gs$|о1ͯUCg=2_躞ʆ *vZKs)Mm鞟ҩ.R=&lvLj#!a M_P:h8IiCIe1(*j*F{DOZi kWVvI0ZVcJN6d~TW&"I(;]KnPs_.%z< 1,g?Cֺ=^M#q)= zg:ꏧ&.%T43u_Pu_iӯJz8[-k}螣ΩSk_~yx#?[l莶7́%|S̔ԼfieTV!!rx6}\<;goH*TQ]L>!i$~oF n( S\A!J2RƏ539fG8h͊v%2d4 H3PL@1τbG7@h>YyL,e4"Ō LA5"nmPx@rM(q?L$JHt M DҲL^!T$`Kr %(< @!삀n@Q.@arCYbgK@3b}4ChH`&Bb/DPg!!X, tA\`~n1@@p /n!3x''dI`\[Lx2% @Y<v@d\τ617_ !Miܠaf h/tL&([d y"7@" eP`sB1{Jes HS)<ǺY0x@Bg`"!! Xqa/q@N& @ @'@ #"`؞Se1Ɇ@3Ő2{vH iEHw""2EX ,;{[@d/ 2olanc v'Zn8@Y,A+Lu`htLi1 $#E {,ђt5:תsez8,}/3fn#s$}F&Q"Л/lB.%M(#TQ>IR&yVNH9I*TLߙktERn %>JnvBKlSwp4֑|H]"2gYAmq 9 ȬrZ`S.8X;;PCӣiMs`{2>YI*:T.=\|Ei X I:#n>7~ ysSkNxc_kQ=.|}c @OaaQȹbVR&~9l\#Q^ȚEZAM;.*gʸɗ 4-ycfĵZ7K8٥/$nV~FO}wAʵ?o tSH?2EnJ̝/`7R^Eؽt蚨LDVTK̗B5Mx54%T1L9Q~z/AXz)/BF4ZR&YE%=^u OTm]l'sV3ْFMu+R@OkI\mmJ(TKIdQ;O+ADtb=<_d##Ho˙[C0\g7mL-Pu6w a<mFzPH+ǢLnh4=fK7=Oq &=jni?)ׁɥQ2}73M53ǂ1m}q}*U>r6^ B/iPZCԘdn贯W/ǛgһUt}QqPu=2gNRO4:~^-2OMy[uGN}7VG٥^ƓCSk7NI.Ժ}=nK^7\/?Sp<~7OuiSԳD֝itLt0ا k]Spk$vIhX櫃{u'}:u?IஜZ7qy.O5CQ@awKeƷ4{Y|f}<7J,?Xc~5j6$9\s?ɞX] : !sK#bYUս<cŤteZPD| /ҴК&U/:xN);3M"KGucٲwmvk#J,|s3C6Y:;*\E]2r}%~!ve߅)F^KF:Ysᄻe:C$wX~>o>]<u;Oa"*VIsцjN> WL6qZvS_[_꺆k٪TBR2Ott:u*Pԏ̡r\5>:҅NXi17Ehs7<.}G[2 }x1*>QX4&PSl O^dǼאym5U{dnW6ui1N%R$"ɐd&"]T %,むeI9% @ka. s*&1t]R8M qL, Gd[)c&8Rc%!` 2pQ6U 'ۺsd'V:' q&錬}` w8Lv `2/ 0"9@[L R2D)FĤ0f=IBd'((2`RBoǔrE(8( RJ̤L Jr*I&Xϔ3iL 3)3cX7œ,R 2|ю1 20qc (&˘0ɴrAB`. B r` E>bO){@Q-{ @}"`QB2Rd<. Za@ك(8@ e,EaE[R(@dc G.opI Bc(| Ld |& @\ @ m?b%Š'c*@H 6'"1x@#l"U(a^,,( 5R&X@X+LGB l$&Z:Tw$xO60HBU\qihXTc~.+:/ql{BɎ2k&!Kd[6P%l EZL ֓=E!a7iaPI6cI!Z6o;dY2_Vj@r%M_&1lu  DpX&`8LRՐBYS()z9ڪ6\sj1Z ,6ߣpiׁ;'g{C\Hl3>K] 3LZ]h&BL %IJ菠 H.pĚ24ܵs=<_hAҙls=; ۇ[dr/D ROy;*L!SM!(,&yi.=I ݓ' ium֦߅JH;dɞ=Mxr<郜?z,i#+ЌjSY.~ ;V{vU+6k-TAOWJ=rE]ͼ>F׫K }+t]6(E\60dSi_&S|SO_Gs\,#i.=0I:7iuz隳 28AU5ۚ=cULW rBSxK6Q-:] եֵ{8r2RGY7=uMk'zyvtLkhIn&iYqdF~SpGOMVvsz?Ksizq]}EԷ̦ L߅YgyjG:NJg8i;1Nii;z_rV0ᳮXLmkiΎWG;@|e,\6*ZͬL-ixK*[::̭#6cCkH鉲̇6kl_ ʆI|p+_c[?lk]_Vk(֩. QƼWNiU+؝?_#7&38Y?mfɲWq߇Ȧꆵ515,8F\29P t3.XGɄtQ}Ǯz{|XZTKERSkÍ0Gu?r %ֳXoG5hKnK*_5đ(Qt=cRv+r頝t]jhx]QNJ]F|QWGeF'=NIm:z} <͛ۆKf;4n>ʢfMЪ; $" |2Ź^n_Z 8 Ҭғ^܅I;38$*pJvM>snnD*tm4VJ't5T6$WU |bT4Ȑ.}V92o}[龫}?MKQZ>z.$;w}ۇvRASpƓ_)OuTԷPUƍRvo|ʼw-6lÑmi]:;TҦ*<˟$Wɨݒ4k=%5u-oIԺ"}j٪4}n<<-G]b5$NAį>b#嵞9`P5OCxXKkǧmvUswl/7p<>ph ~~Vҫ;=Oz}$qytҸ~Iۤi(]~?îW%3n43_ԪtViRpuJJGg>uӽgMVVFsUłVtuIǟ/wMvqݽW3zG<֚UUE%xYɶ>MOV`^&O, a|}]zYk1#!~7IeGӃu]7OSTڴ76se=|c72k$>j).4Ci<.Zm\ ?tUrTL D JnO<`lKϺGzi sL+?.y>>6Qôt\7MA#W,_~ ʿ-ꅕWsM::4k=Tk/ˢ)r>fzyIQzYu@rKkaipζֶZ~Ö)ȎG4hS@ %&G|}Gib0r~)\,zU5jn/K^gG I2NRmW+j_PWW\`U#͞YjpySG3Qbp3 ?4T KꘈH"ҁ2$d(0  l$G%hM l%PLE Zl}i(&1$\d&`((Ex@\"fJ[,hL 9 7@(q Em`fИYX2} Ed p i(tV(} @q&P 8@p,^@D)8@.e,H>P"( />@!T@ De0Oh@p % .Ad! L l$& ieĤ.H%I@I2*\.I@ZxT%R4D5A(h!̀AkY(# "P v̒6@X"d $A")?)'&"Á1~o8@ EE+V 20eE'eؐB,(`Gv  , E @En"͸@s<`y㄀& +iLF ʄthI#m8m%;+p趀*to4k&W_%eܛL7^u%g^n|:%-0RFq3uv)tXJ J4̤'& i5-F4@I|\B*ȔmZ,[d"[ȲS I_ eok֗U\ hގաE ~Ly [)?@- =@ݴS<:aU*riHpY:\≮\XthQtinVpuőݧ撳I^9#: WN҄Jf*]myZY} DN7)vOHXQh=8>4ùRn~[]HaBDXBAgtbⓉk 2I\a0 O:zJ pL`2]BG,XLTG5 NsE.zI5YձvK i  F|\[h:ljRVG?X%#X{0͒v9UJ~/No-%2sze9Ժi iw~?e NZ&}N-J1զX9pom;hs~'?܊!mm=W52k2cY#J1tƸjO+̖'|ǐq'UY1VJYs,igGP9s]95 2zԉ%9pQjui'"5irD1cEZD'B2I|{q&q}MҶj^Cy+O% \O~7nF<`]|\I>xYL`V:f"D׍Q`Wn9|֋%>NݲV_,\X1/?6=ǛG6'^d:VS4ӔCHbP;@]kM:<^5[’/QB>˝F&/X f Ipg/#[6PFR|v'fW7&o!9+H)BgW&CJo+͖*Tw2[-d ~$XOQH鄘> tFu'*>Nsfيix4mXTY,Jf7vvt(+Vv)R, X:ctz{CQ>z%ZT)% i5Sn(5Fn9Y=2K%\6Z਎'J=.-\QVp pȤyiJwR46&LֱaZw;#2,-5*/3tn$Rjd"sD-YB HG0oj&=I䪠Z[czfRc}&OHR*YL3Vamq@^F%-Cmsd9#f6M*%W܉YBV/ =-/k55;+{+;cdQ=[t鱔k|<~4GT2*f>MT -[M\ݾɗQ1ۑ9q:D8m~A )]ÔsY0Kv7q8uj+ENZWrH_,ZyOou`qZtuG|nJupp/w?Tz Tz--F$na|' GN iS}wMJAH%ⵐvhuRM7/KL۠ fZg=-=VikG)Z|/zH%hȸg?Cе@U5TL x,8"^C> -x^ޓG}s~׺u?k16͂qɷx\b}i[Ph))`}:JW4uzG6oG}τ5R1ˊ~u]{ic_M2n˨JFt^LR]^L10>{'51˧fO,u,5kc,>:F #_O|Ii?~7)B>;Y/7YXjt[@ݤGchq ^}?ޞJQ3ퟋ??=T~wWA+iÿx*~e~/^_?7jt[AkqeJoZ{/iQ AAF)*g⧩=+F_Ӟb.pjfO{e+??lQ_?tz.ovL~zX|0y%֛-&:7CS~ʌp SS?@jjG6'q}1!0!a0TYVYp) uX1bt:OPբNI7B+qjӞ5L/l\*3 QkkAϑSӶ?*'.(=my8 u٬hhptQi}BCG Y>֩lȸ*ax_5joT~zt JY ^ jjGM.n1X+)OrdHTѵ^iM,Aqu؅Q}GTff˾#0Xϭtm3$g%$Dd̛ CLYR&,O< "&Q$P"p$ X$;mS7 QC%t@ Ð<  >B\Er+wQLTCe#OqdQ!!G2`t+p9AEn7=Ot]` ` Vx@{2H$ b?dL~9'vQ w !'2q((*%@QBA?T6( +@ (8tN@/p<(G8}B!{ 6X"@P0Je ْ! @*7%X ,$@ d p=6ځ,bc3 AqsK ,"A%(qg yNE@n,X-?dXYD 8Dr$/'@XRD @/d,eBg )`1"Hy@EQ@@ &")@g@7?)b(L*DŐN03B+x q();( &oAIf?1V3u Р@hn8N\"ta[WY}y]t'_a4r$]g6٫K+\gVA[L7"vR[@Y۬Ҿ] l..Z[k<{+>K_08er7u$u:hts`bu=WTG 2Ƹ5P2:1e΋*w,o*cr,ͧp\̮cI \Q[<)B0l`?Z,fS{LmJ "EyKZT-. ȭyuΩT9朒 L]cٞ,:L E)_C7RѴ$Dz & WgL&jWDegT%c49*sZæ))ʥL x*:`TfVLoH= lߧ tlip6xGd${Gs蓹u=Q+>ҩ4|r(3iG` WG7znM͕Di'.Ε JA.)I|*tT4rG1fdA] *PܔS%Sf%'hA>3%&dTHɣiEq5]=ĀSqjQh9=,9>A00I#(qu+R0[ qf#+S n\jf>VUGz/mS ~=]vSuThRPo&YI;\Z7*z8{ \MNirU> = \lz9܎pC\8puNTaf\F5X7'z9*J{Y[ԏYlWsk?E69g7ܻ>鮚Χћm_*ݮż_x 5ks٫5ox^&`άhnN6;nOs %in&y3QEl,s4N'cXˏl39}KںTih\|Gt+sJ :G>KVVs58W֫h|G]VP [9KF(˩9#v}WҽqΟ `JMn})6}tB{tBf}i0ˏ~GV\Z(dV}'[:=G[ԁQ&ínv5Qk=WkP|®}ytF2JW[[V5(l~E'u3TuPGM/VQE~D'/g\Ki=.YB''Gt:gP23TZ&ev,=IMsZo$ o|gO_CE#VK g _K+oQjO~wAP-CK6=} jF7w?-wOK\?|^NcJXgu[zuGvBjk1|4[ ͧ_+ޙz􌲥7m!FHC$\&.^74T'=7tz)zNց0ڢ3voM?ofO໖>x_.?lY:zRU[ݎ>W67G=vpkuZ<߈ݤsi3f?\I|3R ( 9X#oWH.a^~C[_fEgս%zL?i7ixYi=GgдuӼo'rdOӼ.s2'$l~YY`3cQ0XGӊz4#4辝ִΡRAw0cxLb|֟Sөn.ZfFq>A?TpAhɌ2&},YY^֫ FLryYz<#m$}_/ITiiSN=sO$H,ot@@]xsG7ggjJΣUNJ9qC o]E_!0 A^r.HY>!.o@@pP }@&T! =b`Gv7V) H3^sT -I6DQdXP,G Z A̠hyC*זTπ4ҾT3unZʝ>dR9-5VRx'6MDŽG5,%OlSOQi YXCt\r`BÆX~.69=|&iu*dFJ(S*mʌrTdM| /Qʮ&FB+%*9&\Ep]%l/61Ud@!q\"D@q^+i CҮLD=˳$FClrQVqg֩Mۚcm׋͵mg?[SRG>/b.2mT s.F} mGDp18XteP3xhNYC@[T9TtBC؞âM$3K ӣ EkoA$߉Bt G|#fT!zGDU,,-p2Oo#&Z赩6\Z=L4+L<=Nz#5cg9J:g#BŔ$t)Thj]\0E0HRh3a$gJYtdxkɱ*PqU3U J(èѱT;1.ڍ!kMX]vɕ{ynj8m3`ˎqG Q*T;i11I 7J#GzGB[mk_Owk(z|A`$86DŽzl{Gf<̧ S^je* tQGz֬Y`}qJw?յYzG\һTӪ ߕɨÓkfO=Wкޥ[KtP\=x_ϖ>͟(Y.gֺSo@P44T[Ctz>{Q?|:=%mwKwQYFI[Ob 91m93^O)&#j1gJqVc_AVU59휐%[ 7=ÿi;i:xcE!78y.,r N2ǥWZQo^>j4-#__A=[u: 9u׬O(ˍa} wE:9HYϺx9mg7OugUڬh&;'_] sy~GI(qƧ}tve^,{H^WQ|+1? }]+_g=A>=HGhj=X[pr bZlyw#뼲ZNqη}?|yHuPt^gUM*-Xx> lqau_'_MCZR|+Htn>z}7mx||"O1_+6 MrʣS =O=*ia;_! >^Np[/%ekNzOFZSjiFkp;v-<GN_'zȯԾOY,=/SCu:Wg+-Fjqy.=^'g})k(թ<__?(ׇ/\&:ZT~ln%g=F.d^=DZ3. Q3A A eDr m &qH y@3@EI( e ~ He۔78@d8&ے< ACFnad4Hi\ qͥέ 5r>VX m?s[}׉Jy}/×]Ƣ#qhqaQF`ڗjqĹ LOhfتu[A\E83@p{lN΄ԗ~Sd?Sm@I)8n:rrn1Fe_Fz|~vJtBePlt)Ɔ iZ#mr* jfP9rQUpy0\Z1#sfW,XmZLԢײ\Ye,Nփ_G[=&z>)hhuUj(}2UG:aI{T_q-C2gz-;ƵHѴn=Tl[26 4S2&iA[f]͖cO?4LokT*jthZy4kԧ9%l{IG'4P UZt'XnUԵ Pڸž8"ni5cZ%م1J;Z)E(hv1R~>ORe^A?t_?Fʮ* g(ʯ,?Z8^[Sţ2ctVv> 2.56qӺ֕z}}|2rL#[4,UmDF^7s%s,'> :h(A_J:hbNvUz9cЪ5PUӉY En<}J.U 4m-[77x4:n?,|3O0"͜^>gtjj[HdJ)\+Fi>G8]cդ`)8ptʏzFzK..u O>-fzΟeC #M#5GO>8Q!f:bGHPfWN)S9'Z%VqOS(֗\57s) RӴm!qk/Y]صT:#{Fw=K܎nJ_&<,9yg< 0";!AmcFmhk%G, H1gL"=YoS7X횩H8``.pȻ .%%ޙv쟕LҊ蝎%[%fΨHH;1e Bؤu4բ.=>FbtT`ȤvVw=Sn51^k# Nڥͣtz|7{à'gGj y6vm9&<n i?p/uT4ŨӴʨxN}M9i6WGTeg?QQI-c 5RpuʿM I% ѓ4hP\7LX\FҪ.B.,} {@9Z6Z%G'r]>[Mڥg뾘E$'h'iݟ95TkiK/.&uf}gcg޾p4L+&i⚺F@m5#,rc?zgպzK`9py$s<ſꪊKPmAbW=)C|ԝN4_s赱|OGGn zlMNմnyxG] J'ohҖ4z(Oi>j5s <{,y6aMy-\hNN]Kӧ..5:]{]Nkϟ"XON*WJMԠGX 3Ǒ)hGY puˋO~SOo!o1<Λ4~XZ*mqK7OpN24YvkhkYLy]pzS~nVDqKkGBkfpҽ<QSC8UA&W).?EkfV9 xz}nLQzIx#f~3?8f~ҝ׺Kz`CãejciyOd:VụgpWTO[ԵD4utG/ܯˡ0V~t۵P./Ez:M[)ilF9+_qxظ鞾so ñz{OKi6%6ZB#.إtp:fSC^tj82 p/#(< ?"P;mr}Ku{4fWzԭiwO1]mS~ZXNO2O4I2?Y%>ҽlt_qqzvzm)궰\4Hɜ[=~MuG H+u^W暒ܟ'|KQf됽mryZ)ci3mt\7- rT` Q $Ņ hN\7"¬ UNÑLACb2<n/&ݓa 0G @E7M@\&͡&2EY@I@>J` x YN۔K #qjC]ݣ쀲Dd 4(V[0Pd^a9Ii^{VG;ߠdLżwu mp) /I$~ qcm,s$rg\Hڥtʕ\x"K]v'AHS#pZe46A00Ul'=V5\AR3۵M%\; V2`!k:(Taeۅ QбR %:KWp3|zCmQ ԓ:O_(hu(MlRƧٓWAaXé(ǃHTk <[4)./ֲ3[GP8[FJ= UnBR2G*&$Fsv4mvsjG4}_Jh6Dq,܍:^ºiro:wM+=r\Y"B6ݒ!"Y3ۦjeGSNpN*)WTT2#c]]6-ujL"6|l3w5f93 .5|P\#^5lRCMnЮqP<(:<)E+KlSMb.`?Kѻ$J!mbҩ</թ3ZEkKEROؕ1|No,)j\~HjB6peHr|+:]]sr[F;_(/\c_Ok:~4^&W\cܟ'iXܟ'5La{LMŧѼ$\_)GӪqL%f#k1uo2nH5=OBҳGJ}Q[Vk񵤛y3Pv'M֜/Vz LUhW?tUMS:꣢I${χi0ܱFǴX&}C*8lsjK>K<Plif*K :Y=;Yl=+?Ui}6'\yx-774ZPCQ;Zt80!xŝeHrޓK3z%BMB>R q/:Qygv~OS7U٭AE{exk5 ~GuA7zG)ѪhH<ks=M3=<3鼟|t)hzU=n&.uC]4{dҼO58kޙLgGF<杵$sM ூ>UC]?=c䣨?=Sz^M-}w cI:?Igǭæ>OXөzޞdOX{!|[O=>S'U*sVUԚmaQ [&`/c1T}Ntc? L > J pPѓF=V ͞~Mu0_y|t{-P/<4@8j\xoq4zJ޺S$O!xo>*WgmD0Te-+g1+mkpG2揣t}>c7 ˨ui6yʙY養63JEK5ҧgu}Hqs ~K `ZRO 7I|s9n__Sz=_e~13F_d XW X33Gҿ&sa}6̕/0|bɓM0wEJf%JTp@d1 $<'A @fm &`.PAʆ@,@7& @@@tS` R"r(L  a0,x$q@$PI@6@Z1Jica,d, (l_V-8@&c6Ħ2Ҁ1 }Rynʲ2Ă.< @oA.dJ)wt  Bm69H-Cd2~02(a ؁L$@Ё@Drn.>@C ^,|(r~2ײC!h0B(at4f=OsiZ풽&o nh샕ty3WH\'g6Lp­lkZ~U]J[z vu- OwcZƑM#[<%T^\ZS"REJ*3i))v4FYk^8(ѫOd*Iӌ$Fjm1o\:1ܩd&S|I3WѢg$ΜYZFz0gtQ&ͨКg]@ĈtgV >PM5FSWV g B %mrJPdu24i7'RvfWdgh u4MG,q1ql`c PoM%pkNn\یrN&F\d͏n\%šnnJ˓uakKvCqbIǛM~O!Bq0IS)4괕s*S24 j2ESv8[fA֙ZIvLJ*wK[~-j~{Ig7-_O鞗zzE4rY]4wGt_4oi {';`>UFP$!`c)|D,<Qbh囒4D$jMH *>kPL]62v(#h0j НfL%B6<W(e@MHp\UvtiVGDq#52~u{Kt<2V Kƹ`.:|g_KIbQgXӐ`.sSE.-z+Kj;JԝzHv.Uꡉ(wCu733ѬEֱJH%P0SQ\:bgzb`iO{|?'~B ,a5y w5uGM^./ J7c\oOx ^_]FҼ|7:lqg. 7ʷI=?z-Ѿ$A& ~ EY.,U%+WǗ5Y\}7D}8슊!S4f&H-+iŒz-% ij+=ⓚci Gu,ڨ*֑k5W_E"o2IŢP2SQ5 {YhU.NtkbGys 3_3t}/~W tߨtéR<~MGї&-Lc355?DK@;iO(nC\x,{2zPhz:~pl#_yL<8'~[Mj'WzQK՝7+ܺy=[ϗ|WA_:C72.Zu)tuiSxmju/;5:<wKX;}wUgFֿMT=F>_] Dr*r4':~_Iiӹ65+Qo[~S`Zkt:5] U5n>JTp5]5cA ~< !˓_Ǩe(t*޳[j0] ا'xݣ5ˍ>Y֟;_NE6 ʲO5#=@$/ʷ"$z΍TiQ~azOjzںt˩ۜ!y:]iUFO{~ce9"[=wHZڱPbx# F!FXza׵jU>OW tx>/tiUxq2 WOJ/)lIpun֛RӂH0f;/?]r7+$:aa-2:1("ӲW/žUY)eYJ-8*Z=3+R}VMS9%x YTM#m'Ӱ!o;=3UNҷLƭh] %ٽZUAta'LnU hzyMJBv9Rӈ9J`Ou+"eKvNVX,()no{/M8\RJ͚nQ""˷W:peuԪ!N?:uj&t@7[i"8dW|?hB'Lu ;)K@_#G'jqk0\hG|Kty"wQwpjO#95Ili8J"# qf&Z _ [:GdFxZFf.+:bѠ5v#dºDd0rLɊi$(c (QP^d1RPmH5QU׎ΎD݃W,nG g{*g*}Wwq̶]l ]iQQ=-}%-m e4.OI5iһp;zl [etz7\$:gGZ@ x6z+>:M&ЦLaD&VynvaA@X >^OWӨh>O#< pv 82A h8UCچӮ晔P,͉J:s\)"55lf< ̸QݝQj@SךgcA[ n8^uDʨzU7USCx*iP'qK]oktO}mpoeыQ QZMVtOͥwhTS\%3i*ۨlcGN<8SQpqs84Aޒv[Ui-JX=9TݣΝһn}\W 򫃳.8X[$k%Lk ֕H\Ym}]ƥa^tƟ% 0nZ},YΥf7uy +FǽL}|jzh(tѿ-"~ SO>ch Ҵ}=FTv64:2{HԻ?O cۮYNҞdߚSOͼJ͉j*_c 8G?m> kɊK s/]ij0q|-9{y-?P[KײjR=^>6{>YwT6~އUj[KQٵp x-᜴s]-7zo7UC^'Y6O_lo+Sr?zcO1 w+ax:_(yn5c>Dz(O8QmWTV:F o<~OOSg_?GgGkR4ԍG7u7]5~w;-yG<.ps[Bjd9 O`_x8xXJSi-ng}2şOEW'`$YbX厄d LIRًXeg5jՍ-ka Qݍ|/RG{T0!|&t~Akf6D* _5MK{_+= .ӝ?Әrʽ~qO1}o/=i]8{|F_6~vԺʀUp2{p zǝ3;zNjP>Z3uȪFmLJ=㿧iZ5n9 ʞ[Iyg7_%?h 1egͽo}S:fu*bVON>]' $+HĹuI ˢUD6 &C 1$ &"*@X$*@TH@ `X#Ppn=@SJCċ2'(c`,H ALq@L@+wd(<@TnW̠ s!\͆< ]A&ǔ`b,sDŽ@ *L@}?tsdW" )&q@ˀb8@&F@AYC  @^d@qS@XPl"HA %:~ E $xEdDkTP3@@&fd^{ ~K@"J`L7D2&/p&}!X `~`ۈ`m)&p@Q$P(2`TX P< 'С{vLl L[I(N%2B @p6&aMPy.xC$@͡Q$ d$J1D#@S NbS'-A V ae6; ,LH*aِXB@˼] ؔX$t'c $TPTopjEt\NNcq(R,-9]NGpGEBR6NaqhCUٲ_#BVXt 7T\'175pRRwЬ 嵙HYAqAifϫCÕ&Ѿ :t^*Yc#وMQVc麖JA|&%F:o'3ğG]$%LԦi$,68e ~v\ N(0ܢOPXTrQ2LոoTuLh$Je:#Wɠc2%h&2VuI *e0밪b-{lHM))G @H5Rm \=8٥ vCj:φ;?ஏJڟLP*'Uӱ?vrMte8çspOmY-KӐC˪G=9uf-S,R\qٜG!ai𹧊Wѻ8ijAh2seэ8tQˑ cJij( J397* %Ku[WQԶs T9z릨Z,e΂\Cmaۈ֢X$9vIsaqk'dWeK2gD6I n ɯX,qGVa]i#>V^aι('N+YJ8r]*V )KsVPufqYl1ޕ^ C?.sG/ĢR4ˎ}CuF\Gq]j:-=iCqϤ4i(4۲ͧWKgy~KG/So@]>LJ+#,N έ',>I|>ŖcJn%9p*\DHTe$fU̸)m8.Rri:Tu>ge7Giq㼼\vfgTi{\2cǩ<̓нbVU#oB{Q#=GvVI YO'S]Rı.UR뫆5}p>o?V?gмzw޳0 n'g˦ԽC \~SWh?龦Riy/y_#Ȭᣳ=Q>-eZ1dO~Alކ{FKOTU 7ʔ ~˶_irÞSU/X6χEJ<|:d(bfn&VЂn2ok1=%,0I 4BͫR" 6`n>>:{M'^g%VMf^*Ze|Tm Fz׬ MJcGetлg&Fk n[G#!&NNkkcp$9M&(X&ϲcwveBMطbʌ$ L! xQ~4DžH TK HP"&0Z.' Xd$AAHX6I.‘srLd<$l@7C&OY0H21d]rOg.JR{̠ @L@@@@ fP@c' )N?Tc7H oPH%0 qt/sd /M3b T\ Id 3d;,͐"|BDY  tACc0,}09@LP%.(I3m6d PeV@@跶P%!R@`.o#3Uaψ !@@LE%Q8@@.dD9@I@v\ZB(|@D\ _  B(ȼp]2Rq.   u "^|  c LY! ( J *`{&ؔ4[GWCOsOx[Qx852KcP?c8鱬q]WNLRד |XLLonw򆵄6Phh wZ#m7&pi $_*˄p-0+iS8 ̦Xi a,uR8_GKTqfQ!tNQ>:-M"YM -6Rg,i5ZIVn rc 4 KlR|eF%'4F],fum5M; .icqg C#qewkrmVv\=ܦ%Q{bQդ`TrmU8:f᭨HVfAje8bj u5{q.m$6§So Y(pK\B9'>jaS/˘T^8X~J[MG$'cUBZU SzvY5ؖ$;FR!ՋW=%GAcV eFs^` ǟbs{zc @bO ~:c:EzoR{Dl$8$6R|M!^ҪZ|k"*sgɅs^M.IWO)s.SpW>LuV4=2nk#kto_9Ut!-p0A.y_iP(S 壒%fkl^ 8NqTPLG-O 6J8r>#)1+||;ө+ZMp5w-量9hi5O`-YۧҲ- q0}னbܜszHKc:oް4_>W~gUcˋ ڹ8~AE3U~=Z40nO=Nӣ,i m]0_U\ j*8;K!ҋK~V/W9_zo(I ɁMD~?˙H>U4ߑ#hj/u#OQD!yv82GtyG@t/T.GG /ɎϜϊk4SdZ\\PI͒ `ʙat͔z٥n'\PS ׉4K L؅Տ54ut+H`.;!x>0,t,Ҁq j#Y8MHZ# A X;𳫥s^sN[ s\ZF_K$v%r}SҚutqأ.I9Fn'4U+9Dq)+OSoo'7t,TG:Q9Hle *;j kZWnɓ(ѢdΎe,#D )vicGFM;: ZEG=S)KQ麬r}1Qt|Y],|^e 6u%qw04o1)(,_CAmET&fw9m8U(K ^%⒟m?WI1y1iIѡpq,䞎PsJYJ)kA%CzzmSYA:E+X9 ?%S0;G$rOo6qx_^(Z7ςpKrlGW͂Ĺ9zĹ=N] ]\đ KuZ֗NttFG z8)ǓRi,LqǷM\;L=_к}C]؂]봞vPO*DYgp3TX^B֍5X?QXӫ]SC:QzspW_sR~IN}&kg]BiR?RN\ƻU&-|=zjYt3Ƥ-.i㢈,5BYU݇Pwc  #x K3GTsk56ߺ ?[53~?PW7Ku:oRh F֗g_)nX]x 3%[ֵ>6ħlx|Osz͊>xZəzqmj k:nլH.%~9vGhQmjM'r -3] _##i*.]FR_5|n_a ]B8n[&͗z:z9 ܧ |o3XO"Ѣ=ױ:ROog$9R7U^.ۦN# tbZ(mݩjbKC-UrOYU;'F')˒K<O7Iz_kEQyܥ̴~]=|~_A]&vyq95~?-EoJҐU'!ir#~?_8!ZSZIKO>uQ~-hQK9F$*7̏S⒫F+QVжwK๑qyOiN<> ڳѽi׼k01 ϧyǬjf5+4pJwTyqn:MkkepJyd G_R.O9QkgvZE8)k/?66j.`/>>x[M"9]_Lp e>θNWO)6 dy]*lYrI7e&$66 h~ Ш['E. $Uѥ xWLuIѤ24bQu6QRtc\J^ҥ٤ цL-#Ms*7~t!T==6uMZanț}4g<-}ۈ N2#t~,sZj_y3/Gu z5ĀOʞ ct445T䀺7D:<_j!>A).Oڮ]ڪ w&IiE߁>A UVjBXʰ#QdvzgzUi7U˛2o x:S=F枥`ڵJx'xLYw_i#P⏛ϡ>Q/YZũdOZ3eV4V{=}ɦvֽEߐy$\'3ȸ>G\O [Uv[$+.(V=t25ֱ 3JV'C(b 5˷aeYMI p@eŗ 7DX0-Hk+Eس !e-M'RAewm勄զypj/d>^o|o<~Y9MuW홧(Ҧ"xe ;e/׍`#>e%R@ӣN).8 t׉5Lpp!v,Ze)5c,% X$8C@! *L,m m`{(1^Rn>[:GieJ{[`;y_5䲴 KZ0u Cro;?%2:093` Rmtn{sb[Jb;)(ϑS! qv+!uYaa6ASvhL %{Eۃvb 0m &d2<@%&QV C* (@GĠ $ @d VPOv@@@g=P&x@̐3ts6!(`.~, r*;HȰ@͐2!( tLs>F#H 7ϺwZ< . F9B$D~ɡ&@r PŐ6t EEAw@ĈMdʲH&""µ"P@o(SbSP% mrBl9@YbFSma$0l%e-3@v 6Y( eD @ҁ~mB iALf<ۺb,F"%gA) Y( !M P.&  !ywC &>B!'$HKx A@A&Z` D6AHb>H 2eb4| 8;&-"NKR5^d`s]3ͣ ]Sg(FC]c%hin+56ŧ[ӹI&7q\Kŵ>5*)FQ裾Ћa%"?2#*s+n35K)qd[)l:9&g_ lнmRs\2gQ7j錚7C<6A[o7 kp" Dj sFĭ5\]HR(!ɔK*p &q0D؉ˠA/ćKӀ~zqi܇QnU$tޘʺjoN \Nҳs1ꌕ{֑첞qf7BS;jH 8e!M7JfnZI_cNs@c7+XѼRᚚ!m:,ZVAZ'4q{r#SF+eKZ jԞ\Ջm3ɍfjj\Gt]5V'0j;ne }y|Dj45'7|@!fثNO`9Jhk^$L5pN]%wgBԧA E}2%-f $ |(CK_C@])FMR@ug'&G&˱jISLQ(iTuNG9/hH02]2:uѹ2M+lGj1Q I=d5Pk(%`Vd|1BqC>VdK']Wd*`- V=6k1mZ,Ʃ=[G~V_@p.ɫ TQ| *kMzZ6i;pMדnS,?' 8n.R>/Usm$d8<hkUtN+^6NyO˝y^7;I^Or5'yͤaml枙(z&+i=v`ax9LOpK؊"f6]=M0[$F4љt J&Mŗ~36X3~ j3D=+h Ȕ(TH / źiRF/L}&mэ#hݤЯ}:;G SR\7gtc#O%tj\t|I^@BGeAUUZs`ӡF4rw揲uuAtu:a QgzZ[hUkmQ U" ´U*Uh#RjB΂pQd+Cݞ{_-.pR8uZ <5Z:iԣoR$ Vq{<-FR^2\9qu )x-htg:M_'hUg wx㓣߆̈tNKQ7k!T]'cPն YxY O؅JzbL}9 sI6=~4N2IM7qk<-%iZ=P,O_ kJ댑iΓ^R^T˛Ojf=Gpo}mSc)Ʌd+Gf1ɹ.Q:}C WDre -Ciָ+.9 yPzbNKCBҩ{OwA)>}ս5ЇU Jmɋ>˞xSt34gj27 $ƾ bWD&4حh,gs5@2XZʹHp+fhDЙ)͂2W 3 F"FdM|52IX p\TCQbNAedERMrCT!y|ߐHi jՁ_%O5/j9:ʛ%ypv3$- X w&& @n{0+q  Enn8NP $Ys@.ad$B({ D@Y;h@8$bgIx)R DŐnE@Vl8] o1 ۘ&8c(y$a0Qa`,RxXpb>1)XIx8Lei0 Z.80E7@}! @1"0 cjLbq^-t #  iE# ±{<{ -Asl h *!!$`VyrZK6t 0G)C b/0((Q~E2Y0!H !$qd1!pȵ"$X@G3 F%`h hD=d.cc(@Gs(|ȵAIY򥚤 xC5Hv}K%ta4tX6A 4>1Hӆaָpe:W#jcSx™E3IF23Ԧ_jXyC)gX>,L vŷvS(# S)s,T8Х*?A h˦[E9+M!(y`  ӣlrpWhu«)fIG8Ml%%|]b fojU5bj+M+YV`HKkܘ_evvL."xbПGsL-[ITDwBM0nhrݤ#ma O~ !Tbơ%/dr7U<-m{6\|Hpkh+Hѷ*C }ws~1E6g;xc=D9hD8WoDe=)܇il?4R\N_#vֺ\jt$VNS-6V\qܗ%G6VLwN)Km cĸc$u8[,_LgEP:]T8x)M>XN$VGe#JԨCT<),N0M:n訂 'd[P:_M0De2q}bA fMm]_tڍ+WQ׋>9/5j]R㔋x>CJZߚJKAaڹ#H1Xd—h5"ۥ t6(k#CEG3p⃵qqK26^Y?)Q^,Jx4P1vz]'Qk6+12. R`;[[B ؈skj09q+9f[ ;>Aji`Yj5X'1ã< -ku;f&F%e< Kycg?4FqhY6'3⿋]T4U4q\0˻G{9>'Mr|Dhݨ\rW;ѼK_ju0Epx+ˊO<[u6yNI4۠#FLh) qb/\R׆x fC6t-ik:m>OOGGo  6s68঑Ts O54V^tΎ}+F:';^j@#.c5xS `чWmv[cpcӨ6*YZmT1t`%OWT;K]D (tEfϣt=RvNWZv6v>aO+,O>ϙzP6l#}iQXt|UUi# L1tzZrd9 RE&U\::tq\d,CΪQ=wHk5cḘa~1v U>Q p!RB==te B5ǩn ;$8\`Ŀ*35t(Ө6urqIMZ6( am $9 S,NM79>BI4Dz݇-vS@&)\Ypՙ28\2F2!fYAlV\B3]P"B&Ջ!`-pP͖2F9c괉kyvɡ흶NI>WY5~=<gTڄF ⃴~srf"",/iHl:t@ 1PI1!ٟDc0 ؉kH4yb,H98iR`XE ""AdX&d:(L((I3|).HZI&:"I@07He 'H<v@LeAD T31(XZ.L^2 >P4! D @d@1d B]< 򀲬m9He@)/2!d$ &;] $G "^P =lj?-@BAc'3t"A@\_(\X!@fFB,s{ eb1b2{t?t Sp;@| :ɡ01B'$@LJPvq ,fI (ϔPQ eL tZ4~yAE}&n wo e@MJ@h(0Y  L D \ 20P 0 1I@ (^~dOe'b8q x@6,@1t !e H2|)5#Z]6O ]3hޯ*ѡ@EauG]$tcheǕ;cDkɮ7LЮY]pG.íմُ"g&FeFШtڂ}'4AHjh\N^8]=K?cecԼ(M7*\N5HHҹgقӸHVHOL]Lsi<Ty/{0lQCvܪ-e#sL&\KejEP4R@pZf Iv;<.H탾b΅N_Nt)OQ,|ŎhP]Zٴ3* n~'7t4^g ˃5JoiYFQḍ͕_dmZ- :T8Jiy\k鋏4klgTqFJG(xٓt%j0 X쿀ڃ&?EdM* H9G?G,?lj{7.rkkR,'քI9ƿ3Oӫ Z|@dOzLI G;C٣m˄u ?\OϴD+E?UpRt Z)HQu~W$2z,o}YOhR@;KRcLk&:ZKI(qeN }ji*R]ARnvZGKP({`Kdԟ/,p)8R']4K q$M0`8ɧ_<Io&8+h1Am.M{I^TWG\5 }Uj {yhʭF|Y.KZ鸮NQ -|}OG,iJ_ kh:UZLjƣ{%?EѤҹj^SӓZ(u9<Ar|@C+R7dNu6O{HZ|3;9>J5liϺ6d'W1X;zeJ;פZe\mǣ&k_ 4?M3DA*ޞJI9Mpd}?k ]^d7nOHn[P+⩞cNa,q5l X*gf5m <Ѕm8ʤ>,`/mY h f)Xm-UbxӦ@+ WL|j$Z4j:L/QVUhaSGԆin 5Qt.MH x Le4}^Um=I;LCKy\Zk'4{.THz-fٕGCOMM9m:t$rm *msۀrt|V[c_g;&S%Lxy6Xҳ'ʹjM#cu2p7К DΣ-sH#ǕHqKMcA2;e;]@so͆x5.N9GgӸKFS :y]0Ł4oEh5~إ,W¶Qе=&eFLŏtv}NQ Tn=-+EfCiWN9QaS-Tt.$YVu7uM:akݒp;XNXmbL{_#+ǕIrQNь)r)^|@@mǡAm;]˲97BSrhQpܑi?BNV,ŒRCiɁd )e#1ָ>anߢa/dt>Ç2 ,\&?dX,ddQ`F=C "DȰ+)i 0C.-XH,_ A!L[( eD nEe` ,>2&'+skR*acEx]tؔZGK ;IrZeQ+X:Tj!tTt\3mcA%tG-,PpZ\s YhNcF曡B:5)ۛR &E@:*D$♜'`T:~Kzfy4ZMdPHk=/NL9 &Ld hThL2] Tktit]}-EG#ֱӏ4M+uvF\41XSQ5'F *McX߸ ̿JGKJqf`YH<#N{#6U0ߺINL|Lx6ICoiI SOk46' u,'b#.aEp|Zqf% 93'J?%b%M; W42ɦjS~Ƈ8tڂ)V0 *uKLI\RJ.| [d_jSs$' U%\rO KijF|1Jٴ7/GD% "ۡcrx\Kl\WOUF#~:S6G+?0V˓&x(zf<='JC*aptFWYN46~PR`[ HJOI]SNOH0Tl5Um$7Ϥ,>`&K~l:Z]CA;m9)KV.. ҽKtN5SP6Nq $>spV]F=<7tEOU2M&.6e^Gy?#]csPhuߗqtL>zMق@\ϗ/z+>~m -Ϊn19vcuyί(*$.âIUp{:OsJiIppGuM5):lhl9=}_ǥc}NLqp8 SGkLv4=PM#M5є{=Utp䗸vyPuf=w]{>?Igε{-ESк#й*< ~W:{KhY4qh5+>s1GWEC rpexmt5]#)>FCe4K,7x)D[d/Ӥk/kKiN>="E#FfTVZ2QY!RamI4tcm;!6lb>[$t815JN">cY#ɱۅ׋Kr.)ɎXf^::^O}k;K= E*čGuwD'nt^֖;^V3r6WgkcKM8.\՞fNKu)Z_0G=HԎIy(d6s pQuʩtzzgmVEg麗18\ϏsimthjNC_G*o.nr5# +e {kʱ6WiOR1g[Gku4rd'oGPM3%fSHTੜABi[i+FeWfP&XUZ{Y:AUicQShT"=e/Z#tڀ/o.LgJRlgFAFN'ZYn<5tzwijPX[@$_@Y{𘋎H "+{J@P6r.ADЈx'(H$; tp$+,IAaL(Є20'$dPe r/2 v= E_$ 7 %bl2 P @=)L  ̠, .H@-hP3dNPtprG@Lte|[ b$p-)| LB] e @#@X&f> eф;@&"&HB3tČxƲav(R .'q &BM"KHtEP,  Iqkٺ:.7yZ)в̭i>{ĭ#;gN,u".DgGt38t3 p M澲\tp3CBTtbIk7!vFn,qʎmȎF.k3dFzmu">l/ڔՋMRRʳeI%]-83VUeu f3MK4Iw6sd #XZV i9͂8\lkÀ$+)1?#xW\qQ|i32L]i42N)RiXclk Eot3o -3ZinޙѸ= xҏc6%J;`Ƕ]U|3eRHJCe=)1ɧ_(Z M8d(SLM,ܐMfk%EA)oVnGs6pGuKi_q JbL}rLo8p6啈q関1R4CZe]6]PI?w%WIuy~KOPHKvwlOWW qa[akAM'KͭbN{Hw[-BDi\#Fރ낀hUGnd$?TJ[_z;F7{lZGg :):Mŭ a\.uWiCcuc{e$qe:-;G鿅Z?UEpۘ XOO<i`zޝKtWڕ GH>`KeJڟ5>t)u/GtWi(8`圵9MZo% PQƒpHɚe|c~2jh́q%,x܏sXIY5޺'P$Uc\ He'`L 8ßzl?UY @ezǏڎZ|xAP}Hvp\ſ (f"u3Gj:NgNiKÝ 6?ɓ#Nvy$T}K:z3x\"YDm2{M|DIzZˡmYg̺RZkM0!t>CwsM4j6{QFQse%LmE62 B 4ϛz {ߪ?uه.zssҖ<̨.>b|JcV햷+KҍکzxؿXQs[fYL^hK͹_LUGۧF\k:cVKqF3y:'hx cciHZFZ_Kc1Lߦh"˻;ĭY0xhx h-nͻޖ[."}luQɧjX 9eerNN6>ޏ'6GVuNm"nFSOdٸW9\iKp,>ձcD(AĎnˌ*)qˉc!$Zg?Ycy;qM=%5GP`eSFlK=DGƼ7c'4gjm YcozmM: H#5>}NPUKjk:*l,2N$_x`{rcTߨ.ZS< M 3 w T{w<3]wWUttE.yԷژk%fL0OԲ! rLbJrYlA:OnZZpW׸.Q_4}SE^ *rEFY4.X4Y47.bq$8/rdzFpm^Nh AMz)1!t^P͒"b䂹2Ӌ!jA-܆&|.|3\P’[#]&45Tdh V` HA36JaJvZe;^L/(JEL7*>sbޙqMP7],y{y8:#Ee~kw9Zlf@L͢Y"%P x%emeYdeay@'`0(.옋& P"w(ə@q!Q!L`7'q3&U 2 >RQN $0O;$4 %@@7@0/l @n&-?dr$dQn.d/@TPdy?d$HPP00.2n,/0"d@}ů@c3* d2b0JHwL; ieE C#h {p P"Bb.,AŐ2-LAEt"S!&.6\ D0.g'(p!0t^ 0,Aq3k:,8@Qc,@ %01sQs6ĒLq#η]L p9@ YK @>Bc  &y@p (߄>fyB&HbI?H1rI3cDH  \;kD9DSyY?,UkotmGY<\W6X\ mw)N<0Ȓ.QmsOd,[\_lKFfȌ idrREFo1s xθK AddˌK+m̕ΨKTؒaZ:ɡ$) A90ReJ"঑#B4Wf}*Q9W4]={/MXXQhcv#ܥCٲvҵI3xcY^n=G,(s_26On#ort,c(xjd+)ʪCTjlt5_9ßFT./3~FZ A,WLh!e͗ M+Pdxb;\ #.YmcX|. =XHS5Qi[ S fZmvk]iZϧt>Ѫpđog+zlmp=&9tө niX<]8 K'zv"ZHT؈(Xe4ha,RH&{BMvZ#5oNC)S]f[enqރպejsXcG"r?oWƙ'+W=6/y*x"gb:S9.Q7(YuCtmӦlDyMŇ]+8^~Am'y?R.j9dn=L~#m=]C)hn^2dW^]) GT8/:)'_7?=SAUYnG>FcQf,#>M(gc rRr1^pai{ھXwi^Xi 䄖ȫ"qEK>4_Z~-W\^NU{|7POOm ɞޑz_S%HϓuU/ |_Y\hٖ^.y6Q ^WCR(,\p' ыEik8ExZf܌c/DOC57\3\p*v:ln}'4"ʼ:n%?ZƀHuqdzyM^5<.ϻt*Tt[TDY99m= /2GP<ܲOh?]KgVF˂ "e6ـΈMHR䑥tR@1SFd1zik.hi7P9熘\m.1Qqō?DZHw㵫UG!c3L}*Ϥդi|dELm)c֎hNgOi^[_#=6ǔ{j}E58NQ:ncҵxngK4>a-n\07r,gg(s8n&[>B+1Ö yh6VnîptʣK^!{X2*p4JK1ԦA4/ 6kFT)sqiJ.c.̴$umP.i9! b*HSE&0:T˲ePE40yJ39rstC\Ӎfyp%͐|/;>Gk*i143|BGO1භ(r Qy{e*g5+drn>ɐ22 #e(M$ 2,41HAGɁ &nS9_3);x@d ED(9̠@ɒ`&4 #C0oxH@@LoҰċ0) Dd X1`@2Ar $@,%@tq'@1B'` b @a~TP90 Dw>%Q#bH"Ҁ!$H &p; x nt 2Scd (6LDvp1fg2D E猠 >s& Sb$; O\rhca7 藦-Vb^8ƹۘ#%bPRvml2. ) 1RCfFz0Ψf57"θ'fUj pѩdMF}jW.9[9Gh吷Y M;BᫍmjHM2I )ah 1DqѪ|C3;h D*$5@Ur)H(~`4cL6VɺE,JAJ7TsI+:Yd9fڮo= >|Y7T@o%D67}wCzV IPǻaӼҳzTeFFj}oG.$/UzducUXIj)pzOvH+4Qgk%p>ϔqrEZu ip"l\Mqs:k- W'V3)BMO&& elC%#_Oс 6MLKuVlm=.ulS}m-/Ln[a-R3tKU' ڞ[ISwӼ|!pdKF0i~卨ɤxM;DzF-96I_I&aNCJ];f$mč$n=æSL2 1W:=GuJ`e{Y ]kNZ ʴܣL叛<_Pi휕K,o!Gl=+~l/?K.}#Enx+Y>˛ӕ1DfTQʤhdA QIQ"Qs5t .M&v㒑sOdM}+ Tq%‡SiD\3M*C$mieHR iYK㴦ÝALr7v,աԦ 7.8g|ׂ!x~6&ZT5fRNݥRVqf›z"IV4<.gS@\\]q6P [CD#贋+3:[bf|5Cۺ&񒒣S7ܱhj)6*xpZC6ll*c-v>έ>XóuNTWӓR7W횦{mrOp^\c ,[!L  6e)y4Lm:Mx1ݚQ^=Lr*cHe5hfZHx9Й. :еRe8HDp4PtrX'CZ hȴHM:,% 2Z&HA54ƂZ&We2S7Bॳ7!n{2&MN<YLpP頂aqenItsԞ+ -*ޑ ru'{ +5GfqGEA(ell-͆BϺ,ڋGc͍.)"Yr!1)wlɁ!/(DpHqR1$@ L(mnlNZ D`%PFP !@_A>(Z~l.N p &< nP}+,c@ʂ@Qn_;p~7SN_ݜ-g}Mu\|KٰQ=~7I5 q_F_U/T.'W3˨b[1_UDK~9viPuuNRyɐ~3]]R1o|7}PAp+UMЧxlq#-N]ZxYޝ?jH ^~EڗdmX/ 4l;4>/&Z\Y[40qr+9que'ٔJeT"T!`v.'ZzAưǀ$[KȦ7u }zNDsb^o-A>O=?Fqh^>L#'k7gUQOlǣFx/R'jZL4qaq>vtyQuzt!8f?szh)9=/EV#ҕ#]VXTy貍&~V2>{;rme6^Ϙ; KT)bNk}]T3GN*]GdžUm_iٔK{̡-\Ǐ>s*zT1Y?cc=aX%L'J5~CZF^]N0uϫƲY+5?FN9ps-aiM`g//K0=yt>Q:OUBv!|3Ά[*$4Xϓ WG,sKƵU&|ֻ nZU`0npt"4L"97%jb*Fs+E\$Lԃe'SHarGRzulX\Y;fw4@`E%`>\ Msku'LO9gtυ cqvX* a_:5\qH+ƠT0F|M{XIeS:N͖Q{xfyck-(IeqItNQ*a#UܮkX>z M1bsTLRqX{45:i-r[}n8A3qeQv̙qg\iԗQqiZ0-BRg@jgʬs\$v+M4ӦAZqJRϟz7E[PTOeJ\5>E]AQk{*$ЮVi3hcMT%h#RCB.iAi)T^P]J`OQMZ1֥e_hHծ9LNlM -,膈 %t$0ZFEB%S4,d䅐d2RBRH eUSrDܕ C+#.N ;gxMpbwZtXx[t~u< \gKӈ)G'ru72Pq"Pd[qA4HI@rA@?mX>"`,H,;p@@\ T = L a1=@9LD?Oi<@#.=k A@ @L@W$J&($L @ aY/\!hh ,P ""q^>d@t<@L'H > @@}IA`FFy@"'H l(`_sp" 6c)VLDl(y7LD`A{x@,d1pȱ@J@^DD@L (}8 yBPq QF0NrDtTd c~1XYi<+K.*A}6MR48˿C &@VMQ) ufq)1ʊc*h!c \_J -q cMB,pN-apA9r隩+@" fu.JNK~(֧ӏ./<\4V+̴F>XdCc`F8tk\8.35xaBez;瞅w|ŸK`SEU[ 94QI۠aY8dE^n xjs5I[O&tG?$.i-[7Ӧ>gNl%nN%\3b#Su;v\ ?tfbFϟ=R>6o𹡬1k,WS͛V9zW"Id+=f*Uq8'gM!pR"]3pJ}w+}ĮwKHEԐyVYx{Eh,H0f 쟩f^[n9Ůnŗn)jӥM3߸[Bf rݍXvI[$Q&7TNk肔J_L}VOU%BegڥC/HB5Kex +*T e$cQCR dEH*\t*8əNLe- n軓.*4s\Srq>Ai[QPp^n|<.kI'GӴ=>4S'.ϨɩugwO¨`.J>Oo9Uk=d:w܈9 &3MD5u]v]qCؖL>YZ>5$ yٸãĮX#+ܳgyHvRں7y6{^ؤ D lG]ii Gs>yԜI5g`4zvȋ#~)/q8LS;Th909YJE:Ū+<(#tQ7VQͩlѪ!','.=Cg/UљS, /dOCpԜeԄ w7bItzi[O9^M^٢K1deQ݈ou Q)27yL}9Eix[NP\:]Yj5-",q.Vm|m=~md糹GHK Vyyrg3t_*Q٧Z>:PFb#W<Ui:D9 W90wș6*¦濌vt!pa$=->H.;)闓dutLUݜy4oVP 3a"wWe3hi^Fm^Jٶ>=>efjS7 pzQxi:.uKO^ XU^\MmM:4>Lm;/&r6[ƜNR:E{gqFEJjQV{$W4ổ,gJ9Z-USpWvM1V39!(rg{9pdcyocDzz Ts-/\uNKHt{w51eח?Q0Oz8493mחm.NaW'=?L BjC%uY)9Yx_O|8d^-(z#$XSQч4NZhmL/kS~'#ao:tzr- N,N2ׇQ\3DPkkٶ}!L_OqmS=U~:`5m`,OnCǥug2*fm u.Kr_{Zw_q^.GXnDpPћ) IГ ]Su$g$-ffp)*E).L}4sHCfE r] Nn%!V&lJG+[~UhzDs]BmGkfJ-_qn+:-$v\p $p͎-w )})1#($&%Ty-$" aD@DQ@/'0H7=B(O)10x3!1cBIh@ \qk (@H? (4O @x b7>" d HE$]\@@A< DEG3% ca",@6&pto,,ߪ ~X | f) p63\bאn1,NS0,N؉! X'_ pP e$ۺ_a |&˾S$I1!1&.H(n="Q&(*6LD(ٜTX1> 1%DH( y@i2.l| d@ @pG&Adϱ~D_@1~AbgbR@0c@@ 0P2yE `"9E[Ǿ @ }P H@ q$}"6H_"% {c"` R!(N{eD{^,# :&U;:H9/ۍ#?XF'cy][~[ӷthIƒҌQb#s\D)23CM# lrfn Zohp"]ԫYSchԟ'85Za̐ashnP5(Mq?+X?|qw|ubF .LIQIB}|-vrӄ]]mIbO-GpfOK$&QHoe]$:2ߙ N,U?^g1RJ:%G.H6 e=FhRue,>CMV|#G>͜mF7ղJ{_ aE0`4W?Z)VS8@QHԤL)]cM*e u&ǍrpR?te*;HYhC |Eoô27(#w1U(OjWlӸ 1fI> xS㑂MP,r,KdJ ʍN,2*oUhd`F.fnǢ#X e3.mKs&RJ&6MʮK=L[c8E QQ4t% siC¸룋˃O,n9?85 y9wvom!j mbf%Tu:ZknI0+ >^dqdϧ~j+C]KQ#'y? 34>浠\K+?=lֿZ>I]+Ja7]x􎷾^̙_5H꺦SPC$RPHO8 pzΧG}9 rewf]42t1TmzgۤK:۵(G3ԙ[KJh'vGkIMtzl-)[M3{x:_ 6VM2/ |S =3MԩTh. 4طD4v>seM_$eZOY2 Δ5]8_+Umj-sMR2rcXwUݷXR~6ez|h֙UI`:YfZg hKA%6".P:зǐiDeMXY= T.M##S"Ú&EύMZ탕fܬn\c)RdRCA5ʓ)0B%D pX4f@BM 2HT;!%F28!΃2fTԆSIcVDܮ$q2&QsH+ճTh^WjEogԐ^AGJ@td^FnO (8@%A 0,](dL W9YX $0O @$D&-ݥeGPK2EC(& Q!a@Kn,;h&O@AD\ *<LeeH%.i&9 s$D E'iP1( \p!6H(\JSLrPI7. h(B(d/ RAwq\@@\ e<X$@ !(oQ3@ql ?c# ( E|"T'/2,x DH@(E! 6M;n #)(G=Um PO -;(w~ .y E3t H0_([ ,{}Ck@6(osdD8 B/1bĆ)B(D 66@ cCm|MC&TG- Ol*rG~Ϟ0OMҚAW~⡍@iC-kBRhc]H?.Odf5)l)a4OͅOFK 7;dUmf][Xd=88aMUtFݮƲfF͒?UL}e4ZE)Ԧ9FPt|rq"ST0pPF3XđOTZ%a,10LWբmqr Lɤ ]IKD$ha.ʋhXڂ| }?5`HCx~Y>WN9sT`3z;59iTi StX0fύA4<9-V; *[];>SSwSd}"m!(^Wo ʭ"7Ut :>(ʮ&$ ,}Y 9v37x'9I_%5U(E(_LuM]=.}W1]tR|$FmL4y2:H 4]*5}AKǷeVGolP6 _A~wAY8V|t'Ȧ\C`gˇɀ\*#t5]Q\aDӱ4[*auimvf SxГ5&ѥ.ͥxY12h ($9bW\%fe\$(sIPNW#ficÂܨrFJ>=£; Μ(,蒉 !"YXLA9VVB-e$g$$dY\طwLFzCǐ~Vfɴj5{&oim2JgQ<׮i#-k_~7$̕ 2?bD௛ˑMuK+tq.Ȟl*0g @t(d@Z%\] \<QtmlCct!bɈ>G)_l&yIb| D d @#@c _heO eT2="`$EȜ] p@$0*gTl &( ^La%ɀC'&`, A &0,L$6 a_S|CI r3tM6.!  V?d}c/qtk =A@&ֲed( &m!"`.yJĺc$m"B@qH,"ZḻPpg7 &AL *98!4nFSgvQޝn=^)le{_B*{șʶrh2FVbF1Ϣ $97ybMbDͣX iY6nTaϕDzi48CdL]QJ3>!~S즄_ Җ5`Ac}+w UvG0~. NNe.?FSƛ1fTYT2mtq=?lǗR5W47{'aq~9Defosxr,3kj]8[DAO} Egg.5b F?N/mR 8Oٲګ:0k@TBCFm\{iO6v]" YT+i{lpl[Qf(Ն4|*bB_K>E7UN׵;*_,R'a)wrO^Cσ6\S69Pp~ꤺs Gk-;R) m4,IA 3f kO `IC]ᨦw0G2Hk$9]Lsܩ|5L 5kFy5-ݑȻ{­Lq1mIĪ6Zq>W%t-?!ҧuCg[a.. iN34'.YǶv>z5MuŢ~hqs3 .Բ#zS'|NiNY1iCx~K6;pϦ}=.7Ҡs+.&eGy/5^S؟/\Aݧ"nJ=N r/Qp|z~V5đL>WlsAF~NCbI\yfg{tҊaY-)|X⢍:5΀.nX+J iku,K,\;Fyȹ>4q^>S|E+/qƼEoqcel\ޥ? `]Sq n9[,;#8sLy'|3\jtΟV ?QQkkidJ_<7<ڕS$\Ezr|b)$$5'`=3>* !|  46AM2md,9)\#o0p3KeUff M+7pm"ѕΟ:|Z]AvzMռqXHa_q=\G%z9pi[hev}6u1 a8N./Q7]ڔ$pqf UZHOu ]F],#$`Z9oem "8kkuY#f9"=<=SM3gL;+4Rɚ8=K!ZQ giÛpr!=.~ M՗컠Hz/T5Q183H9\L2vPHq.]v|Cڽu9UJWe{^.Ln"h5B TCA^9)!s 7i\EUFO_Xm^U{˨n4>'Y֛?:NY<_W&ERg?-MT$sH.( @?H$3@2I2dD b| ]0,#ͯ>PϺ@b.RA3xBcL ?D[9G? P*,$"!I`Q7@i@GoTĞ2pnp; t̏$ E@vIˤA7@ `\dMtRy?dl6Đ0rPIհi#`OI  4 cQ$A?e$m!Ye$!m&4X~)a꘬`Gt m$*@ 3tdƋ= `Rt!@2P s0 @m\o ߧ%| (A@|ym K7< q6LFs^~(Nl9L> X`-wBjK~V(ϗv 0?E8I?& ǹasS)DuZC-%I Ԃ|G K|:ESJơ mC pm46#etCűsIeFJ74 jҥ2d.(Tg<)x(q%bKowΰ8PJ G&ޞL2aqMe墓GT%(EaQSgbȦ *Rn&PS^3Nɭ/uC Zn|Liu"2~Y3JsOgн G;E̐%_E=3e& Yɺqu!zf'j':qR&9mlu-w% wI^j5"xvX j\pJ"K9Wf|ƪj΅F x+2G6ƿfiWkIwZ29$,* }!Û!&/ 5Sv,II{J]8a' KGD}Usv{dnm6*6FujKˀ>EIrk&􀋪IE-Es/{2]PCI 6;-֋$BX\_Y,*Y.~~:^tNkZ7Myn 4Ohm#.KԤ-7^}@ںfP!sc m#J;/ +\0v%?y|Kv<_Fk;T]C6ñgrx ~x'_v7K:EM>L<#!WHW+ֶ6!y3dg޷jrgoG A#r);gKr_k52@1'G^Ҩ'By P,VgUk&gQ&SR̙{ZORŏOH*Ȑ#o)ZMZqy#9ɾ z:m^Ϗq$\T@ Y446W,}U&TŒ:~SU~KTE9mvrkq&]d(^im|y, iNХ/?v'Oz߫M/K; t]Vf"揠FӍjjէo~? oz^ pk͹tyz?rNnI$,4lz0Z!k:l3OHQs䑂'6[T놴Y-t8Iߐ1 OO~l:0G+9G5V;`]d7Vf{EԵ@B/Rj)h(K#w'GOK%QgEL*JغYq#NJuSNޖu1u QHNd'FVdkÌ XJ Ma10i籞[ipџHʂ05f"OCkCK6Pm@n is(4_tE=]>z#-VG{85*  ?ׄ7*gKX9Ȗ?>v͙Xy҃1kt;@ ٦>O?|)$]n49ƒ\`R*7t5`Z)ɉT;Zh}ӳ.(]?^ږޢ\^|;M3i"vs^%X=Cn]X:=UE-SLaӟ Ԋ'cɉIv;Uk)9Jprte#5#QC07sztTG+OIT7G*DϪpw+ =- z"bіKW>3h bCSupfܩWQd0Tice#6FA Or,MF͌搸e1(QbLNʲH6}"$$Bh̒U^ Hd#S.65|Z7qr%Pf}IA 5dGKJm8ɂ1s(lrp@B[!' `aB``E[ ň@p'y@"n. d8@w(\1&Q-QpG&H @Qo#1t"|$>BfGr  Қ@lbɌ0b@ w%L U?DVaI>BV1V od,D@dw@< b,Q}@ >ҁrP7@dMg" H1tH&DeI?tB.sg@3&1{@t ۔Av d(yHe$s͹߲'2"t @&"BI$D atS{$J AA'0L x"$*;kG{@P[C(d cN\$?A,6huq L $O)Y=pI"P..fɦ'"|viTf|k6$H5o3`9UZdY61p*Z `c`/(!,&&H%*vtme3 8i@O04o@@)., A$jv%^ؕ藵/Њp>K/QkD̉!M?MٿNݴ+h˃ b~f~E$_;7\J#kpARySdZj$6&OYUV-n&>I;iZ,fҵf2vTW:av "-@aҹZY0xdiST.YN>ZbB=E]<@bmV$G>Sr,$FrkQ: # [_'th̥PMԶx)ꄡTӼ E,R賤N!FQp$ʖ2ӨЖtnRFGU4‰i2禆NhSzKwRtֆ_+B &*O֏*?NӦhqCo-i/+)cmLbU8Dt]1VQдtf&;rAwIeA`ZG!A-5 =OKA-ir>Lql=FZ7tcѶޞh$]p9.qni/\x6fduE+]#;պ*'WDt1#.Y*s]y3Z%Q>F[͋9Qlbcoҽ;moSAV(Cm:?YXo /BOU|[?cWK'Y7ƢA;YJ;~J???w%1y $W34oi}8>aZ6XzRy dSov*2SM;jdq?EٓWnIxm%r&JM=Nh'SJ閗O.o=I;{:B 'W >#-IZx (0_ ר]Q.qI]U[ԫMӾWa y=eɏ7tzYޥ*c`\,룷ӊ> ~QPxpU5}7PUky+Qè9)#ޱltw?EяF϶;ߩ|zuWKA[ˮ/f.m V<*sɸq7XK&繝Qq.&˙IRְQ24Ц*F6|hDU~zi{俪᷃Z4/sPİ[c%q_d_tÛRȥ+kdy$zoNzSճ}"ְ%vŜK[ >*O^韓1H_3|:-8ǡSA ҄\]qRM~ƅ DS+;uVJ}^/A[avhj:~m@h|5NWLڙԴMXe}:j\#uKGPw!vm<.O9[_kYټp=8#О ;"3NYkiX;$xzl=&tMXIm>KQ I_.O UG_l*@?e 9rcnRm5b e nJהZ;N,I 3Xgntz7.1酓[LW#K]KPw$J (|Q Xk%.O+ 0V1猻3i~X}y5ٖo":T\ 9ԠX,՘dƧTuФ⩜ڴ `o<|[Q!iun ݴDJt/~NF=m& {Mv}^piIve5j1y!m8\/(S$[*!{sٓ#%DbBWpd" i2+|S.-cN<ѓQJdmf'2 cxٓBuۧȍ!:6SF ,錍jg<8L.H٢3d Ϗc,W2LDx %$)+3.hƇiAW8ˑ$l.N9bREj@x-[fGi^<836Qt+>UcR +eM!c8SIjp5*Nǐ2] "\y`fЇ\Tf2ːad%1Y`Ltط X&@VٛSSkM]è#u=^ne>[_HV!3|I3;jR@6^M𙲼d$Pb&2PKd.7gA-XxdH@ (($mda!" /o+E/$"w@Gd  (0-^$`"2 =(ALsH@A 0@%A &P8֋0x@{B9@AH< $2 { 72y@l*oPg<&nIP"d3pxPA>P@A7&PB.y( wd^m"P,6@@_S@P.3!,^oc.x%^>Ь r(X .{ >2[B$H@| $@&@&Sd|@{Ç@cIB,VLL6'1 C Ő5Ǵv۩0 [2 ^P HA-82cM -"R : 6vR6Y] >6<,w"10p n !{?7rm 0cK1[4EEK C*[db_Nob\ t&Jc7Q ٨PQ/IDž{A14JLV[즍M>s0çymG|nO%z {>nllZgR?Y'±m: .l 5oF;5Q5 h䑡i7ZY1-A..R┟,htl=;STP9q]B*e`YDɞi 훨rbssV]iJ' J ;呡tЇ8 n(oN[dD)p6jJ, ʥdYH;kCQbFQFCGsʤb*$wMLwSדhddUz 4[uYJ#qcZljD?w Mt?ʭ"Ƶ`w(Zgn7C)kjն-cLp?CmkԵF)Jʭ֣6g'V2=/է'[v@$vBĸUeAV/O]=Z?ݭF%I~Ҟ|j%3>JQ %BgZԘiSXӐ@DsK|r4*ѪieM~Im/VqM>UĸY9(O/Qr.X;tTq.~?^%qgRsPE13Q=g­\!ɹ>;% Ucpdhz4иAV:csGą<HyvMiS &4iX Ɣbhj~t5O3$exI5)A|PsF ̽ |#|Pc + +}ЧV|ƗYvWnXzp2xG螡 IKx\x'RkkgK&#zQQMiHG֍?n'YJls'gnHp g7¥޲Gqzؓm%QGAڍm*c<\'/鴴:`!VIznid=VCF8 4YzYh`VliQ"GR$v]aiק[_V/UNX- .N(vqu_(jT*ҳq,q|zRپ&y>s -'&_ 냺 vPUrtFOi+|F w @V-Ѩai #g98;<[[;d-U3tբ4ϡ8 JAhzt}w0 0QeǸP ɋg&)WhNM72j'=|5L絮iòd,V{@E)*4IIS:7QU2ϥwiWah3ec ӻSow jExB=ȳb2h SD4g rdAUFM2Kt9lDf2ތd+Iřa.fNRKBj\y(ΩcQY^,m (2a-άr6Ҫ"%zX5?Rv+LEh,\LS.A,'h͡4Yzەr Zum\+ÝCEJ9kVV2YaBT]k-͓:S9XP$g$%\>ds raJE BFrB,Or6xJIGѓӰaWѪ\"Rk̵7qchxMr6I DKj4Omqh3f4nZc7~yI_A=$le]ltn.=T{"{S$)O m"JȨʕu26tJj γqL.$eu6<i/f`Sv wtOm5`SӸC 7[Z3s9GZKhIV¦O6  B^=PkV.In$-{br'`2yGȾVf4\SfݕTtuAڮ 'ٛMrn`OZ8ǖ?IJ3jih@k}Prs5\"H[F|-.]D(-TP6%-=*2%{*ItF2uSP(i4+Tw :%[gŧ^gHǤ4OZ./4Ijc(-g4zέ}%-YS0lD`k.tCNuϟu=vGWO4N*GXqM~?L:vfwG+*y'ɪ)GQ쬜k.m/q˒Tw;e-0skZ]|}ը9b"jRmx4}N{d,ΐs'@9kyEE'CFWz> q゙K`F 0CKCQӂ[.{.8gXo}8ޑөR OSn CB-)a6r)}-/2m(m\&H࿓V5 VG %,luNf[VȾOcMKUƓĭR;HH'FH ӣU;=Q F4w89XO5' /s."u`,rWx|M&|hkKD eXQF58)ZvrfЧBVl͐2$u8!V+BpLsO[-dۢӲRxW<;(˝'TjͥvcȟF9 i?vW|3e*Ej FҼIc‹`!6]C^t8."ZX)ɜ0hϢMw HHakRRA.\T9` Bb1(ɓrMV;,91\SHL #+pPW6w]7Iz@[YΈ&|wԒGڎj,^ WA^\O3Ot̼Ihslf]7 ,PsdM3h@=. (ClA|L Ad t0 2a @'\Xv$bt )mQb6$HPr\G ʠY l7"@CLZ4~H0E@ !0t غ @ݐl9A%?t.fd.oA#7@ 8( wsPZP& QA *{d'd9<((HcS?PĠ ac{ c` P4$S@X=ӱLx@@,f%` d2>>.,,MbO&2H &bBLH%.* 36 "#]Nc4FB`p%68g#$]mgm-pe6$N$HLf OF4PIVke8U,i:MB"!XHt$:,4Z;eC RP <`ù1, 3otur@ẌN-f i4u"],a ^ LN&cÎ)#HOu7:uG^6H>mv=.t:D/Z!"ʹ6=zPt:djqȘlchBi}C]HӇ5r )B8)톓%V2#9*_fG~9'4B_]ݑYRǏTM北 h"nՓ(FO)%87ZTlD{k5m[ Ѳj)UYeKQv,cA%[ThNh! 7-:QblT:3.(2)+-w쫂ы4m%tU!ng(Ivi!GdElԓ v?2+І ^$q2S})@[(Se*)1$6=@p˄J|iTA2cCp`]fY8Ͳ/#}emݲo 2cu,j>{ >xe.XzZ45/C46J莎Ѵq4z?S-RL|>NeN,>u=O\w M?1OgŇ|4O.Ҟқi%>Jo.Q<]Iu*epH+L&mIoIQ;܃/.n_8"}jv7MקX8V=$~M7Jnd6+K%%=EDw Zz˦zZLq ;<撉*'kIA$bSQT`#ې}sS.| ͑''Gy7]ߦjM88\ |-[jU ʚg 8ΖbShrdg#"UĘfv` ihݙNm%ѽt%dyU[vͤ*L1h'S(Dj 쵌j#E]&UsR=ARB< #uQυN6ޒWNS0%^ٗC) aqZ]Mȃ'4xZ<{GiVa[.7 IO5>S#*ڇ<-7 خ75fQQ?DG;[E"2h>W<.hDž&^(ge鿓OW`D1O]1k>emUDD&KFz촅ɩFF# 26C+>ӡ6Տ%UOh7K.=jh-+EpkPav|X]8mg\$jYN4͕ {&/?6(AiW()DVHLpŝC 8.Y#b%Zqufar! i x7ZNXH !btRIɈ}-HYtfMUIH-҂** +NMDgVҸ52|IvNsgK nHmy\e63ߺ2j}Sn3)q b$\G$B^. ,P ilb R ,DN|P" EY3 E8@Q#* EM(-#3d\_b|@P4#cN1l 5tJc4d E  h&Li -06&y@6@&3kQ.(O@D@LŭtO&P.t$f;Ea @d KJA&P_9@Qe~.7A EŐB@/2( m(dF@X`t]0$@ ( )XaI@lH !,R7Lbb -DhPq쁖 :@sdb2@3a( $LT P"&g["!S,ؼ{ 2ɰs41JE5"8HUgR j4jm1a| , ~K@OCL̦TmLMuY HHļ9 &{ ǶL" `5׼(1 fSn vDy$in -+h1GN?뉔n_VL\sXc";F;i1e4o 4 .{si FL|Yi<ƧK•C<ܮkt쥑}'kv+:j7R\KHvC:G/(͉0BL!W#RB$uBpc8٤(D,_ɖ.̕A$,g*i3WcX-c%ҳ3O-i,듖=P]ZQ?%U)pk EǑ+HﱆG\(Cwayp*3yp}֗ftpeGZpEYi[!,06.mt/YnIjkX WGbچ2Vr4,hR}|C&SDģRAI9v4X4'Ѷ<˪ W }_a娫)M>A1T5]Pm2ӢUV omk4N-}f f2W\RR|be%&Z+DF\j~>]3Z HK)K_/ԊDZ\!3eF?ZD<}cf]_F?(uG,>?G5ۧѩZ]8*7Hy/ 5Ƴ:XTE'g]Gfo1l#FB]WҞѺsBi@#0i\|ߍCTi}?nŨ% aʼn\ݳgΑw. GeۏG9i$;q(rM {X̬$Hj1%7l2.Qӝ%t-DR9>̹6ޝ:it< [q"rǧGIr;<ʚM}w{ˋWz?5}EihXNN5:fmvi4%!i6wxˑ=HΡ*3p/g'ܿ<YvsAyoFOS-պsI.<|aH<Ƣ4|on=ͅnV~Y<{>G+*cNp$?@Qg^q? v絟E8) kZIW)m4t{H=a`i^0J->?ϥkd>qk㒝C}R2N7U*TzA<&T 9 Q:(7 oוG4=LBQ>gU ؊Ntp:."cN앲K)GtN #i,$XT {Y:ip]=V;PA; 9=֊hrr&K]ȜX.5${.7a*nV>5J[$y` hgK:Y u:>Kx~m*nL-vϢMlE [KyI7SxsJ 93AI_oSk>ZσrvԲeT)#un\[NG\g{:mRT>BMKSSVF8*Nt U_E:?yY;G>m"zUj4u)xAB{gVM`e^N6RⱑQD2eZ`)mq ;ܩ˓-jw|U0ld )7`yB+E7]gQinlK$~K0Vicn[)PT+Xdh茍 p+3RT/d|Zͅ(m!4V'6jЬN mœcqeZ䪭* 29pk3h N qhL ɒMY30r9trl唀5Rr2*ʨȸ-S6lb]nJOS.)jT>3&&C'^WGk,^V"-<DHVQ @v }5ft;J&@Yb0!l:-@Z@]2iNl̤j22A@,m7@ʂ=~ ",*=8^OqodFE@&P2& ,@Y,;!'#Tߟ ,؄I0{ȲepY.o@\`[mL @s' ,) $K: 2ȁlZ( cTIJhB`$"c#XQBd@@P$HPN,s@‹@@Y,6x@ r3@s1a){[u6tvlAߟe,57Ls7'Gt(AO>SC(; wkI.%Q$RKx&b V$D?"Xk^Ų17@ F\0R2`!`E*L @Z"5at2n΅"9]Q1n6d-xYI#%c$kf.Tm xdPO(h 6G)4èɂjx3nVcvոϱKG23+ WP4{Ot*Xt*gacȮ,@6nk/A4V% 9tJs=zVe?r'>F2ҹ$yEd{\J-Us#k)ʔT=PG+U$͓dǕJ.1uE, TᎻئ"ANSc:8K3V+ғ챦dz.Xr$@咧ӗCۑp n p!kaJ!)S4=V3ɦF!6:6Ye=m쯄ǜ$l(>>BcuE-c.9 q$&ͿܓC!t2#kMS´8ˁh$-UF$sg詤+oa$nRh=o#6@울}v\ǁNqfx (9phu XW~ "PQ*\m6c.F<˄N]N-4wdj(Wzmz4u b݉c-Lp='?#zUo_oIjO5oq}}T)jWGS:7PTFFcæw'gĴ7;Ϟƻ*Vy/tDz&mƩ]<0ۊ)# -h'ZVs dCr \w̸\8`N{y'~Agp9d|H)аWt%,R>GWm%td7SRqLh9K-=m8Dȶ_, 1%'~ CZ]Dӎ2U0Mk=pȇpcVϙcƭE΃*n:v9&Td,CS=ߡju⺙kOmZF/>+s>?i>OPZvzL[~;Gm]k*W65\Gi2\9$qA(/?j;>iΜvWb^蔵4VYQS57IAlhϩQ̌]MIZ_J` M'VӉR6.O!:JT{>5aԃAsd3uؚv33XGiBT}4ѵx.yc&Gh ϜhF7 `괾+ Ivhmgf y9G雚9t+?i+87: vZ5}VvF }t\OԘ`JgLfn,qz-{:\ܞt_|S>MLui'9r;NrUUY pF^OuYNϩ4n+3ӑs\7щI.QysA B:!h1HŬ}f4$'^ſqį^T\'!zj+{8(KR4n5rʖK$Tw@& <.Q]iKi!)dMS3e@P@(&E|Xmaik]{#, QHk X֕it-45]X.B>4A yߵˮ) 6MiKh4b3Q ( 0Z Rl 0l$C`dԸYf:\tq2bqt*ZBh#N苳H]7Rϫ%\y>\p0FVyM3KD/*JnRI| l{bK;v@ }0J`[|e'"_m^lq# ,`10ĠEPXM@.=e"E錨ǎPd2RLEƴHH00<sMֲ,dJ b,!($_[O a([)Ͷ.%Hsc\E;FPdK8(GDd&f@{ 2Ő FT\Znv1G'1Ih@x0'CkBL Bv4Dr(e}QB.d$s"3E@B2 ( m6i?DP?4O  2# 2H,͓`A[D 0vM!$Ⱥa\:LO CN 2&@1CF 310DaP۔d@Q IA:9nqt2#/ }uMF|ĥm*MP&YOpEfZˎe~ar N7>Xz+X:!FlP@p+ULDUaӬZc|6GM=ikn%ZG\5-.Bq!Q-Mƃ5RξC CYV[k NsLJN7V9Mb݌&vӤD.M ^Z/ҫ,?xSlQips9w_TSKO[vpj"icn{>_ބ՛U&=/Y9'U{4ѥޙktSQpI*7K#~Etw"htڇGG<:>E֓IȷK55Uw<+.r[WGaF #Me( —'%Hk*Iv=ŧ*ǚf7a<U>K,Kb)=n-t[KYcۊjchoikf: TK*WUUiXt=,?+l<M1///gAzX:yc5#@'J>m&462JS?6jrkf8~ç[rWQx=#];QHoé-^-6G?mWT@2Ɨym-uYcձe34YUHM[ ;kչրVz^RSCΓ>I\jYRaH7 XU= :nLSi+ֆ7'LwٳӳH5M80D8'"}rpiTgP,\w%j)QECa\uEBKU \2+V,$0puj""oRHa&_Ll&!<;Pd = dQ@nRv` PX a$ H32na0(!)$A@'nĄ@ ' ĠedBL(;.oc e͢!X|X&&. .w ($$.De0,9eEY1Xő\F;Eֆ-ʨq54c͖c]ōnFOMi܋O*ԵbX TrO& Re5l*MN]-Y{5^ G_qޤn[ ;^IZFu٦6kZzzkjB3LpEGSP!T57ǒKߝ1^F7SPy!]궓A~nS++,j3Xg>6˥jhucM s12\4qP Ǯ:/]kSldLSTs~LҎzk\[]T|lm.|z|xB =ƦOL Uf˃j]|I̿쬩zEhMבS'?Uzwt>FEs"Zl.rGϩ>E}aֺb~i?atQN_>G% ;PM'N$12M=9rEɃQ+8XͥJU@sA)qEѦ8+[NQ,٨ǖ-P@Y\1y.i0ac%Yb@yEiSE|0t&^[D{LRP4%G.b\!?CwezMZ:[Q|AR:T&PS`[8=%!Pݕd}[gދOPIZ$$d9O4bˮlH=wI6EGvb>&kKKS+Gj:ƶPnZzͭQ1d#~46q4):6w-rdz|u):G}#)`1rs|d[b:TQv>Ȅ8].GοztzÞlO+O9#,}YKݸ/Ev~:Mg4Ty"D R|r-+=Kѽ$jo{È6\qVFx9I.2O(hGCYGSx+53NN|}\LTVaZxo:zٓ??&I2e}'mUHduVqU>CFӻjlǣ>Qam;7#K: %[w\پ=`\3uiV<F9T)fMVooۖ|=Sk,t>I 8UBɉHv=)V|/8sG Gd܇ $>Y a6F|.PIթ8+XcFҏ)eZRMR2Qֵ~WÚpi9}Lzo,'|ֻMunV3o $6X3nXɕ]TeWt%\)s[Ӫ6Hh ASR 8KA!\]q xn6X> M>SLic1H^JqQLDAdR5LI ́)Qlx0eCV=dʱ2G![ۆW׏"4U#dJ)4VYqgZ\~|RL6J7WD8+*>a@ G -לH,X} .E@1`SX$""SD t`ȜiL @H6$##h `$\a0v {B` H \$P$;D!P@X 9 &hb4aH1* m2 NSHE%:1o( 4KE 3*}10Fh.=L ?Z3}@%P\0 e cx((d-D[ (!.Q`..L  B;JVs(hvȴaPxT)hZ `iH ct $ !o6@uqi0 :a&=6,6)-l])+BlD-bhႺ"ȡ6UM q*O)2JUsI,v)͌afI1AA$Hht:)2m h$ L'~7+)*0BsGBrgOIUkK4W&5Svt)ԳG_g+j0;e9^(RM&x3-m=Jwi,h˂Pt.p1숶ciCZ| eծ l&רEG,ht -c6tC3ezUY7SUZ٤sͰz{E\B+$MIt0Q-4Z%ѴDX+lSZͷf2ܟ &@26TU6zqk!8NIo.DAgv)} kEU,\glBl.mjl,$S兯Jrj^NwO)S16Vo|~E7. y[&e1O5oM.QK? V.xW?cWIG_'?EzN_j2HArzcU<ML=".s6_kSnnmǰ %O,ۋ6EyAaq_,p,'TS*S7:Kg|dn9$-Rw8rsPo'c[*T/4݅vȖmˠXA6A촄-Qt΅ԺQC_P+X89::X*>пO5>lTQJ1.&P=/}>u+?ߙvgR}Cu:n/ a'XGitJ>XKtS> /A[_ӴC8B0NS<4I_~=Hhȹ=QIc~^iIZE.Q=\+_SZu 07tRڏ{UX+\ON_iP0X?@wǭ6d}&vdϣ1hF~V?(N#.oJGGZ4CLv1FEX3t0u-6n'uz8e}+:^N咔Wxiͼ.&_I>Bӥ*>W:6A5FNW36YS\B' g6XEQݴ٤_GLu"-#tY*4-C%5!]@it˪^{XfZwP6pI|̴otzv7l]c%1,kmKK/Eyi!ΐ;.\HuzV3}6*KohqO? sbj<1;z@Ɂ+l^gŽ` -%.N!ThH*L|fH(~'tec]G45ǞV|*>*nѐ V|m|a̮\'2ɖ{R3ޡϠ)mߋɏ?Kzk'=׏5+<1qhI|]+v 'ڼN9 `w\B&Ѣp|ԝ9~ -A ǑƏgi# zCI y]Y ]E~:=z5}'pW C~3Rgjiqn z9l77\ޝ.O/YQ/AŻϺȫ|MI{]5FVd";N'N2#tUXN*ѦUǐ?ԣZ6)(ʙز8{{.NdBOUZ={r!*e^nR{pˉCQWnWnYJJqyɳy޷ 7,Ok=mr9RZ./Tji`$4gf$m}3 j v*^wSw>gXhŮ Bװ?i.Ŗ~;5Y54g7^3knNм77'RkũR>HX?ܺTGQa~`Tzɖj"Tf}CdH\h"0=ņmŜrte[jcA% Jd?t5WnǪFkAnW2|Z "q<v~W]_yZ_ {O9\9\i/."$ct"Y0.X&)؂l & o  B{n$^ L.d 8S xCp1-9SH@ 4؜3@04l&S7:HI(@t@3@ 6h)aMX;L #YOb4S0nHTkLHB2cLB̥a2#)X ML4 CHQ`bdc"- J5S'^aU/M IUv趶AYQXHTu|M=%Jnh4஌r_$7S tEVy.Z(OB &-zR o'j2,*dD4e'a˴mJ)59dž1ŪFk҇ 51ZEkhLhh=V+U$f-Pʺ㋈*>IVQU{'tdgTWci|] \Pڭr=t6If(JϮ~z*5'J0=VUd+1x.ϩz֝/Ga8\xtGx NZuTksYm>r~ք! .sIx#]XZzh ͋sDnF?g}VU]]G.$&~ cQ[V`J1vznY?0yOӗg.Liseι=֝35Wsγ ń|֓yC.miRD\ҽ 4e=p5ki:{͛oL æ75@\Ӄ|w产P 8p= PJ%^j *5* <]r,{ppQRWf4YȸÑ Fحeݦs\y1gq-VhCZwc8 liJϢxĩ̹>KE+>a:ad.VpxXidQNGxSg}HGC sIIxk7O=&@^~r|𴏼z[6NLzMNd^ɩmg/:<t^.Y,ύnoQ${QIM}`GC]WujYG[/BaX]24|O\QpW4d%:c[*չ,}<2mFbv5u+6[֬m3qճ[uzMď+І ]rYϺSa]Xk!|MNmmWLgdO8HA!%^W KLEO@ɑd<$_&d1d ^8 ;(vC@.'9@ @! &@Z;Xd" &?9 CX9<&&hNsœY>H4+B@?Z%dXYae -`~%:*{b@ Z{rI8Rfz–Y3xxLJDI71ċ Pl` u-sX@$ @_`9D J"{ ˽t`^>P de&-H1#(nn $I 錀tQsC.a0,I 01@$&@"}'$I?PP62P"[EDbs(@LA @_) E@$(~1 yfN/aU;"| b"HR`d. aOR`UL6L|B``͐U RA; G7MH_ HY+Th=%h]r8B$Y@K,`XZPR Pě`}iVv q'1xSr,H:lha4t(QodC9+ca iQ&.юL0j&gB􌹻3z8V;gZJp1IŖxѦEJaLyGBUAT;씬jwTUTF.8774.E6STpŧ:V4>MUc#[)aQW#L!IڇM5gVܫwDaRڥGcG:l4mЛ_zqEvhSDNARxT5 <;w firݲ=nj5CKA*;z8-.<17H]+ֳ~kj;ܔ\8EY lGs:oLju-%FHK/9/9YKl~xQzz֣e7QfǞa5fƱG¹Q4̙̄VԹӥ')bDt4}HOweC^=z`uαR.I.WK]GC>.)U21uʑeڕ~v뾡mM^KY,0d4:,Zk5g*#uѨMf;\Mz].=響tZg09UĜtdz|\I`]9oj?COkZNJ*0ZTЫ5=]z"S8KC.6 \%/G2=\/nnQq 3Ys'p16uԔ?}sU)5\jϛσ!՘KYz>"{py@!릩,%\KjcI'M]=2? #JJtCAʴ :@TndgF]3VӋi2mǙKIWx|SPʐ\A9>WkZ>cJ:t:!KJa ??x>kOm2QJ7Yf$u 2hhi XV|lɜss3o-O[S5js'(>F- }kQOq?J63G}3چ<>G|8>Aasv.l|:niJep lx[.{(zgkܯc@ Xy!\4#}:jD.Eͣ50p}Y .xtNQ|^mI #z`/gQ¨+FpFE:զa2;&k$}MwZ:TKv4x=6sÚQ.V\n\I]f6Ύ̆%ϙ I>>U[& &l7CG:>\>ڌ ziUq=tuX\ ]ƗV6_J!i܂N˚iW(FKr>mBKOe!XerO: +ZShZҺ1lZT8W3Ƥt } ^)^mMLGؐڊ}4UXZ曎o?;Ǵ~ ʗ(fF~y(8J䴓qg=} :4口\`;G@Ᏺ^wv{8?!ʟ,:#.iG K}ks3)G׏/r44؈]"ϠǯEi䵨Lu:#+h:!嵝Xc39NV)!pZ&iR 6hH ԕ \Ӣ 6b8^|*U1B+@Gh-Yg$(ͣ"H{$P0`\WhYH mS!d%PфF{ָVգ 纥)buM-ews~gpWǜJ)6S 9L}B3 IYۦ*RmϓQ,RM8۾h."LAl9@FrP D ,EB, fSAl 6Ǚ,. ` ,~B 2D!@ƃ(h(Fm&OtFbI. dtm!0ƒlS9hC{D٦*Bc6H eZD65ʪMH U@QlH-c# ikBѝsPFZ8ex$I) )@6"fI @Bq``"@p=a< !b2J,̓H'p"P$@YRM_-È탔QrI" dPp!@[s09 X8ـ6H2.#@m9$YJ 8! !@Y@̷ a @P0ł1F bmr mSmh mi@Bd`8@y`;9.H։2S&Np@2Me8A ]L` HHORP"XAݼ@XHCI!"{&|(J3| ?Q( U C`%æҴD2˶&U J`NPĭ(&i ΞIUFG2Tl]S YX8]aKHVX6czIq c?J%:\kURQ Lq/b\qł?Ӎ]q}_%ڗ6AVnmRKmrkFEG."[].lh3c(>rs [Rl&wBܚGK\.\[}XcªlN &ѰGtF7=(r=ƴSY넁j[,+`R zzRSm:O%|0IʯUD'glIۭN {/ohm:qJ||9H:ïN~guiӹkz8OYOI_/z=cGJF X[JVk5ɥ|zΩ=6=Bkѭc_95Cef[= "TbRr C=J팺䜞WJo#(iYLLZx[%oDܮǒ==[:XZ`wi2ƗgGI=(ctϖ~U,53^> I$q鯞3_{ZXgשRGK긹*1XzvKpq7½ [Oy`h8_/4哓)?lkjj5n&ҵ`0\ `[\W^G 8Tݸ-xPJe3M#iE*XBݺ)]S1Q pkk'ЪtAwqR܈=Rݼ)OPBv]ɳt}WnZjY\O$IS^iWvƾOiܲ[<N꺗'G,*GSTA+';n o=OYT m;g|G5JRęM3z5iaJ2|{,AS!c{iW 'zǾIqQӵ);[YrN?'+=^Ӆ1FiiThvAg 8|.jWj uhYvǣJ+>xqFWV+4hӦJ8G=$7*>iL7p^S\y M7ƤKG LndI4ԆZ+~xpbAU\36>BɶdS6ɧ 7Goڟ}"layyIWǺ HV!sMq3zg9KN{!Ou0anTk+2A[%\Zy}[.͏:Oe5(*.hc' xZDHť:iVqSn'I 6 Qީ5G]mVJן(L5:mz U:E!7~)K7_AnSd6~hW~4>/\-g{]!t9]oN3Wfz2V6ǩFzFWL5 T]gT29 TyK4in\xuhjIo|M|ܰ喫W2օxGDL%CF2I,e*,iiR!(aeIP;ż03?E9*.iN5J+3yTnkTd[)ZzĠ] (&3*I9M68VH@ƱKpd4^]&Qr0PA?2C 4Iv] LLb4L pGx~W aAۣhxpR:߹r>[d`.0Vio?G\6`lBr3)i]kz_3c~ȡc> J&7 J%m8 nP-ʖF'TYW-4B֓@+'~`Ԥq$C ^+X&ƪH &D{Mb ɝ+j0kN bC8{m:#|ptSO9[>eNV"j8!+4M\iib.)F*[N=~C#=49ߓҔil[OhsQetu.?S? ǤҳKEzDm]̒O =o#q&o| 0+g(M(ʴ)7\ Tѷ Qkh';1KOezBeG.I LѦ]:%}6(bscQhqw pj*,V-V{v5O7nt(0ƹ#kQi\|QqɍtǢnLG4MH>sm"VKjz_N~uPs4 J-a1ljg] >6oWkkTd|Gm`>+gar|=)8S;EZTh[-F;iW_;GϺZ]Z:S8p}&0Hfr'rf\IyVrQ$h`.5gDR 8̤䄢N [FQCrUDm&NOV#H-z@#YꮡMᢦ)>>_'E*[Aq]#>}) }J- OԗH^K^9'9Msgۮk 0I#RM-tܦhXTNG bvvzjR<>Q?{͉9;zֺ J{P!%el~O#Ki>YWt.Y`< //5)σ?jw?|]SSߩ LmWġ4}gN3 ~LYu+Rg1 tᷜaQ닡:1XܪEznn.,6yEgORZK> sZ栎I[ J3R|6%zJN!v;pKzr|)Q뺞texz|1ssj}='Cq Lc)?qw=[@x[xS#SWYs0<k1 t}#헶9;&~Y3/+t3<ڒ/N\:H2`oOK<m-r}2 G7'g麗Us++GAN;?=R"+3GW@<_YbvrWW}=Exr\?-v=MH)GΏ jkAr9^J-6}džmlU6 KU앣%/gq6!sIeod/GHQhtZ KJQpVF>>ѪZƿqygmӕ~ &>GHE]8 2u#'at6΍<=SZǓe1 9_COYL]vFI#gx>_MQGx S]a|{%]FϤXM{gRڎJaCփPZţH%H~#N][EejOt];UR5 5Mpt.-N&x'<2RGH+RM7lx^?}:BhՠMJC%;&%kqui봢 @#_}g sI{ Z{!;?6Ht, , 3)P/&[m9 Mck!C]51L_ܦ"9%?=^jiȉ '?$N)M9fN}' Ś/}^cʕ3NSN|'g kV.љ U%tBWݎfUI:3C-,h+d]Sbb.frBI,VLR`ʒK [Dy3z$R9Xܹg*<ڔ XqKZQ~Ψj8zʭQ%ykgykfmaq|Gsgn9YI'!4d |d&n !X@Y{dD@LX$H,, &,GnQaeba0(ې$;"/i#GXB9@)CSEA@"&e H8@ \ Sh& iMi*fpy#K*Dk9VKƎU! !ZCx¡1niM]C@!#*&f2TfW$)e&g~lIj4K) CŲТ ۄ`` D@cLߛf (I0L;fg=;nQbbn$BV w L, {^~/q8B, AvstX}`AHuK?,^Ŷ^c\G,ڕ AQۡ_=ک[T>'QeMD`T{O_fUvf!֡賲HnQJ5HE:uku{ٖ8O+=mwJIbBTGc!b)ƲJ w]0)rC٧c,~g.`KV8gki9VmKo<Ǡ ̄ﴩtCt()S&04_'{oUOg=i}A^d7J.?xL>:1{"ג œsuh9ZtB*jOYU4|ҺJNVGnn\>d\jK Kˋr|-gChtKˡk&0=/<|(FNkdM}Jişa-9[}k3l1 \jzY-{@P# toM~}E {"O%u¥ &4ӳ?L25P]:\V9|ehG]@Pd<7.8ɤgG%mKnR5^VOBWƭ0wgõvNHoZFivaαϓOL%BGu3>S z D:YzjW\g˱g=SҪϮvT7WF-O\j(-bUrUc%\_I^u}7RڢOi2!aG rgcCmr} EY*;eɅ|M3-8{ARiuX9]3?{+h֣ʻG?e,\S:R,n:~8CшxTÿ́.%ĠVX<";MeǛ(q5Se@6"Bƺ:qj%iHh='6oAm;$pWָ_GӨ9%ڍ;kSsb^+L7Uf>t ZubvzggBcrS  \ H'$06CBX̥(e,Bj&fJCDJlqn\gGQqLd|f/8(=B-)Qqw9q)'rOBN X&M^L6x#k 565ej-c@TcKE%l!89uK;o¥Q*0xoNK ]gp٦q424.x}&ikIHnu%qPBCeZOO|M2֐ $PTla,}"(a,?RVثΕ8d\vZM=U%j#HXANt=k )CkZ%iMI)p0Ҋ{]rVKxڍ1lak!eTDbӱ$rm2irtGUa} "nҳv*.8fZԏѢboFV9qerCL2Vu} 0O'6o쟩L25GFD;B2v*A9j2IL9@hq [ѡh7NM."fvr"8'r*TEjmܑ2O[aRou NS=[~3!y>WFj#)B.N_&f8FH;ѝwYcC]D(g&2ç>Oy踱F;j>ԻU^w/n~ n.t| &-ӊ]N8/5NbG~wM>svN^.hGEn#u * a3+lqrɑ%|՟[V pWfQj*8hE%`.u܏uz},oP鮦j<c?^/NKI0iti]*3n6gNPt}?)0 )ȚƓ>K>)5HyҒ.^q. ~!ºƠtSu6Èq|mAf:i]9!&|'Ivid$c:t͡@A GeRG߾[>u6{|#bm?H٨m?oIEӌVe??zV"!/s7?Vim^^\NGDdmG63Kf :vs}$%uh9]>[dܟ'MNCAIpօ+kh530Bź|(xT>qV}g˾ iumR' t7Ymv&'ϔҽ>v/̼Cj%uGLXC< E76Hi.ihɴܕReĥ&6eGn \;Lɬв77h ^;MWTMJ"uC_RI/ r4^RD TyԩסTLs=S}'H]S:!)6;( Œlmc L(3~3 YɚT.U$>Yjg֫s^FRGsgy?#*žQF 䯕Ϩ|6G$r g9Sz]J$PLNL[["yTd[D:!4Hm+! CZ# !D^fa ,S)Hg( E %0!i~mHvH&m`cM0d t< AdO@i0က/p"d0$6nP)s8@3K  4SbVE10UM4 n J ->B I†R,=xPFjq–3-FēoY*jnN3De&ZfW,ScL8Z<&;]&H"֔I2ЀO&P N s T8<bj$sfekb6Ad3-4&.'tE,TaX61(H!͎B>pȋrh&dAiBvF`&Tlh,o28HA7(DɀB$C$ Ae`P"| .2 f M$P& o(m&xMs{$6,m1 ܟ,; !L(8$MU{T2Ro2f#ꘁ"x@$yLE1d Aam=3t}wLk.wAQT"G?EvLC eAdm7<&ee&Њ1 C2l0&D<*D3u@vZJjD -\iڑzr;R>7t7LXw"'LIohpo2\3pF@VC3BP蹹Ё60{`.-n6˂$= W3Md,\!:Bq4Su:L4tBQ}s~KT`e&M@E]ʕ)ʢq(;FUc-LHD:wVp}NR. ,JP]iD -cfʃ BdmV;]p4:X\Z6ˠ_R 6Dp='Fo&7+{He"pQ: cQ5T1.is( ba.xʶX7.:bTU֚ ` E٢Lm =O z?nLk}1csygOG]潮qNJ[>-~\ۦ/ru^7@3MJ`bt}> +Ⱥ2j^|pmmnZ7lh*{QsнEQknBȀGVXҳ7+;:mT ~)&w9)#u~j/1^VGu@Dn|?(Mө 4o2]L?u(Ԑ0atJXϞ47Sd3˓uzWr}DKG:ls&|ƥo̿uhIsgxlNt$u?n +sH6 Loԏ$g=\|I k:4z LI?P5+kp{9(bIx"cuF[ˍrw::m97qoSfåLྫ +NJLeMS>kJC㸦~a+gaSF^Hr=ɷ&| zT5=;գ/tG,7*TY嚓rOZ4Rs< ?^i挔rCS[OY(>++HYaqG} (t_977b'XPh&.<0D+s{-qGorτҕMsYknL.$\~k<6:ڌUdutxh}3]C[Kk !flR+G3ԞN `^z^?KgzM&CDѕُ"GiDw%9.+a;p] FcPa(٤X`+9cSB,g8`hJ?||8K'?- vzrnê[+yFʳ&"l,9/ih,1R(,[Md KP`-#BQkXg2$8KԢ'3h5G"XuS25 IrvC[Dfd-NDlYX& 8, e dXYNpQd9ZngHMmG1ܹxdp#<ϒsنnl`ŧ}NY'~[,q{r%GJnLOdXÞSb =Bl$aE-&G1vm@ hXg e,]lA2m ŐnZHM1XFɷ-L 9&b@3d$P>A`&xv :!=i6L 'mdi|bf fchh"[ D)+BfbaZ!`'U4`AaA7)w@S ȺCL)e!UP38Z֐neE[h̯Ij u- PA9 FgxI3R-pr" !*L D`,2.41nl}JB$pqd Y!1_΃a`;tZy HoU@3Q7\K]0 ytȓ{$b`| 0'sbC1D*4Ar8H ֈd¢06c߄@ ha@idxIBI !  :-@0!1htD`@@0 RB.g>ɀYtš.10a ba_ 2D&i)6WG%YN9L$ɲl &"8@  Y\ ` hJ`tH .-|80HL͹ACЃD-@ hiRN!16N2!~/pP%]JDC- M"QTdK0C ;4}jra;%>KM dPGf7fP?GbȧͦqʴZC7rwZ"Х3M&BŶgՔ.:cֺ"8fEptAwBD{NҺNJu/s M\SIQs,BQ=4BP|@%nMM0<"Bn -AH4ZƼ8 *IYIF2Anc.ΉCw1Y)5Bw- GI::]Pb";TڍoIeVTFBi7Hϙ JגIFʂZcC4 ҉R96MŕxBb*m| d$x2CYpO]c37=xbs6Ɲ'Ak\YԨFv ~˪:%W. rbʼn^GF1cZ{nz:+)΢tz' ' 6?ɬ9%9gmۣլM]UR\,ɝ  ۞W3vQ6lbQȽ&[LJˆ#|[Y+ _C):A;N}J |>mH slr(U4ômkVMmO`' Y5.Jnft> \=w|6ܸz'y3j<}])ouYtX+!\Ͻ>źjyTys$UiFMl"[+9dSI^QԵTVԪc[.x`OzoW};CK]$@.Yr_#ygoG4?pxYng0Oz! ~I7]!rUWT溫 l;4`,5sSђan+bi \ΧDzT3vFn83vx9 O龇CKXcg9'-~z׮?Sw%zq\Zl;֢_',%PNK#WJsJM57^v K~`;.QNG|3m0au8qg~(ߥ tiƎy4I7AV m- ǵˆ[g.&<In\/R?yu4תRrFl_ q00t\;l/VEӴG:ϓzTjg2MS^/}W=(~g1}X`ɳ%ȱųۺ44)Pի[}Ջj5&ϫ0h$-<~q@;jGv{ש=ztџMBixu|ZFYXe+te2@ Bҝ&9ϞWW6K>Gֿ B :s+4gGArT}g]DA<)OҶZN?b=785+-D\ehf[^`BE:m+]FTYK+΃Mo 6:>#QR=-Kur 1NCY$(% 3 36@a0S~^Pl ,Jy@Yb(V@H)1@''BAMr)/9ETJ( )M!H "U0~𝊂2{1Py%Pҩsk nrH8RvMo)|P%Tl*?]Uc_ӶY ثQ.1L:1nVGT.ţ*TTd BQk9`+Y=k ڤ)RH@ǎ|]lOV1sFNeZ0c80rs٦.$q)8KC\yFڮ@ qo Øa5R]>?Fؽ4$|}O,U,sMMp6@+hWs6@Zl򯡌vJq5|ѫRYS[GCY hcOkOA} _:t5zy> # {4{+7#Mv5zjNٹ[ˇ֢ :zWƍ 6?U޹gYI{G*ԗWnˇ6y?s:*M\ئOxk&J:CHs6TӚB꯳of)q_R4)"^e n NA:lḃQ۸37D}66&l^>1"݀Yj7|I.<A62W\q4*KMԸWV8ќsE>>i(P`e|¹|z'KA(\popO^T|~ƞ O=C}I16$8睞6꼾]ǩaԽU.ON, #T{?E^#GRQٟ*DF#s%a&7\"0)5՞Cu[l|~x\.TPGGy*:W=q$%sfgj`csrmBT2UʅjWeԻy{%MOF0eBmesumK⯳=ǷW-Wq~5~,zch lx䧥w9Z]}ip!x\mHNT e%χTJ+s1LS,L!˚wѪTt#FjH YB13x`%ɍ\ӗHּOɛU ^~$#8:4 0[Mn(TtS!{q{aɼ]zkz?qżM>M7{1G$,vS܏=bB߂apy++?Phb%]M]K\UA-%"$Y꺗ihjj6@ b7\6?,v>g5u5ujj_QĮcsdpPD<:ԝ3Ꚋ7.m(wi+4cm%4Mle?kh7IW䋦,y^/h)QԵG?y'#=,E y^ʺ=sj֩#}981:QڿmGtOm]d5e¸nGkr;]gIC[.L-`ܝz Ö\WUC[|էeJGVճE(=6=G)%%OgF͊^xNQ+3]BO|^MTcMN4 2>yzSg"쒮ϡæ5־tk njSNu 2QsZ2 Wv\K*sjt2碪P7m~~w洏O>s G>O|/.ƲTSOɌi"b')nd!`pI?e ʃKH2FiiV];=^ N&@3ݪc4+k?*93^Tu:yҴ4t7]ohou?e (V2c0WadY1Bf-]M%DGt r{ aWM__'8?Q|7`!|~3gZ3lk$1pr~Y,NJ,M ms6 A7 3@0 @be"mɲ / e&2F2Qp(bQAe<li9@ L}Ody7p ͐MP a4\|**-)PHg@q&B4rJc.F`a&hD|VTIEDH$E Gte;B!e4&)s`YaīB `PE\HlAK: /Q.frU'3?{c>R:Jݤ8 ڣw1{v\y:15%:.fH d#+MT L7f@%ktC>pDppғ2.PƽhWlk̀ _cKmʨŮK1c[4yՍl˩T&f/igqLΘsτѶHI*,?8c!ﺸ5B٣6/ =:lOE nmjt:-#K0L٥SQhcK.]L͕8ZWӴćH>oFV*QwQӴvb\.@=JDӢcʇڈ]_PTsFvϓS'lW,ܷBZ(~dF`ᕚjdSWn\qh%=@ 'e s.Sac](] B h[sT"Y4Z$ٷ- ,RuۣY!Ѥ~clmi}Yd^`ꏵX/$DLLӠїEZ,rkro8f xqTtʹ5y6$썸q͒gަ3M7rbYZg;y=:שuhh=4w%n=N9>ʌiG֖~28?PI&jsZֈFҕp7MJjSu=ɅXv9pr_Khioӌ5 ld\;?'yߐT~ϊ׫kj7o۷ӂLiޗL.7I9\Nݏ4FrQN_GCXZb>"XqQť^~N=besᕫ:1_%-^I\K|;9\2v@ ;+-&bո켭ddvaaUxs.dt`<\;bv0j[8f@ |m$GkҰޱGRa#Okv )|~EfV>M^\\ܕٗ"Q)($ 6W=3 _uN[pКIQָ4Bd34 WR~,H7.Nfo4it+c h~g w՞Դn`;Gzy?9z4Zl`/]~g~?#ɧg ljrzzǦk\x 7{6 jm#IBk%f:;R\ic@ :R' !o5<)Qg:;GAI =){VdO*C39]~Ad_'&v2Gka%B]Y=3ɦ|i*t{vvmV l\xgT:={hm]ڨ?il[h.TkhAYy}Zf L&&H8r:1>Ѻ=f1vzӦ34ٺA+}IE5Mngzy^hzrA!,m;]@_(_YFW|;D;pwrxXg,3>a.jjUmi8Xaz0k|wcύENEphJY|*:E&5$m+fk,f,{p|ޅj09Er-nFu~ _/YoM9TxMX@I <$,BGt2R du,]C)2pCE]|,Ma*` %dG|Ju}':{&\}gk#ov:i\=u5%Ha*YBBr $#+VJVTrY-:"UΠaVY* Ԁ@FS$@;f M3!241 M/yV48hha|+D3M7sR%34U1a D}d'6U4 hqt߈SE|A3T,hTT TDe#-@fO6Pͬj"2T’<^H"!4CID&Gtx*dMb7!9ČRd $ Q,o c`Zݲ%P0a=d<n=AGAZ"85]$68<" ( q4S-Lp8&.HE G잂mXϺh SM 2O4i]+TJ62#7#X*1hWXm-e,{u"H$8ќs\lE-\?K~X:nk5iڗN @W^<koNuM 1_UMEL}S,ٕ٧ʊ _Cq+Zf*Z,]{iOU&jOe?akJ]#H?Bqnͫf9hЦ>wRv5slӤ]r5EJPƽm}Efcx'. d^%?sV@%՛v*0~ѡbl|4-ͭT;rlQɐұ 7O8Sccl56߳)~ix1Rn6'$6|E01`It2M'5QԾJn/<u N=>-w୞oT%2녤1lI|VbeJSjR &,?^L\}CXQ)pyD63g~%ݳhC#LS~I|JXxy#7#^WA lԨ78+͗&|5:7lzg}_>Q`Y۲ag>~;ISʮGT{Lɕ>%)J..ii7+-1t;?sg+ЗsXb2#=/j:]jz޾?185Ӧ&c.''m4z=ItӀ7.Kky[OO>Yk>_G{ҹNqw^&}*tGŨqlj%Hi5.qse{+4 (ot|XK fnG2^YIƍw.8gEc?L Vs<Ňs|/f_>!Qy9v~(\# rBigNtٻdcզ=ˏԋz}G9IKȔ}NQ5MqD F0e& .)Lp< HY4=5nJ1uVW9'NLqp5p"mE[=74gU[P+.߳f5v=ѱ.OB"}Go#@Xũ5g٨X.FCJL  v^VĨ7)ٟc'F/;QO#?<U}DF1xgyO~p3u'^=5ɕY΅*vpI=Yt(t>527lEŝYݷ3-GtN/#, vּ01BZQϑݳi105*<$*?;In]w Х,(kdtGԶj6ʌK\uq0jЪ. |OlJ]+Yt:ѭ1/tIScWHݎ ̜s=kmRI$٣+8}hh4zTYPi7Ʌ{YgKNhf=VmJɷG.|ךSIpg˳ |DR7_gֻۡKY0?PH'6%~OzWRցOtnmD%|rޭ)˜[G'?R7IdRv`Yz|)ũ78)*w)p4:@WT6(.adUJ9Q3c^\Y',YpQPɾTOCB#cԇVYW( o3[Y\A58?)ܪ3lV{@;s D`tm8 v@m͒%Xo$`)h@`^ #"@(MȺ0'*нq[p0[tSnGdSP݋&&؂Sy@LJ3&P5ؕ, 0q am߉Bn`]!92̙$IěЙ'Vf0.EֈiaU"iثMSU^B*`L]& 1O2R:d)C(QԱ5QoU衍*YfjH#-@qH+e%T:|B_7TIM@HA%kAHh(Spr B`!.H!aD3$Lؙ!0<Ђ)0SͬP"7  9!ecaD.2Cp^tЊ"Ɂb[ И'3),c?tX711YRA !R 3(s)X b*Ph,( I at T "M1%%i%n0D \yDx}ZrN)[Ǘ]B.7oX|߰VilhI3} kLrk_ds FDZ/O+Pf_)R˛r 6,yyWt<01_m{]L0~QOԵK_b:qUTǹ7iwxҎO=7g{H݈XG>CU K{rٮL/o PTPG xf_#GCFZA#qݕ~Q~Iղtm Ϝ~i >l~!2|w(G-x?yГL+1NbsA+l:} Jw^u2ۊGNk)g^OB۳5 䅎9̑/Ľ e];ylvCѼmk< zaah'15J.ՕOۑ3ڑzA.u-әQhS{O3GWZ`~6G~냥 WmmR qjTR_}+ܹ=^:4e? ?23n<Hu 0MR>^迃揷Nҝe]ktKja?0*3YG>ON:}XQf_:Esυbzy8. Y}>bmz/|t3T/i-tgש ܏#fgdKhSK4Lm3" ভiU:WRK| k0<\긁|ZNk?|r̭By r 0Le/qZ 7@P@eٔ7ʖR,2' I+6o6) 0rgмVquM຅~ ھAN% NKzg &*4PMqau3cL[vV=DLO3Z\ͼQ~/j~9:GDfW?0 ͱE3 p|@X@֏RxGd6~oh ls@>mo2!n2&(^41n S"yMLBy@ 13(&&e| t[>kX B, Bh(@23stS&| m aA0ǔE3"Y!Q IرTS.U!i* OV撴BCD*Cc[B,LLE yJ7V1dAC(S)OMf+&;|Y&j3 8f3|:3ׁE֦`RLoU6fIGLU3(GwCFoϪo  P!o >:㎠N6JjxB[b]]S˸hlSK0V̞W.KF6bls(ÞGooUr.wljF 4m7ۗLZ4J2YGj&HLJT=C:â.r꣆;#>gA>:MK~Ʊ[`2{/:ZQ=&o-9t|u_]?YkfE?KǤı0n rgV#kO%/y&k9TnVNE)VJ=ҴwW6~Zs?.EƱ/<'ɩʴ{#m~.Uē?Oe|kazF͝mj!M)t8ɾ_Aj48ӤIh"WfHrݥԩmsİ8~U,O<~ noYz]vTXVtkѿ 27z59Kdjب#K2RҸ 6 NQFH:֐ ZAOu#NOR_8b aNU5cI[A'J˺Fm'e*Vdy/;ZUK9:za-JfQT;e[pp)*11nJ2a&6LE#H*G:NP2Z H cf<|c<"3SS}Z.sW>vditz1YXJ3лUKQ].OO4#]\q+?!42/|'Ѷ;4hE|_VtYR u'~[$TrI>8i*U=YHSZ Ae֦v'xGLѥ/^3 td$7fm?k:BN(ܱI#Z}cZl9F>aStϡzcR?kL9+0l⮊PSptWZڤWH#Y>|Brf:\s94m]zlxfC$v9v} 鍤70k' ۗɃop  Tq=>wכ_Q>qO!yN% IpzRhҾU=fτ~}'l/Bԑv4sRF'F@Sg'zOJuNT4G\IDžͬS|aW'غ%OPJ&z#K4{"n4yItZs$јŕeT?AB:8HU_FτzLKBJ&S2h0PC DŽa P"$-7E yP"$8PۃLiN>g]o{ 2I&B|9+>8%7S4GkgWW Fj]->VkP3hk㓘[݂[7pmf%(T Lo:gz=<37*=KRwo?G o_+T~7sJvUc⟘dl.gb9) YK|1c0qY"2,r l> 6@D6ɸ&Ot n< T"M` *ɀ%Nb|D&K 08E!N6p7QpBy@P@L9R~R%D i9LLM$b#E20Ghl4#UtE쨆T2h{!kuhT5IVc]140T*,xTA~L8@żCB^xI–Q߲4e (hg"J:͖mњ,fJHЇat2&SC\ l @y<#bHB ] H($" $0 9( B((#v#c\]0bP"C EZI`E.H1#tK6BA"Mm lqT-Z)/hʂsZůj_RO)ٞAٲ<Ț;c5VY%ʚ7} 0X$CiD[\{f2aiۊPa9j69dp\js2fr0ܻZ?6BEݙ}A+y:r:K{Fx"⌹9gmWE 'PLk\VL fˡDcc)LD"FQhγQOMD ZmJ.O<g 65_nK~w 9zxG/\鞛s^Mh.hcyR<?̜>Aw;MU v;Cǥ5`Xeb= 1&BK ʕv\AV`#z/ sCBVKo#bN>RJ mWj?=Sw˿s{?s?RUF~RY2,+d9g6H͌\Rv_4]3Ô'{.QX.Ҍ#$xF&pyֶ Kj֓J|}#?.:ONfcŎ+/|?nwʭ#*5 7GKϽK3rMol"C[ di*E@H?_VNi6ўj ﳙ.wg:BԊ4؛UFR,2i2pgayz'Fjȵ R1%T朹:& /KC=m8:P&(uO0dBr=p1EFAu]xٙ3%{ox?5/"\.34Wmt:UVD9vn^6=nzxFRE1m69}B_93=4n%VF14W+X5EGp+M-KUSKB\иrABm#/9${V:cħY>7ꚽ_TB>]{}4~ۢrӺ#f4m zS[1++Lj􊭥eB胘]5[ha: ; ]k$Zm*?B9 \{%xMw`sH?eo5E`6%G\\&B3TWELv7S' ѪP߇*7RzEj~ W.6_xԍ- 7˜=gma;JYY__QmӇ:_KQ]_.>F S{ϥG6~)o0m=i~Txw}ؚ+' Pti 8[㚟 *3?=IڊNpm^5#Q?;NJҀظQ œ' 4WTd܏Agú?[WJE~_e~Ӵ|JfuGjdYUXm6Zsk\{py2σ]O|Tu:g.Qu9YFpoZ&p ͠ä{dE{E@idRE C-0$Mֺ%= kĸh0xWTz ̴Sh%byvaUmE*II>Y]29i ]L d0ʀ~UѦ DiaJ&ia´f5 bU %X0A4&XLO $vAB\@YHKω!8 fyR2T̵c͔ YfG0otft PG~@ۉ)s6$ N[>a(L 7%s.~N,'߄ 4;eفseXpbe(;dBH3xI9!B؃$EADLX7@~bfY1Etm' h&F_$YAȌ&\Y3d w. D  H< BC9E It-<Kc?d,#l{* b@7LE1{2 ܥaF#(vIL, m~ ic(Pn4\^0J`T -@ Xb/na)ִJ "PŅ>hTAO&TXwv,C]WaZ's|T0Qb,〕 $ݚGNpo[&ut*k.t/kE8U~O[ h w^>[$67CY>UC}⌟Ho3ʷNQc1$rؚB2\iec8(hY4*/ R%[Q.#I‰*4MFL PbO{d)z|`kVJ:"׽P4(i.یC6GS=Z~H̖4B\jYʦup"Tl:9U٬x~;\%OQ?6#UXeP'$FsvLi66hOTX6:*=L2Un5U迓h`lrJ4Nz9Z,rVt7hC[QJ.=.*85rJ ܸ 8..I}kjuU@ys]xת,ޯ_-]KSU5ںyx |G}v,PQƩ#=*4=mB6Չv2rc^pS:ki{fq[nڋk.ZMmCIܑZ-7*]Ku.$%o 4.9|G('d-cVoqrs2C;ڜ#h[{DӪFRYbU$Ӫ̦Q˕.@rQ_&#Zj7˿E գgZ|jpU c!G_9)?Nd߃qfubr-ge|ζ;92#h^u0/[Smy,詺TCW>MGoJ;r|~*Yf{U4w|υ?2zյ-i W팏t݂-wH߱X)eGI+[䛱!z*/y:5FI=I'GF$G>4W50B#RV3Ypo>:9wW8JK||sR>kY^@YW );lrfp+,mٔ%Ug>Ip aT8ShtMkUA\RW:^ 6(j+kl'f&$9zJZ~\YOGuZ>"W_)Eh::Z|cOR[㕣>kҞEhr顇OWoֳ#/YkSEא~s7LC&Y+2lYi6 mɷ]XeRh,O-&/쀲b e6b AYh&B9E ALv f0K7dJ<y(S11nSST䄀c.dg2p@안 f&70L{S8@tth"TEi*,{H2¤  a<+B@ĕH)QRa@8|H䉏 *PFZ†YH*, e#O9H&K,hV` bd ېʼZÙ@dMJ@B7a|&&7'Dn@$KX?t֐rÁ|{`m1ML bv"fP@y@죞Y{Z.9< x@h1'p"/t2sĦȄ,LTho$EA@${1pFb2n JbM8T@\I2Ĥ'l٘1 ` E'`I"J1ĀBH -`M@B|:Ʉ"2~c`d)&=Q`Q~  ɸfB*.NePCXJ-0,7,t͒:Emxt5Uo2 ΈU6=O6`5_X{`HCLAqJt-%Tj=,JD:lU="^xǤini t~:\P͗hlM$k*.ZE\Y 9 3odJl:T..N8pW]ʧg=lmQf5GD@#ЕY[ :}:PL,aB-[ϫ;/oMtNѩ5X6' Y3qƟV#O| mtA> xvGj_Z%WklxGEPb SUZZ \y2m.r\S䬍\~P09Vj$q0>dys!3m-l|((A@U⃔Oz^4kTvޥ 3ds*itݜx+bG<1ܮݳє#rKr6~j* s,7vS['v@M;ftbNJ= '9dMrϦz-hR1M?] PĜ1b=RTQ)< 1,oby?s~)|-&} j=iQ*)mnd`f펥#٥\ܓF uJ;>G96!7l$ +mU-- =i.鋌b5Tf UPVq2A}r|7L1+N>P ĸfFj·Ig)tJ/cl 2iC Z{\^G#>L&C8.RdѲ+ԂH'Mu:ݸG&bRG:<ۆҹ-(-KAmkY3yo Kz:ײ~i46xK5].%jzʲEISȢD): >VWE7sJ7|2CrhNn4?^Ź,s>F E?P|_ͦ.dVQ`H=3a L9E'P0Kr@–e;(lNaC)20HRR *5SiOkS*êp|i|IM:Ѵ8+:,\uU%} YZ|Z Zq5h4 N4~9>E,F͗~oۂ-F-[ @Y6,;]e,  |>#@VJp-v{ f%&@EbLL@V-r-`ot:!$ 76lcϲ`ę&p\&1DZ( KIۘI G.;*@1Haܤ!a0F5SK5S)%ai3cdAVa0 bfO)0ťPdI9v1NRgKe#5X&Re*Y XъJQ,jd3T$ 2tO쐬\qH,@ adqh@\Mt ??TkCZDP $A7L\L\F 2 (A d o(dAta4X[6@~P]|`[F  0 Fo`[vHA9PB Ey@0*8&M.%bЙ|GnSe<t &8@ X)M Ɛ~cB:JB`[IN0E`B;hCch(?Q6 Y o`P`A@1*ba"-2oyLEX` Bfa-"e0 8L ) $!2 7NƒhlT]V:,fFP& Hd'f%c&2D"6(8dYhnhY:Qߌ pVi8dMIm=^g֤=IIxC#UiS"%zo{_|3K_OKLƸUmG$7LW̵j$<*bi9o$IIQHRo[)&d]fc v+E<܀Gd(e {&oXS2YbflgF|h]Q-A,r}9)>k]rCW2 45{ 4hKQKn M%F*Tԟ"/wU^sLͧ ,#t2=<(I/;?Ok|)9sAo?)Yn{mqRIҧMupTcET=*E *lo B2ov+xwf7=t_MTS,$sʳQǥ|g*-[pֈY5u1~}?DX@.+uQ?Uw_}4,)RHyig{heY_|FynDay m&/k+9- $Fi Oxlқۯ4Z479X.`.R_slq$㵻C}WC\NWL1 ʨ#勧4 .i0Uxc=Z. m3 켭l'!xܲ{ ܬ4FlHqnVu%NR8f:4 u>#H<*5;h/{@<lo GK|ٟ)]tdlߙؽI.;c]ZbH3w!|w%G^o^,XmCg$rKvK%+~?RQ|[uEɆ~K?T~GD.UA~F'$*2#+\ollDz֏Uh{s{ݳ@Q/Fi[9F'9!U O łYpy-˼/GSh?LW{EQ83Ad>'2ϥKTtd"F ?8h yȸ3sG M-|vQp.ER-{hQtp^NxA RK/N&~Rqlk.7W]6ڳk?=cr^tS P. l3.u<~Ѻ*ԐB4L\V6u:}~BJT<>OӆW Geզx=~B딏L&4/*jKA;r!a ύgyyc$ eV68 B\,ZKGh^`}Н,@FRE2'0?bo`%!`F8CmpRxP2MB*X(,. M)fT!h7h˭ЍM'1WnQ6}ޔlR;mfg =T2~||~A$)3lT2β>LfŻD<P@Xi&0EM.Y6H@!D@&40CA@B@c(b]H t~&* y9@)x O0) qLL1t Y% tYFS`@n wMV9a ƶ@h"cLK4DU-h*,s{R smT T{hV .,(St Cse-CTHPŒl-[xPъfJ3IdsYpϘ2$38*D%״\kA1 9@L@(iB)ׁ(At4@@QpD <] O@QM&ȿ&0>Th턂9@  (L( b-:-+v 6La HLsLeH9.$,_t`,dɄwJ6XQ Bd@>谠Ly X"w!D06 c`4&,( ILA,c(LtBP73Mt`E@VJ(vXl:lbhDB2Dh 0- \DO0!y(eH@s(`ɸDfoDl.#X=Ҳ 1e cVjVvUN2AmWmvdz*~_ q5}OնI>/YZ{`/wMk>O{FRxx;Qvju*p7 f{T%UFzesM|tg}G6;.yq,A" 5&!PRVw9 \|;d7ϣt_Oh۟u£;GQW^]]4ÿScEGg-]uW%KI7+wE1$,\gXQ9>! x[5rfc6&9|n*@i(iQa FJ|n+e&.k4p$%ž,7q ?XnHZ4^oe%t^G?Nyh~M̟^׵Ai(i`;%FMwhtP¿g67cry\njmBX7 O0rM6HSg:=2 vMFOy &|>X>SzWPG~<ƗH]&lJ@ho$> gSTA.n9Xm?qr| ZC|5\x L tm+"I 3ereKl Bޏ|Zua('"2L|x(nA:jL!nwfbUs)`!sߴo2svSd`,[.Rٙ|=KJՙXdsMS%Qn)+ J!CjN:%]$.!I:5H^vm|e 雛!gU}[\5}= Oe9SŒ~s ŕlFe}GLm&rYGǫ0BDvJT[eEܔܤ tZ,p&^lOŤiU6c켭^ўt|^k}; ԰T|\҂lrx 0z n]l2x>3tjELq,ўdJ'BCAXW4$~O |ƞ~%ܞX#Vu Mt~>l9Tf{aܔH >2a.Tc{RTs X ͔V\E,EQm7Gn Cm6U]lϯZPLzE!]>^[,~I{[ܱ8ɴSndݟ/-9Z/%y|38I &`Ь7N,AePb@}@Qd!DPd "cM#J1EVp |ToKLM: S&̉[ioh$@ p%زC x@L:@M@X2̚@5P `11 9@06<odLXvJi[T&i@T &ɉdvHTM HM92müJGehIr@JCLe&s)Nj(e#c6H kFJ̓%C)#5@f~7,LKN6ĠDg"@1DD6 DGlV- EFLw)@7"P"d !n' m !Yp" v@~=0Ja`ؔ `Zɡ",'q`p\pJh%l $q)nE ,0L lqhG2󄀰4Udm## & &LrP 6^(S a'(@MPi&hQkY!-{">=q onS@flJaAA@)Mc6SJ9 29_[K?Seؖ^U]s*I[O:G=TgXg8vs%vvOY|,Pkv:QA T)Յ|_&9>e(gb-AmKZ` K^7qcRMeV2EtXn.aD,H-Ψߕ Gr(W u6;J}Έc`*SkHuQC߇Xm)t%ϩ+'&d.SA\pMa {88T,V{mO0llfikhw{aJT4gMP>d95W^I2JN])tBKݼKra5*0as9:/klƳNp襅s+}n0H}>M ۉ%g|~vH٫?FA{/GI|Ѣl(򺅻j#w4!&%c&ˮ->YI{ #/ˤe~]뺣+|b`0.^~=)ݎ}od\>h\ɒ!7-q6+9|-4?JzcV[ 5)Qsl#UILePuV9b6~e).GT%ߖWKX\9˃+=HN/kFaLRkH ɉ6 Jg>am=5m9?3^`x!onȤ|O5JJz5wz5qDڄsMPDFE|Z~Bx&*m^S䣑>hS Nk?+O1"E)ټ21 ȌG{e*Vv3r Nz3ujã4%/ýWE?KZfo47|3 H1pdau?w(^Zd,;ȟs/`q5jU'A W+}NsjO8OQT_Fߧv2KLZxWӓBʰ9LvS,`8p H`JLnq&qb_$J??TblAdP tTLY&| ;0 y d${a 9@ w`a,=x9H H7K- sSd ;p, (XƴXւ BLmfp@LFm)[4S3d`="FHAm@xUy-AIe; X &~BMԱ$eQ6CRUJ F:bOu,%CTPHz223prLH.ns'S\"$E@"Ёl Jt7/i"$J e؎`Yi9  :MJO_"̴=7sC<* (6!;֛]ZF!߄FpP h FB(Vg, LV^$V݄bY eg ,BAd 8(c4e DY6$,Y2؋ (q\@ dY+L2 ;frI%c()X=@qd& L"2Q{Tk3*5Ic{:55ZK1p'gV(,Y X%EFsP&/ c5V%+/ʱU^-f-#}!hpmpl] "S'P䨜IL8LIF*,Uf ntfUA|$5lm6y+bH 0Hf&ftߚ,LIt1d{o)'2 $W)EUJˎRGEJThfO+y/aqQ4іu7KVG>S(ll)SmTrI> ?SfDX{UmԶI*1nc)K)\ y*#$o11+V#J. Dö-kmߺ %.`18$g龝uu'4,?|Uv%dv gOztDU?GQv%}gc/w|dJs>z3ᕶg2$n)%?d$5&p]wlSko2j.1nF̡R5m+8QozSTAq[,+g֭*]ǩiޏtS {B7;\C/'+Yr@Kh[3 m9EBW/}n-H7>iNT=WgJR]zfs+ߪbqe@yG^N$Zw]T=LMo蚦ktmk$,T5xrZmj㵟WY{,F3V]l0 3(Z QeWԂY,Yz?OaԃP^UA5:GҊz%;Ϙ!WНuM?W<$a1M O{ W;M23C|(BvI|}pB.^Tg5+ʋbqi0uFl f%HRXB"yJ`򥈇6R젢Rt*YH~R)`n):{vB\.\ Oh$ NM+mQEuHld, Uk"d 1$PY\(,2 "MT;)"R,e! 44udL[s;8 4(b1t!p6b S7(Y@в9(A4bA@$1DH@ 'Bb/+\e N`1t&=*>%#S&2t1 v6A6kcq8Nfҙ-`6HDPX") c bPbdPh"Z vqtX!&RFw+)jK-i‘*SG,%OiP3-CSe8) a ŲBVk-8@$e0I9EdFaQ?&T<@wnnItP;" H@0@{NeHo`n7KlPS,0 }U! `A ,e%`Y$DEE HNHMÃ~ˉ,!RHNٓtd$.tO*HXI.9P\) 3d { LE`2 9)Md6V19۰L aI6="H $;(-@`BX)`!A,ؘ@V0ltXQee&˜beM"@; eQp+ ("Š&<%`TI-%Ī@X=ƭnچQ4@/NOLO i%uSMjR;Z+0fY!wg:M\sRnŰoEp<KkvŸ=ik0 sIo5KF1۰8)(S{Ik :huZp짔 !R<o?IV&8WpdOgО7^͂iOlqS_>7iJ1/i2*H#(GEƲ<$#|y#[RRo-7F ͲBe7 o[n˛S{,q>6s%qe>|E׸#8_"=7u|h~9+#[N/?TRj0G,`N:]qkhlc˖57lm*M3KfM|E' fSc*;m&~0X1(z3Ӧw(>{g{fsMc&eG&݂ sNi/8W65pA͒Pr|R)7rݥsKҲ6mv-hK29-!AD> IKmEX\qD:&+ lѲ".IEqDPir)ɘF bF*"uz/LuMm- 㼍 Jl5֗G-jgGԯ&TtxZ5/%.GarT[>No%s䆶rSiqD1nvɦe|W +|4j?}{OuHU\.nIY`|6Іe)|nq{]5 KNcry}RYg*{efJy&)Vͳ'f.+WŪ*1^nЯy$}F+m7;Gtd1q^?,1favEF&+ٚ+QP-,$ѹ&mҳFiBقOW& Hpͫ-sSi#]Z朜1w#h1zPu7G[6wp,etM<UBvg3;gW#]ug?gZD;4f_?S"{d%ՐdEOm22:/f/WDrrꢞ7fPWAcCOW^4Cf/rex^]F>Sp4sJ-ҽfKz}'suJM4ϊUOX.2ə|<5 o6dV'Rɨ2$D.,o;44$k8dk%xZdm`ykW\eAlӺA{/G>NT/Aω@SCuXVNDqޤ:kn]*SG㲬>-4jjP|BJh X)#͗,E 5F{BP]lYxqae6x%]8%u󾙦9DG]5S-5XeGx_Ha;uw-i$ x$j(gx2FdR_ *hD5LjWOn_bk|e:M)`Ķ~frҽ>g}֯kd^l.'{ͫLe=[sdUt͡i3cnH퓌PW@YrGOLmNܣ)ki慼%eJ+Bg)|wrHڶG&%tMkHgТ1NOe!k8Y.Ŷ[k0ZAp,!s mvRܹ%GH#94nŌ$ZcY8 $IҬn;eۄ*8$d:G[OPT Z,{{-ci4j8n7M6ԗiO;|"^FFz~YW\J M0A$gL1.p ko錨LmjiARdNeL9Kv -17GD+'Pl2tĩbTꯗW3;f)9ʹLtN;cPr$hÍWoq)Ou3m*noq3+c}q !h&w}GHm7'T)p;$\r9Γ |6gJ5:jLSw=F#JW o$7\os%1+)KYiD\|k\jhŁXNn7 P\R.%Ty>dbӘTOدHSU4_RDbQ\";Kt~5:75{{l.k?GuGUSUysd9GbEB=#+.FBsp2[r6nEh SvV$RT}P siŕF@hx% Ox4"/'JNint%`򰒮@ "[dr'}P|yrjhre%S ==79WFM#`W̮6ۇYlk۰D>|F6\j2$rx\ nr~(f azZ8[H\\!PF兤 2WGl}#{^/dg6I6eJ1lMu@ 67"gvm:@/G C=7᮳uR/~/5?4{ŗEi^ -j_gN-!xZ[ T2Oʃf+\E,"۠k[y 40LEQE ',͋K9vE$)Όb\@(N1ayAHYq&@S.n(n8)R2`L *BNfc¡iY#̪Fch, І6ҪMP i7&Gl @"Њ# ʑ,g O0 pcPY`IJrbǺ!xL>&v!&:DJ@ c+勌%cH6M?nQe3<%b uH .-qS ^e(Kh7FBQH>G$Z)Х^MG4znƊY(eWegٜ#T_Jv8O 44D cݣK h-]Q61tʕ C &Ȅc9U{^-6xEѡ{OaJ2\BS\Ѳ;:Np%mmܜo%|Vĭ8ptٛRa}͑ef׃('mJBX`)K'ьxiKɭzNnw}0 n'FC~!iy4{N-˕ڮCD`>:Mrr$ڞ%9Mə.Rqm93F4-6[BF=.WFVTJؔcI܇N]Ӛ}Nnl~ VʸD7N#GMm*:Vw2cokdr K6`NIB P]*oq仡I;- t9$0Q]Q,5Ō8+5*tlHshOtFhįF8,/EX*ٌ~?Y_ ~(UkNɒRQTg'E<`vh8Z({-ɟT*;mej ,t)`[١!tm< VnU4t 7\5N!n-lHM]UW$NI)PIB#,sn٬ǃYmGSl$}F9pQO.'|Dm:E؄}.c..+Üɲ+pks  dXVqe 4;-&^o˻/< f~INuj$Q&rɃA%aWAt^ό6L=eY 5 Oi,O[k  R}MR=Ӏ /I8')F:>7\JI}N@: 4[tĶbV(tj:WLIZ%Gs4hH^+MHt-=Xxtۈ0?Q==Uɤ@e;H \u/:!|mb,ٔNVl]aQ\L-E9PS{J.=Kϩ,J̶fȕ #f!{.H15RoksLخ]ڒ}]aKFw9.@@ʃ)&"݊'I ¤@"ʀcIt,@))h8)%KbZ ⥔C?HKQ>a!n0Iq8@nP;H&p @qq[p&y@ q9@?d ~}OHRؙ$d\vh 4Zhi$~d٪ *B5S&JG1E'ByM!;Dkq y@., `c s2mQ+sJ@q >y$ y B.yTP2TnI D!*R5A1Isu%#5VBM Afp; $ d ' <&؀%;|$pQ*ŰdXh~S!Dz`ath' 00;r  Q%Rpl!@ (< d H Z$L$"?Qo#@!$V&CYiA6@ź@L@7H,v@@Xb@0bF%@$&06"M ?`ND̠a7ϲ+*%'Xt [ʤ#HTb4)|$,D1-P ?&m(Nd$01n,)` !V\y$ l 1' X@RU\>7Zo%M. ]BSm$By`wcD{B\n Mm`5@i*LcMD1 H JBJD ')քE5>(ӣ#c¸MwGsh*WW-OꁅC)i?(ǨigT͔u;%qfSV!Ns\!k.ӎku숨Oq6L:ZC&Fz q-5x%Ҥ\ A.’nhH-}q^H-iW,/XxqeR @fU:HlE2&CI#P >SvZoNuzl ;R$4۪dԾ/s No:~XuGQ|$F3`:tgZ?y5dm7Ub{!Gp5h4#xÝLT]6J[cǻi >^^1`TO6Q,4jl} IΉ]rmAݰBtQWV>jk*w5:c>x#)ERTqa7+26leIljd4G$f EQpr>hO2˚Z'Qrv Dž0 /X\9ҷٛr활w{>vٕtUZ |6 )I[c킝] VA%ty6AQt_RԷOdpޱzkt9֞;_ßLtLuVGu]DWy#;5wLѼ?}NLR]^ i9y&ϲroX,sڄ47ⰻm\H;6\rW:4GrA@`-*YA! 7s5:FJ/}+${&$S[c{F:cDFRağyS2MJ$LrlSmDS̛o9]]/u~}9uPSKD]xr*8=mETUkl.MO[;L#=XmѤ3Uл|ONH%xPVȶkEG{-{cK~U8zkڍAm"2]eU_;Rɗm7F;e^F҉y/|o$nlSѴ 2 +qEL^~wטi~853%O=%F3}^г|7=EA_=%^ZYT -Cl2;#Gʡt8 :Q{-;Q5^ nWe#NV4ەL~A^ƙt|>-|}Yɭlwй&Mn*tJ|/3"#NRDzEo[C9FQtQ}uق|i eur^g;ߕ<Mg³R>iSg©Ozj3Je]PNI ^l{_e˕Q 'p!r-,}<1bW6u|`~ӕdGOGPoKYۆGJwPڬ7^jY#S-Eۄe‡Xr,IHL<3Ћe",˨mZdԠ`8+Qx2d@N~ ~1.A"x0!$]eLHEl Љ2qe@# pTIaen3sBq l[ا쥠LC)1.qșPŗl=܃*XnHԱ{ b&R)1gL`VotPG`8 Y'rœ1$"řlVD q97aKdL[Asp՚h28 Ohe^1jqg^ЩZZȞL#vBҺppqlfMpJiti>~ieqy/*OYO+|)fL>Al "ZJv+H»5XR^Cmzv j#OCrN֕4E_ֆ*METHf;=QbڭK%hpp3!OsVTkTkF(ͧLYdkZ`ZpoJ/ZB{[\r@ jn}ISxr| Hh%[%Z1BA+X4X5J.|Nm|jLMŮ'iJQǒc]d@-eMP;HrNĚAhlP\jt$ޔ`U=3Tq&[fԧJ[ U%8Ã5Grl唛v=9U1FOjp.ŝ 9rxnLujt,=E7,pqTqrh4#=c7WQL3q˗:BH2]%rlNYe[LlhTJ*ضRu(¥ou-=ZN /W.YI(+Ge]3j*RCMuFq(gUq{AeZlc\e)vϘL(hXwriSⷺ}#żrԾCRBNWFlTFwV y2@^eߧr^o=J$`'6ٜ?1$9ڌ_=t։]xmGn,.F=3S-H8JFJ+abNQ}zx(JKBC6Z&L $L9T䑔A E4J|*K8'v7Bkp6YY%hVqxڄ۳͔ڑ;k /g )y_Mk:v}T!/=g|GWɲ,"kF$,oiR8oH]!{åI L0na%<*FcfiAD/ A.+JRQ%ΉK**%9_M+7UOvBwrz/G֟Lw{GR9߉5O2BK@OJJq>O9RT50weE6^].X^u(u"MAt#=QZjMmf|#)2C0cUGqۅy6BzΧq 4Ly)8DJcNRTMEǛ# +e?\>-^~VfW,ub„4Tą>n:5,$nݹ]W-2,p'=ׅ}*o|>GY:mM .nSQg\$VAZjpZ2T^NOk1| y\`~/܌qc*1n4^.0f$k%3M+=3Մ#S*CsW&z!q1vS@5r0; T[YQs̖ɩcF8cu G/U#<O1E;2j h6ب0H (M&*FIԁ&J$ϔR'0IJ3*%|T\]R d*AE & $}ONIۺLh^RcRQ3rmC@ Ʌ D(* s*J@O 2 i t 6rGo~.4g?D<S2DxI(by=Áx D,\!H'iI )r٩Ъ49T5SVt˕4@2S8ʢXb#@iNcD(V061–2-*FE؁DZ@Pi@žfOn2h& OsEj Re$!;8ICdHfw$SF Ib(2~蠢4ZJLPQaNnE 5Sl ]5`P6Ӷ.'_ dR,FhLQC(џSFsn(@Y>;+: |%DDY!Nl4|Pi ȷ)4&8 ײ(M~)Q| 1"Pihh$2XbdpRD|dѤ4XpbZ6([`X aGP SD~@I,(->aCeJ6*X$V2Jƀs) [EF  2PI9@!Qę@&4,w&p&`1𐋋 ,1)lSC m4B LiHXRRB-d$p2@[ @þ-0\`&kPtHRmnr= `2拵kx5GnߢF \74p|ycqgm^Dˑj|JMs .Jz 1kۻ$ bimɑS$g%3Qœ2! T#kjuV:6M%|qT4b..uq>Yrdb%ZҥEFO$> mr\U8[;6W,q-0%w6QTOcћ(Ӓ 3j+ oq=O)tYk`<̤v9yJ6K}ÒvC.%qt̛I3 nՆoeFo:JuHId_S/U!B-q$`Y[ѳ+j{{dc\HBNТn7liK V|l`ƈ8U()*ESG: M9RvO#,mu#+ LeV`P\ .Org:Q˕#S[=?C;xnIshLp 5}V)[Q=Q(+ԿC #sy^_$&dNiJܮGt&+*eD=uR@+򚍰QDdǥfo$gT_fWE 0Z'HӤ%}lu +Y .u7X7'CcTZ-#/|jz/WZ늭#xzi6G#ţ7"洏KIK'.K4O1jW̦De!M0W7D+SNn.xZ'$~Q HN{i9IOO68D/z1v[sV ^c\TRҙYOhunru4Β7qpy ?S x1 4R`H q&/,691.#Yc082Чf NnIB@ 0&ࠡpf((@l0Nd--9E["D,;Gg_R\  &Aw,VٌOeDM6l&t7 &"53Z!i *f QD:${AcI+YH$H^H"$؄Z Hʒ,qaE`Q )S-ǐyRSw"v!1`’Qa" Lbذ @[nm4/ia7Ae@F3>PGL1Bfd5Xӑ6M}:g(Ƕʙ60S'Nт"l1DXF: ,Q; 3Ad(,Ae7T lBGR P@O#yEJ( 4 $-ԇ#ꁦ('EXR ge#n(nhNbpнa!i@" @X;@$91ck T@Yx1d2E6md ͓!ipcL`X|&0 TV [E|@Er :1 [^H B@ÐF9HT8 . 6@ uI guLn<9LdH$Xt"$Q@EQZ`rO@ u1`W/e2HmQ,"Ab.4͓%K)rqID.Ri9aI(`>( ҁ.o>HEUA iPY[Vʌi6ZBN I*|*TO5(`>M*g7U}JNi-TThX%gNQďG! J&h7FF:>`Lo|[j1i'-|FqKL8M+:c}ڏ.y#Q9msfIpM-/7&Vufinv n=끏a= _fLyeGub8[sIo*Y}8N*8˜%4^[lK;`p6RS{lj4u[;J+;K>F~l}m U5,rՕXv`>"vޣ.e(F"Vcs%L9r[4w‚d-1;GN'-W%qӾe5mJѡhZF(I| +4m`Oo T}M$( ۵E)*B]qFnJ=k5<.pѱGjJ.XQr(-p') 1n5^B z3>e#Hi%R.s3yUNOz^t*4~Dq9˓φ`ʍH! u>+k~uh6+ڹ=kN<Ì9y}3NZLLuJG/B2ŃBfC OHe$"Z\Yr|۲S} XIJ&h]m5ōҾ.<4mnZYBM<%Wޯ`t8ev;*? Γ>v\'Tϯb ,zoV#HN5d5E!e.Gi2Uˆxhe t⛂NƏYwIީ ۅv@{bsfr& ]{cL`F-ÕfmV૆ag6Igp!;/>3cy?jqq+uH76N,3û ͠ò 0 AZ9@ܠL-׀D>!QD7@QBbR |Z $!P\r!4Iꐙ&ODXT +w)h9)Gɒw!^NeBR r8T0 u )\KE y]C`-O`nH g쁋stS ]`&PLdV7x263hTCI1 )FRb^ߺCLEFO8!4|.8EaNd4焨4HhRn;i(,UJc(ؚB(isoX4@ 1ny?L g2v l&bId瀐-sLheH&"`Ka WYam$"danB`\nXF6: )l`@:5%cHPB,bQKcK)C  #H,jC<?d@NSXƷ10m"$L,rA=@, a\E)EbRmm$&,Ue{ dc(E$tYKe7HtIPŻ \IA&OӅ, nn9H0阍LT\fAN1^j5Mk@c}QxWs#V4+$}ʕiuQ}#AGQQ%8v]\يO潶$15pti2O¨\{]]J6Z9)F)4C1 26G%Y* ݆ m - v+F8M `[:t✒jtqS ##X>.k.ɴflIch+7';K49xZ]J( Y-j mG2{68Wٮ=\۶-mF4vE,q߈$Y5Y-eCh[smKn[pvNPTIܸ0S-K`1f6 캕u ˝ԴD1f ]ʷI8s% +T>$4q䔾HOsR8sfY&Lc#sO)1QJ[?+I Z$CiRq1Ӈezjl;ŧ]5QkI0 ԏ*n_}?iì1Y%h7&w>[[:ێNJs{oѴth8\SΛn[vB Oe"FZbCP8l5ГH5Zm*2O&M]QHf9JNlCJQOxo7VFIv-K/ʗ9drc>0eO!~ `nj8hEj5F2TXĬcO(%.Xv]t\*lՠԘ{ ""$rZp/[qcK,׬١qCxqE;%::~uv^Bv;"Ns{O[+3}>۷7c<\S7[ҫ7`ݭ' ʏgvYmu'mBxƨԝ]/?O} yUW4;9Ɨ*7dK,EHSA9+QɥSM88uIs=Ӷs˱et4>rW/g+\8+ vܽ)93X*B5y Wt'l .u*<#_1RmD O]N"gSuwJf?T&ٲM$Dp>ۭ7(*KMtS^Mb`̏tWW+" 8icF4'=Rip"|o6I?9gQ#u,NX_F`GaоNrA>@Ȅi[,k'E]FT̲ kfqh}'/KK=5DҕvirG%-YWۚўnRvׁ+LR.}GVdd@z9SVޟϧw;s$1*gu/UL'R #~2ˍM|k6)b*6y̔y25sdW" hr"vdsM[kWv]Lik]}*;C\AZΚhٜ s&9$pԬYl6:;GLXA N͓*`uTgig$yOE^)BKVЯA52i8IxL+d:aN̘yHiqH`&HiBs@s@g3@B|a0;&QRDnL*HTKʤ"ʠ+U tB{ ]0\"#H&%H $!CE,(IT7 cn 3FmeLۥJyIr(Iz:sݥ 5o?ܽHI䕟s,=g^Ft[A7 M*n (LUZMw46!mKmO>¨ >Qi$K?R1$䕦cŇF8=B|b4E@ aԾΥ+Fe!dM$ocV#dYI0$쵊QGT#k8ZmWΟTZ ѴiݴTN=[:b]{*|"M@FI| <[BsCdj%GTݵr)ӍֶA2u!E)lv vxL&ySH~)|j4 kE n[M4`t=]xW7wrjkYZ WP3gpJg@ng7a6M3]b߼QM܉\ bҪJi_" %oNqع=CNSLְ ܮ8RX[/f9>=X?{g(ۢ͗&=>N(zdOY*N$7ђrK7$\JN\toyi<'&Fs}zϏe' edTΩ3BV̒rZˬ_eR솱 w)94 Cv͊mγ7CJfO])9f /+7lVK*\MUQ 3ソj\Ciq8YcϛUNT>CX87&#Q|A˓,hi>[EZ{dggϲ b(qG['eR8ܻL*HiHI_Q6r K {4WEhxݷ 񘷷#4v^MW,qGոǛ#OhټOE/s;1];mFM)JjTKO["E'Cٮ$au ǒG;|ڎtZf~ [+\; #xm"R:@t>Ubӛ#Is˗&;v>]ytn>\χmBْ?U^O^JmZ- ;?)6||G7dClڤ:.qr[T!^lrW5LqThhӶ\V#h.]u--z:` {Jmiyl}UGifiυ~?X.nׯClN ;#䪌t&Q3ƙ>S.]DEN3HG;QN۳$~P>RW=q6m7*b]+lPKŽeB:9|:jgi; ,[ogKQHtWq{]XCO/!`.!Lbj6 bj,&r.V?5D.y'_GCE@%zLsQ퐽9dܸ;SiTۿ/|oəJkYw.Yj<!qYIG$$†4,T2$(`з:HHrqE]T.D `8@N Ϳtd< 3.d [@ؙ@-LLxH -dLhHHߪvi fq 4 fs=ʴEi"Z%`X,{ TfgʡaOpw2yR)cyRQ1hϔ&T%2TQw@/4}ftt Żt1n0 2Ce1DMXTHЇEB9Hb.pTUZq)P[t ~P!i 45UB4S$s)3C)N<!Y'!ZDf 3cN UcC$Z,tPX{0E ` a4M( ,h 4;) dP $턁iӢ4a*{%C@:m [B&P7hb˘?D4"f2%J PxE@ 0鈝tQRH]6` r]@R(eP9}aߗr=zq{cHk&HեSx4n02]7%t8=ȲAוIlk@DŽi\ySi|HS&)mN*Mb ֮wA4|+MഗQoqZǃxɧ1 -ݕUxcvY'\#yBZvL%\pMrg?qq# *gv#]PvVBStmB"8^#t~q>V%FODNl\sL-g["S0,2j~B)s`'BEna HLcF]&ӤPUݪ>2 {/c j #h?{>3K)qƍ^V= o!rn=ϓeG4FW*Ïj:$DK$9+>lkyb꫏fJ7"Ol r?)Ӱ9whoEEu& 5ѐ4Q)wץi*36qt}׫c5ߐAO7MTRጐ}(%fS٥ϟy{Y`.(v.Kl( A9MA{i .͹@Fҿ#h\!콿U)aWwȽdb.6]0]uŅ @s*2(l-̷7ibhעx1wT3#˂oMYeF5 1+N4h.cz)[/gfVO"i_>߉Zgȿ:mJn~d|yD݇M`9*,*,6/K9F NaH&˒HJ]pwAtMrbKnW%!ϕj*R4fnuQَCC 0TYh {v286ht+ױ %|Q^ ԛy^F9Z?`x28ecl- ePad4t @Q 2@L)D*HM$U!6 Њ$H@Ͱ$ŗ@T &PLͮ!)CcH[!H8Hż1s2 &.2T$C /aH s1d O8ISۛ7q.; i &;(EL CP2?i4@@1< 1ǕHmH@DK33W#cD#3fҙ4>ֹd1.I (r3ʑqD/ P%|"`Ip9T$ ltQTE Yd'C bqF%=԰Oh7Բ%ͼ(b/k!H O1ap7ًp`%C 41xTM)0DYY6iRDhk ZKc´ls)D69YU c"a|1fBD{rMhP6Ym:Ad, SEY &9)P6E &#);(S* -P %E s8tPK)̹;R%Eg{(S F!&9RP6M HȾe&l"lX`4&+,c>PH@pH36>BĠb˧<ԁ{dA0x@2@-dP!d]: A(aP-"a54CaFtD JHwiBFzk PPP:s${0ۧC!;rZTN y ^ AA4A m%P6B@ (D=@Cn9@)e .7–Rc@0H'`TbLYE20ׄcLeC ԊO 6;w3)XE¡?taRc:*96¤pn2{_Ztu 3L?QgUً3CMM77 `kON\YsO5p&T{ъjХY柆̺,;r5[h'Tfp_Me#o :%:v4X:#^o?%-o%:B ab$Ns60*RrmE-ŰK&׸}L5-" = j$.rRuG{vbn;ڣUGܫr;24G^HXo)JW#M:Lq1\RgT1rǗ8}ڤ1 :L}3KZ6F]j+o`#gy~;L\ o_&jՁp\SO?f+[qr}-&.WN4*f%N| g&wКþ@$ta6j3ը.&I.NY=%J%qJ{,MFxi<,fr[ZM$.]>X5I;\Bn"No &$ӯ(%)թJ7y"յG $9rj>RA4EɮŏI&U&STM.}&\2vy:;ҭӝ&tk?`I^cXY?Z4zZe+]d暦'Qf:nmC)6<C>"|b1[7 d< "@Jb-  JE;0Q(v贲eM._xLTrQGe0$I_W1?4u2"Xbsg ƭ$r\NTTtGi{!VTs6\#)IF!u`Qٽi҅3ۇOtrdC0]ж6jrb;uX 5K!ǒW.\TSlۧׯƢ3ejp*咸 ˊnMI^أQem9?-8p+ωO,Zs}lM.-^,Q^{:F,@UAcgKhj5EbKy~;r&ςVuMZ}JG鑒RBZH0jB[.+҂S3xu ,2T9>߸.WChP.LsKu#4-) Lզ&^ :qLWzru]]ptمTtZVke=R+Q$8dNGel1AhZ8k0s]Σ5DzgLm̚ip.E,:bp k 3hcH'%,Qa`}1i\ĂnU!2,AhD{J.l.Y  $!XyQ1yTHyMΏ@O)c\͔6P$MRL>ls <ʆR{(euP1DJC\o{CmH "Bc$t,R'÷Q@Vp쭑¡_ vE ?#9 `9 |%CL64P}#D&=VƑ Dǰ}KCZ#YcE1}  h" BLd17!{TP׼L%AbUHF 8TA(&bQ$DQS%P0L bn}8d K:">EB(I)3#vBX&55So2GhM4}C4`0![LXr"Gd!h,{ U"SeI5&50tfɃt"R$-}Ǽ PZ )el0H@JێShPɴRCnhY* qT4%88)P { GZQCB%H9LhfwRa" %@L%C@|`0LTH!>DBB(!L%ϛlP^fЁh"-ћ) S%&0Q,-))h RFT { LES|+ *C$G)h!MX0bhVhmb]|E#u*hNGBT6MF"0Tqɲϒ1ڟGC-DOn g<2n`u\ zFJ5BhG~$H=~JHZQNM d[o烻贃olMr5}&kihX,Vx~}F%zۺ]MfDž\[*/ 9K/(kZ;`ZTڇ::-4NSPyclB@uͯR\hIʺ4KQb@Dkw/MSܾV1݋n/1uwulP Ty.Srki9l#0ǡwWM܄kRs͛* cEӂ1/Xk.[ȟ^9YRtsF)ڇ<꿒eR~I%IV1|2'|35mQy,2r92frb3HnW3ʐhHORlzr;yl_[\ hS5 3mWr +7J˯^YK &5\i-y?64+.+2Y0`0qmMvl)2`9S0rF/,;!&,cYI!ʴ;.EnjD br#g(W"%ܤRAI踦6z[q|LgLjU{/8!(x:K8GCGC{ĮIҫS~6#H^D19ٔa|xkx{EQec\Q;jvg%xbvh6Rߊ{1YrD}B{MŸY:,l+{m. O)"hȥml\q$|džd .5F Oк4!-5M?L,R!|W#D1#9#=FHK8q 60N:)DTLt6tj-33jdY32p}&BN)Tiᚸg}::Bc w. p<'/CP Ă.U Gj[:>锟{i]O3j$of:梛Kl-Kv5g3+ɧgJ;*M!1Z* AfK BLƚ,2Ve\YIPmR kY=ŝN<hק+Fr4U6uav^ە [Ԝ,4d R4k5,cGUş3]LH`v!#:.@7@PQĪZ,@7HD*%2,\]R$i ʤ%P2`$eQ YLP+Y+c;xK >[(SIq졲вI8xR1n$S`,Ɍ$I aSY3A# l*HI1 ,|3qE6N;K20b {4IT f"e:p X"2rP9Щ!XbpƱb1ʴHT&1HCИ`MH@9HCZ9$Z~ ʟLv@ʖ2(Rا"`peErEt&U23b ad$τ`Sv*dHCŐ1o)e!n@ tbO& 1 * Z&&ˋ ,lA C;hjV&iceh4Ul}6nU45ҩ ʤ+B 9Jb>B"~10!Qoa'*LLV g!nP+Xn!LS,v%$a"3ԧcl 3_ɐ 4&6"RFw1-)sD Ŗv J@_3td 2DSb!xƨLPnv'c!d&bN9@h"ekhem%P6V42"l%F&mR.% eXz]C^LvSe&;{Y42ؑ` 0CDLcb0j@9fʐrP^Ɋ ZBl1$Q%A uP1Ftc)b!"IR4&9I2P3d! v$^{ ٔP e>mIH01a et-2-a 4S@ t@ʢʰhr :_Kqke9gx(5#wVPF6)sW$t*|lsiTI֢߸o++@膨։?MCy5H\W,rj`Ev2ܸC[Zd=MVH(efa ʉ_L_T\a\rG&L@xRmYy3ju&e>6|t*W~QQAn`ҭ%G@tHk I9+XՎq#zv|]LiE&5pIܝ+ڭdIE%9I\BȺ (h)/M|#MĦl(h7T+c&n&"Cp բ[D@^HhQ7 ?QγGuףQcC2UFz4'srJ8':=.=6% j5ЧBwѺ,{bT]mC TR*dXH7Ty' 79[9Rr&3:%,8٫n'N{7:1B\Dh]9ĢN^Da|t6nxߑlѨ)魥(-7WLѹB- ^k6n}.V@ x UQ8NG4s׬/qt{ݴ Q9UD6MR2mE59T(JpIPalG/CJ1-wkݤ\(j3H`+4H}WVfESqew39vn|ԣifMCvWl}$}4.|qtaҹCpI*HɾUي|U c%QI9&@&fWi: ثxxJ>'~>Q 4;b~q0K=+'uJq'8eV~^P?r|xs͊KR_ARƇӨEy ʪ#+-D7{ڴaH0G,p%W<ՙؒ \QB^1PZDXmtV9ѣVzߏ!$.VuV5 A)]#Â;6diUcYvpi3 |=IfZ^G,}DG_x8*\һMX-+? ,1{*Lh0b '(ry(%&d*Bdd qL r>Ј D9e ]P f}JdN bf$R$-O򂅻KcI3Cc7 B\op`8H t&YH*Y@T39P(dD@H@t p S *2I A Pd vXP+/ŐaL,te Cei&.P; {cO+k'p_ kGeH4,0 B h#gY0 H0$Rl /"D)e^f.K{$$㴤W˭tɲf.P;(.byE2fI>Ɂ[H pP$NRf@I†1.=cB*J &Q` E#X0c4Ӧ-ehj`{D٢oq2Ln,"M l9M+Di7L  b ;J@Co7, FCh=2 @\ `T` ) ؼZsu#~To쁙3Rfj1RRy(e%͙粁{I@,%Qha"%c4R,@Me `X(v}C2fDgT24hLLkZM@k; LiLqM N0 d *%0. ʆ4%σ ݖlaHhBf)BO8L`LO: 0r>PBB0yqV`DtcHT,"!T@ə tpś L(aHx@ q(`@$Y ^-_`84dH@ $@<]!/H`>D(s !X m`?֘òe"Pۉ:-CFXK|GJ9:EUAB՟hu8u)N/U c&WT#pTMJ;Tk)\TY>H6ISc#)&g|D%ѦFEM *qE)m4>RRi-2_1!dD`ql8: ' Ĭ|](Ή]X<ͱ9+f7qk[0H1!栢6r߷n䱭&;U`56r1h+#@1!R+*`a_eQ@6Jˎjm%MS e;+sOOQFW-,G@TY(qkI )Rg}~,JfjHC0xǶxz4y=u:xm󧭛~|I]bCit!d-#,hu?k2tQe*Cm:mor>{?Ϩw9͆' mbD,B(, _Bl#a%KCLrm$ n`, ($ ĤPk"D0VZ!-[) \lps#WQecBE>?VZ"/q2,(cتGM&-48|,QrSF=k)K+.G*_=ou##״NT2a5WMr˚3^{*~JN٩d|AuedF#E'/&jI+Rf+ F).zn#+%ɃJun-TC\M1]X#f."PKA dQa7hL7%_*, .lLR$¡L@ @qc\?-ā BL`=CwPKꡔ)O*XŸ#1q=Բ3$ HO̊ĺㄨ!9:L`*Ha Ӝ *B 0'B qE )3:m";LX@_3(2|(VO{#hYFL 0S%BaL[!0uTBa#誉e %"Oa w p-LXr@9JL`wHhE0\ '% D@ɺtnELa._Io[Mt@ .q:*Fi\IvY62rviô$-cՅ(a{+UcqYocDHL`vnDg6| U÷2痞z{'ju5vФ;Xd˷èGn^wW)4\B=r|&h}?Ӹ:MW_u-F\>_QkڿuffSh,><=Խi.yHy.̫X3 %ط_e$a)Z`>ajfJC gBs pUe[KeDeYA@&$X6^P  D+@5AV8c eqVFfj>)=F},\#Ie{JGA(Qa19^G n8+X=\*h4n+Mݳ X~wMYO[@`&WĖ|GIP· W. F7xUfI /3j7M~[%>9&= 򴕶9m<#۟+4J,,qJlQ7Qq^Ι,XټL>w96GNVNѼ`VZ!lh\hWh=6M:p4;ͨ\Ye\>Y=;M[Hdd.|zgahz'+5>]7Q B왲[e(' 㟞{DHj-ؕ#YҲDk:xfp$ I\>e)X٥֦ێFW7^f^̬զc3j/'Y;&}u$%L/D2;乱\!H4 39I٦'meˬN2\0S]_,(IŏiqRᗍg=J9dc8m1>Rw_Kqq4|ց đ+SM]AUjVǑfbhAe/ O R>ʺAT$i0VoteQ͓<g`Th7X"&j q]Fyn]3] y]QՏ% ZFWtrVwʆ7Q|(!g)ٺ{LWlr5φ8" E+tMݎkf9wi{pˆnGv=n' +ӻQOCv+W8~QtL.d|D\2&KAAA؎S!haI0D]Z <$Olh 7LtQw9M,L)Ny 8L) bowPKR(L}p {DJ28DC $; S1r!X` g0XbP^eMeI/'Xxtm*q@CN2 0aB)-dg8)P)c*d-&0 G (&UPft+$ 0D?ddl@D@q3,`Iq$~J)qd )h`81O*@(HxL$pSCD"!L RtrstX 03&QePb$4yHyHe a7Ic[hgPXG=X¤&hgZ!=$&ㅪ!M(&Uh͚s:0Bf,}ER*o BNMs 1b N`T3tP| e @ sf 3H)HfjhRRf*b b۲BL\ \&=D{}*m4 'DDI 6T;*Lu!9[7( ('RƈM`Z/ !n$ )ilAAI[ YFnR3Ut4#%R)Q3` *>cl! {+1F߃*7V)uȡnD^2!orR1o1Ĥ1fLX0쐆@( BT<`HpA&,:$w MEѪěf '@kk,8LE4)^q)1,-㔊&b `ad"~҂Rv֠װ DkXM]P8pV zn~M}Pcm=?Gfx&UE֓2Klm 8LwX"I5vhZis`*άmmY.tHɲ;Q$m"Deic :KaepMٶbGl5ImY;IMvt<[65Q펧 cO@n-UME:L‡H&xb:uxI'>Q\:̙>O,GEUj5R?7'pҡhk >fmWc'#H7.8-L:**8W3)rBk|W%lDx]TKfpr!ou-/${J2`+DH0 (YP' ܠaTKL74;ASCCsS@9H;c2Ѝ]zzjPh$vGvK-VU f|J,#.ηN]}f]3EE{fַ VgzUN8Gf@\ 9ʑ]Bd4p$x&m@o ɒuZg"y}6:R9WrDl4WC.K%\qlm L0*%r&:5). 9 INt{;]OWKI-dx_y6.huS ]9䶣Itd /5mاe:Hm0$FD،Qt>쐺%FBKW,DiԦ4"S% .<T,|Z9YyIMx)Ęɲ rL&ozHZ6Uś 8+FUm7^u7$R6MI|:S:) Ǎ;4գ+|سeM> *)we)Z+~)L[+7xhoV)i\hj.0Bt-1S hLR%M:ح#7|yڲ&Vqcij"ĩ(Ŗt5BRG|2&ANS!$]4C v"VnZ$>$68´lgM P&&UnH@ Hb\DX bѕ,b^e‘g3PPQx쥎Jt* h(ALVY6 ieZB`uT!lª,-Bt4^˥C|< SvP3EEҠ(Ғ$JjT dAd*X UBgP,P@<&"E e )I4Hз6AL|[Ks) ͰE7ED= IE7L`H28x@0wNt&mrppƀ.$dq"@@m7I  }!t ^4SuHӼ]Z!M1&,U4Q6hga ,6 cQ&;$([$/ 8R T&( R3S@ A@rA@<9K d{!LE#;F M 2D)e!D‘Nd RGED)M!IB(a)&B @%C >&|w*Ld!۴ LBT&IHA"FKcCL@H?i m! [ea&Z@#1Y)GXH)PY)jY [ X)YeRM;x? lKP"HLkZWDpSR/KTQw+,"ĸ'> [’  EPb<`J s/@7ϲfA(kLI@b63-=V8AHDbȃ#I}2mMat FPRD!0nD.AMã>u֧";!.Bsdʧ6pmrToR:!$밿OJ6g*8K|15W.8hf!o$tN6D@TFҕ% |WK'Ϛ# * >M gp4ʛ +,MYL^iV9EC+RK 5dwˬ!BVFp,JU0wJ jF|8Z.{WqKf[uq#NuZIHSl:0"𶎝7ӽպ"uɺ W7C˨bU2fD CVT,]V| x2Ci mX͖͛7ɞD$.w.AiX1|29IRQWѡ9]iV eRg^#ZFJ&Dz˼hIp@(b bMQBɛ1N7ʖPT0 LrNT1w’0|㲑60 e -}L ɱ' 6RAc/|!´6DI Ɗ`yNP1JFAalU kdP FY6Bt"8 P솜PA` J@ˢ<*>&,,@[y@p9M e"q&=C L粛d"3$Ɖ$% \O ,^P4`!L| 2g+ +w3$qsNҀ#p2$0MwRRO pod J1C t!$^.-dM-bJ"$4&DC4SդMVls.쨁B 1c&Ȳ(\e !7JTi` VYaI A$@]n6('L}f%!P3e#I-ֺSA@<-<}P2lHS) Y) Z[y쁔p(͓@T}e,c12A'T #ي;BKcˋ&HaDĠV1$2t-׷eU:Q xYRCJsevn8Lt x }ҲSNTVbݩq09@h>:5+00OsҞhmG[ILQ`bˑ>cGЎu*dpVV2(QVnO$1ϑ? Ӆ| +ŀe13Iɍco +w+QTlobd6rVR煮 w5~As%Dl..N~pD2. |Y%EYx^r㓟Kq' Ârh=4.HFmU=mo&Wl4&%glHxxq;gLelk.t`"Uc [ۍEu@w/QaBl:b \If&LXaFf Crqm_IF7(*k[VD9rpN EjGez"}ׇ ]3i )i lt ="tCL ihh&Wj#ʉjUXXfW,kdȅDاKJQ6[m2D(R$V-QTeRє5F2oZ+XeΨeS+ҦU' UخNx7gi<%#[bMԨE&ÅWyEem.#T-{H؞7kg; 61عI֞HT-9Z"*"DLUtP qq 0 s L†PNAPY`-ò@/lK,pD E԰+`%rU m9< k#(Hiư@Vk c/#A T65tLAea }ӡGB&VL}C!iC@V# ,~Pl%@SEE6~ɶ"lS\H@ęL 1d )0`rC) |b!IBk `x$#@ͬyI$fC@܃`@taTd9=LH{Ɗ/ L1e$ @',Hu 3s0G0ZҚ fbDi-D)1hi 2,h ћclBk%"<,m)I (T&:$ Ĕ,,2ed Xa $Hnm$ t̋ bDrRli|eK*F:@$n;?EFI&ƅHI=0'@f @Y&S%2J1X$, i[!Ekcblhm ]!Rl)n>-Yɖ{,-"Seі<$jfR 3Cؗ.%!DIY%@6?NSmqyE|* 3>\f0!%ZD[OlciN&&pb1HI$/AI#$$ HJVٲ"bc(`-9RPNc6P0{D X`Dv@YYĐO$8*lVg'~)33>ɚ3~  @]#Qac4 GJDINf)_GZ)߲3LíKX=} :lm]yLIZ|{t-F~Ȓ;.[g8ۓ۵܅݊V_4S?Iu׍n= ;c_GV`rWt>tkZ] B9ӵ&L86@Yir˪TmrQNRzR\F*ޚ)Sm6 yr9 y-dIL->X6DZY4suag)$RGsYpfʺ<=΍˚ ߚqþ{EQcE~BhpM3hЩ[YCC&@LEG`Щh81Bc-+C6C8ʖEET> C s2,43-,duTAQT-"ĬR Jź4Kwᩨ'[/Z~X/rxIdTN jNJKCW'oNƴy]pA*&m^wcsekUSm18EQUJW&ivC`Ls]d}QM+yOdi9E r4F.LQVsYwnfPJxǀ:Lt.4=IVߕNtDH䊳*5Ph!zD+5KR%G6Y!ts(ݦ 3\q+MHޣG6A;i[T&8= .f=K]Dcqك|5KD6WT#pgw.9fR,ko 4g:/y˓OFrh$PJΊ!_Fr w;0!\B*>UZ0 UB<.z2ɲUd(Bt&\DtB WHHƛFjR{{5NsXJcl[BR/'vC#]?)N,M T>|1uil <+DN6ik(4)'S(q)+38W4q+?Ų8%%`ЧY4fcTU 3hEVm|])qUHEMVȾNy PPtЬI@hmFIR lMFCLA5L^([5,~/eKbc5?/ʙ6D>CC'!w`tc$zz{G S": ]riєQn0jC豬WBšYcv^TiR 6)3Rki8ͤ/K]~u+SU_MpH^(dMnLR.h۱vN @ Ҥt n_ժ TpC$$;J$-Cʿ ?=mMXo+7NN"@ XFrcuVUBꠂAe,:L5~;(6#5f ΖZřEZf`Qd1h)6h; Tc|Ic- Tf D9 1823J31$C\#6Z"(n!e. c}Phm27`%:Tdq%{:l ;?siaƠeG6j`{ޛ:ED55ր32Kiuj`jSj43х9]^)nڬ-̛Vʘ79NNr5ՖQee3y:.48%m{wȥ"9.P%z}5_;^v $Q-"/6PIKj0p^g { +HSx>G\WRp2oiWx+礸8tJ2*=&5c@:|g͙f_#QhUlfq+O7Y%ٮ? zi?Es&W:9rb v!;@3v#X7Sn'5gR\ c *9p$F661K]h-[ięWG؇۬%*#@ \5DaiHK ly^"6*L޸Ii"YR/bгrɪfoF'̫h6d .M93:#Ts>jL:Hˢ#m68ѓ&8U$TeCռi]ڄ:S|NJ4ӣ>YyD.G8K7m3J_uJ?&&Թ#6^r˗bʤg!}|1fn2Ƶrr8:JKAM@ 3S}"XLx[Eʒp&$4`e&; dsu4;/o(6E[@2-Jcl¤dI 6+b@02L*@5U; a  6ƴ¤ dX O@'@" +l$ vR&Þ40Ga@Ӻ!p J)16 0\(`-R)m0 qRR8 JD h>&0w}ұ},$P]NBB*bm< 7(1cpw(:.xV I1lM)7R.#X2Mt ? !pp#1c뜪D3K,1ֈiL xVC42Tȋ!o+DLT$2}(@2r!URd@My XB@U(x c9H;L1d&R) vI -yIs v`B B؟AB@H`<bR(2R7"& Q7ܘe *HT,LhY#p1! ~FRc4Т$+9hLTvѓnVMd_hv3HU V&N$Q@g U@[?dPkL'Dll*&iT+_ e,A L{$P L I@XqcCA@?,{ Y 0[ P ~t ]0l N ,[YHv-O!Zguż}Fs+ِ!&(buO m9{`e-ZFm+(u0hfBrObw@ d'3dkdPE ûƒn"X`+h< -R!Z6Tn$eCX0n6 H4ȀVI6W6fj( @a+n=nU >/P՝My?+Oviգ q豨tC`GmHH4UH@ƒbY=*-!MkE ը*'c]gPFyff v3QRNS巵MFjB˳M@ Ävb|`.ɑBd] Ȋqa '#Bnnɑi.]z\nr#/Z=Ye󢙄QH:Bx#q_yO~Fp杺1<^DF|1k|\`/oLlFZn+3I"FX&n cj8&BRN즶\c\Cacۇx9SLMjĈLn %ero@bі%˚J5li;K U1U-PC$9$"וr 6 E F%(4lN*Aׅ$+4| skF>EKGL%`TV9HlcOT[DՓ4e/-|-r94|=И -% B䙛fZfy$bPeD'A&i0*)&s7IpfeKSĪEѬ3ꉶ[MJÖYt=SZ/?<ԛgy<ۘX*2#ݐeݔ}՞Cc)!4f36hcD1t 7Vv !p2LJ$!&8%1@v "~o)AH @pIY)`B ͏ G` L&p^R; VdZ4r>ȴ*Ac0OX |*HL&ʉ!4D τVY0qb,ZT (,1  C|쁐lSd^BA`A"P nx@tsHrD`,ĩ`.<†1.m{e tJnRqc@;,fT3tM 8WC*E KcȜ؁.t#) xyL`' " |P%\SOpgy@6-4&`Vfr,!Z OEhi`#=343!ƴ %1lKD`Q3C\}C%$ h7H 7$2nRgFeb}2"p$_! `|` q @G2Brlsd\yIS9Hb"m'G|0"S,3dem2,Yd^gLh঄ $*nDclqm 㐀HN,dPN6dZFZѕͭ\b Ov*|ܴAL`{ @1i C@0BB֗XY26&p E;Ot!.'tYf}Z FA' 0,c@ Lcx  sO)LA>SĪ;wRтcdFJ][(QD,k;$gd5XR -.2۱{-VD#CyWMYX$~U"Zu-#k 2j:كY]ZG@q2&d[->MKQ+]Vy`G Q)J\?.)%=/s}-:3I3ݩp}޻NZ3M&6 -r۶L<32p]gӺzVm2Թ#WXҤϸyGVxjϧN{AL{m`rg}Y0 W/jG䟛~A\֛N]jX}F~|}_QsJ.ոOW#R쵌MZ&NǎU!i eQ#@V84M4$wMѮahCE%;m&JvɾU&K40´K4SR&l#='u 2hʴ*[h-4]Z2Sl`yUȤXw]tԓg?x(^6Ɔ1ڨ,x i;Nx[BIcfT[턨6nXɳ]" nVh\*Eto$pvYd\me>^^$ۣ86f8QBrXq:/b3Byۜf{4n2R)rǴD:4i+ѥSTωD;nd/G6|.]H&ƱfmM#U?#?e0-GZyxٙ6 h[dA%{hPYn=IM Q?购#oGa2司^ldIX\U!,[Cky1O轈q2g>ʟ,䜹T7S5inek;vaj =CfW,l1uĭJL4׸W7Ȁ͒xE >MNetc~7r-ͳSc\'e̅qLMG98f3=[ \ׂ0R [es*&RrGb Te%Lm7X-"5R2!uc%ńc6( A&eY=@YhMК +sg)r,rr'uJɫ%Vfs^0\hh`J%>CGi&[ p-IP†g&$r}Huv0\wN4VicAc=Lc8rP=pmҖw\ͺ|qɍ<]U5Ո͟g;_yHlu7@D1qMdzaQ45ĪD&HA*,91i1) (1 '>QbBKpdC.&4@He6D BL0U kX "B \LƴFUx0rD{b# ~1?l " @Ҁ$F~0"@+y <VV3?@H)cN&eK1n@źLIRK9!IHTȹRPu,b-@w 6ŸyExN@!$@>H{qA@<@ H2&Jc\{mEP @iPo@@ mkMb4S#Q&njLL24h5RC4TAǷDͰ,CAoׄ@o$@Qce/Q@I FTHsQ$@IV0?tVnB@  8@з_!M`c 0b   " <`DZT $c +1ʀc؃`pG!pE@DvS"C[n F$,Yf (h:& % } m~d\ k4C6?pV1#xE op!Uh`t 頲U@bxL(CqPs*@ZDP[@즀%*@= mtN;3T#Ldsa2BJC8(HJt oD $he,/ە,v5E@`00 KSܠELJs%4Z0Vp7=4F Wo&O|5Np'tR&U #aznn[!*|g귌l*RdkDRDu&-c.Dճ~WQg56 Lrm=֛[z6Mjjj 櫃mXuyF7 Q- T:vbO+&$6N5<9RQPT~TP{ i%ɔ ~M7 !Ih1R\ƳSMFGZRy-R 9rgrjGh ko(ӆ=\ˣg,AXBM (CEQm wg+(aY\#cnWFLtbJěbmGdJr H&rݘ$h!mqrꁲ2{YZǧ5|#RI{g /]]0еOvK#Ur[N2F8G9ėyW"n2 ff3[0.OCj Ut%rS4rHQE] YΪ~bi8 l΂د` ~-#_6Y(a\m"#UAU# E˖"kev ;92cMwU42|Wn7|HZqVf hH}ъta!ȷ+6jР=Athzba$a%.΂Tݕ%\3bVLɱ{JF6)vRHS(ՙ*4rIS9gG)Y)e/&Er$1uBX%pu #桁{])p=D|fel,<ݒVUeS&s -HѓcZn.${,{?Tc2U"FHANj¤KUI`n"@@l/N &)"1$ J ,ؠ @'AA5)Pml!+BAo%P`H 7,S6%L]BGd cEvsQH  ]!o$^8(GL& $d R YB͎0G`(>B$T we,\ 6YKNd(T '0B s%2p6XEHل v10P4, (N,I1,*Le1dP6af" M 2#@8-,Kuk2%Z%nEiha deRDY1;& G|"0$vH 0 h odIIPSvHRcoP`!&1(1 cW$dŻB @Gx-4vDŽ"V?K6]|> #|@@X-f/YvU,㝳Sk[)QH'8I䱬͂+u{Y]+^k'4R~t:!lj{y#+:!(#pX2SڍT\MŽ.9O9lxptˍ9 6Hm%{mZqQ̲:D!A \R#NWŹ5'VItrFsDŽi K]h*R|N$%6+xr\djk 7GR X )0*V3bd8AXa.. $rt)ϺLQd6*eLt/~uўڠثSLM1UrE>ъF92F&wVuO 0L5ZxcrdM{\ ˩ym.^uj@\M6>C>yg.yN沉(.Ģl:%c$6k'ʤ&hcc Ƶ̑, ;DùVHa2  O$qHE@.$af3& 1&h$ 0p1"ɤ#0}¤&l+\@7T$ʤ& ϔ@r">Le[( *@6@ 9)$Te (tn467T h̀\ dpD$BTv p&T1d:N t,  qʖRĨcF aKf;HT(>pJ #0B QBc*"{$&`E;o((b-1AHYm x@8N"{Ó LlP J\*!5S$+D3M8#ouhU1'ZDi/ VU 4 :G%2Y|‹H rQ  ({ELL$YԀ.TP D7@2 ( cIEؠ`p8@2$S зnB 1< t((Pe0on jS8.q6 !.=%Cf)A"LK({ʆe I^)X@:`(ikA M Bc$+ 4ИbS3TP>DdIT "D1F$f҆+* D%CEp/oRQH k@q aRCb TvRq 2L܉@H@w@ mʖ h"l\q)-lb B*)H`' d|,lAB]-xEOh|dF&ha.@qE`}RpO6%!F(#LE(8m 9)HZL R-À﯄X@8EG 21ad sat %#Ht@qʤ:smbyZEYskTY-38@(Vd'Ika Ǵm*6=m 7+X!U8{R,EE<p,, c`L)PDyHL֘2ZɤK(6MAeHM`b{κ%-%$̠b @8nH@;'2 !dCl$BA 4p6@xT` i` AVB1k 6@@x*dp?E40@9&; dlC"C9)"T ( 9`I@] X0W܇g?RA;VW`1C\dlEC7i N6;@ LǞM$84R Ya,dh$։0`Dip"m #[QcHk̈́&2؉4b[ /`  ?ҋp?eCTEXS6H1 mW3i3;$Z)CP$*og[Jbx D'ң,U,'ZOV4hxd͔ +&Rf6mHͰ<~/(fJqYh+tx_UkHs_U6A$ϠHۧci W3♵DNShqY"[h4\uKX]IUfEp ~`r9yZF&ч$R1H+UY_dvcestt> \b@dj[teI0K j~,fšMkq8U#-g\YFX ¹Ӆfj郤[+8g- ,Lւ4Al}" 䁰M*P@Ғ2-G2݋(s>sa;k # f)H8 "+ w MXe%Fj+ŜBH!ed. GGQlxx}*o6?^Y<> t:r>{>s.&GْˍG63~ا-ǾO($Y#IȄɲ "@Ek؀@1<&!q4Mc1@V([&)&Rf"$f#wv|X@̇e1 Dgh̉0Ȕ L612boIm:dxUXYUiӸV]6V-I'Q-h5/-XQ ,Y_0aYc7HĮg;g `9dpGb N*6Sqb3CAQeoU)>`_)h(`ݒ/+J4瑡-w|!ţ7Z^e&uCg&e&2W !6ОW^4vl5UФ:bBЕCZ\WLk1ת^pe;9JYac@-#pmҀ%z`8r26Q[K b%M_ <+c軜x]:pk$◧K0|Nsͫ\AX6dAe;E B*ʪ󶕗32I^L:bitHZ;qY$YV6ca6Lw?rH]TN̢'UeuAp+ڎ.e9#V5Hp9X6V;bTDMXEVѕ9~0Fas@ti5LMO+ )A#*edyɔe$\1Vvb˛#yeCNpC Pg' 0]–@) q r(Y0ov쁠H$  ]plP!Gx)D!4-͘P%Lm@ rƋ@dM6h͚) &kբ$M^٩ - }8hU<]P!?eB e6dP 1Y1se`HohH q)Z;LH Z MN3a`уV!'$*[ci m];QХn26-\uco3j6q:pms`%&upfq%ϗ,ɻhSMl#.GtVͮ]$.L4c'o oSVid#:{vVM0(d0%] {.y;fR,Z.=!3.d|(`WatpLb])a![nQ3%kRC*@j뚨Ji6sKSDhҵbٜ+0| UemT4qh2tO:"Sy>ԡn+ H1/+4̥4@ 3Q"4"zSR7893G3Q!.R|4ՍOo`rO;>__(Ŭo4(5 /ͫVݟ93IrRaE_',1O7d:p9"b^KJ8Lv0O 0#',@v6LL6ϰAXE;ǘA#) k͠e1 t0T *aϲhTq h&L$ @ nA$\NF hO"RqC[DŽƛb$kaT 9M<Bh`.nW&81'r]1D@qPy@=eŒaDH?Kl H[ @9ЋCRwP9QxĠt H!M$r>`)I%CopSك2 s%H1n'‘ #=e _2Ġ@:g!lI 6Z{$4l2[?~[`@ c G tǕD3E1Vfw*D#-Q ւV4Sh-&b@vTK0p#/`A4Y%CYEOo) @"{\&E IR"&f LF-~JNp '26T1n=xJ(1nDzx%!s6AHfDP$St >S hb/Q (,yT#7L'ʞr`Q#LvlX.-CB#([Db ` oݐ@ D萁# raRBeM!' GB!7M߲bslŸ&m08Jx@@@&i3iR 'AQ@:n3)@@&ORi$H  ,}*l%4׷ YI^;J*15w09HTO@ (2:3BZLe6ewъM -;_"ʻ) OxJCii2 G,6>PD!T2 d>B3a䶈u rQqkB wM.!lL'tDb4"-v9@,L!.S)EPeM`|.G p&"/QMRF\pv5le  - PwZEu <ʹ.`E֨̊(1 )f"2]H--3Vubu$ _ TDLn7݊*\eXfkEݝ&H&htjYjGg@NB(Vk7ѲL!yCQt)BM#|1۸Zٽm@ E*E(<6Qe0!tFG%t.kmiS--3?"ɉht%l![l8ed6rRiuQ"5HYDfp.&A\~`NMO?$.̲ѳ| nDwSBh"&WFdi`أU;鴗/>7dA[4A Stb=!Y>yvT.(ʐ9XEracaF4*9}JfuA]9,f+T7Jl͔$5>D~UY{HȌ4휿!c-uq- O"Y#"!jpQ&- &1lB좙,[&QY+,#.eW]mkeP[K湷=|"L U)\ TTh 8G-%0p3d]!dpPhsx1R EB`K `t5Bl=D" @Tˬp| :  &2A@*-Ԍτ I N@Qs$1n$:D{${ ʙa$ &$DP6(ټ$)0&6 1[kScr/.1%#AHKeKe$ }ET)X ".QF%:1X s-CR`T@D ɲXq-\ \6 !FK?u/ ʂZLNSh &MTQLLp (+q 0d(e M M)D~D K{DD PFAED&x*@OL`A@ Fl@@ZrZ~gA]l;Zc AULYҢ +Rfp9tͱB `X鈘E!o E2rp=IhˈJ3ϳm}37>O13}=,MYK"6İ.HG *Fѡh[9$jFj_'4ݱZ ICDI[[12%tRTkiLEl fm]92(jLe.&s]0KIv8[ Ftɋ $J-%ee)e#[ VmvGZ& &j.rn9ncFtƹ(7ԑiv.kFTYt&6y EatblMG ٌ4X É*Tv?غ 2g,(BB;dd LbsU4r\<\]FD]5F@(BUCJRtZ]SM,(7XŜfdN0YmX+5NDFH J-kTqA ve&y0j5<L55 :c6@DB`ClHDINH'!Oar".G)Si")$IL`!Hw t𕔐I6)1NR hĠ-P1d2H`9 $P$M =Qdd&}$v@=]1c7H%!nHq9ʡ,.&VlAhA8H`H gMDB4Ro ҅b3'А D$4!ߨPP6!ɓ e@`1&#(c= T`Cw,!nT0H((<@E1t%ߺcD@Q`TdF$KNRsbP 2/ KlPEE2[@Mb@qe,{L6 96)&Y }8af`=őblA Ouis})h(|Xh0~@A*OP"`ih` ]7T"È=\LȲbֲ @Ehvȿ D@ncMů H VP90# LD Plb@g ](|= WqWgCPZ$lc xHn9jk`WB3c;+$|& @T>_dЪVR6>szVѼ6Ă$)|̱Vxd6 ZIC )eUtii\qv=Zָㅪ5rUXt)ˇI9M ;eHiZVQU p;5 pl 7F--#ڊ1MۘpMU$k9Z&ͩ|X+\1#96\C!Tx:md[tnfo[tl[끨|ҸK,Jɳ4,*Ea2H0~[|DCa.`̕v6do[5t:H}]YvQ6A/. +).PY. *nYAٜ]oЮ(e;.,!PBMٞoeoKCLJ,,D&fc ds> L7vI)HKVa)$,DcK *hW#6Ъ5O#|17u^c ϗC^l/RtM{|WU;}?3U&9u$\x2)rI7Pd/ .|bP$)Lv,T);w~ }Ɏ]qLe*$B`Q8HL <t>< \Hl0$&)&6Lr dC34w`ƞ)Ƹ]1 id k&Ȱ D4dkwk"b,`CNJs c0䀂CkDLd'cHIC$@^!2L")؀&L&`$:(M@9XP.q-3&贄`%+L~,RL%` ؔXjyL`=7)jE&&QqJ ^c.H2з? naH %AHnXq<`b7C9,٘xA#.dq*'0, 8T0A mMB @lL pHKIMeڐcE:v%2M2-0R3hMk+FlL- {2Ʊl!`nCZ0d$++HtQl"mX @x )J2pYGH h``tABTq $e1"T7O+ 6Q tK3VnƐFxK;AbUbeĂyˊk7 w$SCg ͠@D\L JDf.,̦2\,ZO $e!Qd!or %&P"/bQWhdSͲ HqH hv %+H "RHLפ8D:uiBzy2`$w@ L$kky+t,00aP& x.`ábџZ7p=- r#[|ji3m݊-}hV#ƩY6 -:48 Ѳǒ2#U=+h dx'$)*i!+Hk#;-YV[H4@VEթQr*BlSl$S&T+2dtDdtt]io,{Ty{In0  `+X.Я#YqH^]gQk.qUፅj.JA\ЕEA|L +Hm)+hbldWC*"ب> \'a!ɪV׍ NY gb=H t)𡘶@`&9풋o`hxlc@ RJyI.̕*EĪ Sb\L0аfCeoi xD'6xZ8MY"g6H ph䕦"`ѕ2jj*U%F͛QJ#Y15iywI_5/><ϛWIbZv;"v|nmTMg E}.縄e9Þ%_[F!Pĸl!N6 r$Lao8(dBgRo lIIM0u*H|& I6 ed&AR H6Ni @>x@;% ;S$6DC`51@ F[X`ZP&id.LM34V hlto Dc{+LRbp1@ݡD3@Ldr @`Q00V w C)XI!>"-Dz@%nH[ȒHKZH!(d–4 @EYq"@%PF8@w M bI/8_]ӷсdL_gmrkjVtE<)< L-(%8HL.,ٔ:/8UcB);ʑ\;Y;mt@0, pt$@ @i`!H&8LEIwT0 Ihe;%`E̥b&%_4HAݲS&md 0Sx) 63Y#ccy&@$wLc;5-@ ڞLэITKCD ä1%a П*\?EUdP3yN""Žl>P(P% xKc|LNM2RMB v:J@;㔬T~o)6:+x1,8M +(GtpIjEE s9rHlNT w_R@oe$ aLt-1d3M鐓?NRJCJ?CXq| i`!R a0c IM07C`h66.P, HSPHemq KF@ELT24ShRdm8pZ&CUNѬ`U'r ɠ1 Vec { jpeg::Decoder::new(black_box(image)).decode().unwrap() } fn main() { let mut c = Criterion::default().configure_from_args(); c.bench_function("decode a 2268x1512 JPEG", |b| { b.iter(|| read_image(include_bytes!("large_image.jpg"))) }); c.final_summary(); } jpeg-decoder-0.3.0/benches/tower.jpg000064400000000000000000002120010072674642500154510ustar 00000000000000JFIFHHExifMM* (1 2ï%OnePlusONEPLUS A5010HHGIMP 2.8.222019:11:26 22:37:44.6"'d0220>R fn v  ~|0100 d2019:11:09 10:59:362019:11:09 10:59:36)cddMM*3AD602695602695602695R980100N:ERjr 03Y'('+ ;$2019:11:09(HHJFIFC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?.)إ{3i3bq?bQm"=#@Hv\umXXO-٢e=iLFړmh 6Ѷ6F(=bhF*LQ@G)h+Fړh(Rm@K~)v)qOh&(@ I5/٤lm ^Gwe+۴p[9B/ aGҸ1U ;#:rlv)vK8mmI1@ &*LQbF((I1@ъm2-T K\S3P!hRJ1&6{iqOK(KDeV :F=D\XI_˙C6qRL)cp j6?Mc?+|cn<\S ZBv$.)^ F)&( #F*LQb#F*LQG6Ԙ(1E 6ԘL.G]if1RbQP{iqODh8'5g\л=tl k*t[Zp[ 1`=3:{W=ռxK,w`/"ַ21 zד~kRa4kGFړm.`G&6x&6[ivԛh4 KS1h`@\`Z].]\vvѶ"KK㸠:r*McHd[hS=@"3*3nA=)o% 22R>\gi_[M*;Gd.FRϲ8Į! N8y5nh|[)6Ԉ3%(끚]SwgQZmmmKmY;hSmmC66;hSmm !KFm6(i@6c6ԛihXf;QFEhSNo*]GU}>|<_,)lszϖ.LAJ(/-K&>ߔ0}^usw}  :S ؂E<Ѱ!fϕӶjZD W;u$@Szsx^޹+ruV^qߓSwN4-ԌeB=?ukTSO"Fʛmk{"(Slm leOe mM!KK;hQE{iBXˬyH҅|F9m;m?e..&KWvUMRk{=2yxNZ[Eekm~ltc^l=;GuqZV G8f'TV~l2@w@ݞQ"9c_1]`T).+KS4lttu2Qa5 wο-E 9.]r2p^k\{Ick+Ag`I3^pr\NLl}.;iv(])R"1nʟimAeOs)6=G0rmE4y)vW%ڝ=mg>+b5V/*Mt&KR-*Ph!6T)vQkץ"Ŷ.mS Ej:e)c7H. 9=*丼I#x7 7?{?1rb*s{Rq\|1 \KFUH1¶5<:116nm;ȑH,r?^NDCqV* &u(SrG=3Kp4N@8>j}=Մ̃qEJII HHNkZŔv맫$/1l`c 57O'uRyxx tfYeX$nOeMs!\{TiV4gv 2I4/c>&RK&J=ԼUypBA/Ljc! 7gD0x(#:R3y0e8<EgO$LTcs޴,:?j֬aUqZƲdJ`TKadgc>]gm#MXWQ@a%j3byҲ&[ٮp_\fU8zvMT F*0<cuܞJy3h`Mȱ\b?v@>8ʯSD;*mnmmyύo&(j(~%3LۀTf2 ͖Gt8n6H>dW9bH&||z f_MIi׆Y #[BI%FIHC.X㓟nZvL _VW~Oojs"~=dvIok Ibd'J*Z4`퐝q,@$[s>Y3U%޺OX.mg̑H'G\篵9=[١O.%F%sj4hix5ͩދ:`H9jܷ"hfM-Թd-J64cl;FvY7H̡dqm,5Z d &GqVӳI.CYJdEW%GYsPI@/c(KF[,0@r3s(e""D#8#oCp.Y84QI7aO,JI+S~gNk3,I`mçҊ*nݒ"*?JG " ۜާtQN[SXm%W&@8-u{Tzn,vraߞO\GJ([&~e++滐I!a$[NaD1G'󢊧3M܆mA#eRPH-@'j-r%Q&)1D@ H:zEKtCD{,q^ H{¬J##~g6Oz E J-Gm "XBGF#~UG+Ehݳ8t{E8#&T7Fcs`dMQMpL http://ns.adobe.com/xap/1.0/ OnePlus ONEPLUS A5010 72 72 pouces OnePlus5T-user 9 PKQ1.180716.001 1910081948 release-keys 2019:11:09 10:59:36 Centered Compression JPEG 72 72 pouces 1/1547 sec. f/1,7 Non défini 100 Version d'exif 2.2 2019:11:09 10:59:36 2019:11:09 10:59:36 Y Cb Cr - 10,60 EV (1/1546 sec.) 1,53 EV (f/1,7) 7,40 EV (578,68 cd/m²) Inconnu 4,1 mm 23 octets de données indéfinies 602695 602695 602695 FlashPix version 1.0 sRGB 3456 4608 Sonde de couleur à un capteur Photographié directement Exposition automatique Balance des blancs automatique 24 Standard N 48, 51, 16,3929 E 2, 18, 1,0441 Niveau de la mer 76,711 09:59:36,00 2019:11:09 R98 0100 C     C    G!1"AQaq2#B$Rb3C %r'4Sd9!1A"Qa2q#3B$R4Cbr ?y(LZ>I0*lG t0 =ꓱ'=4< 5ha>F>MUzz%i W8#ڴF0y~(Jў(%_Z m* փDg?څ 9Ё??H=> %f1ՠ =9C"G1ld 3B # ^AE< h lvhPQB+?M'`gj#(AlP!lL}* p2 l3fNw#@#B#$zжFGYD9]P/zhn8W(bB1a@ʍ# ٬\;5`hDKh3C@@2EK"`Ilap@H09#慢ArN{vQ8..gބnM> N00xp>#|i^oj h>B6$ߑDQ{fAChQPw2"kX"]-epVɍn7`}{Wq۳hwTxFAHtS*3@H'<(4%QBe3gڂl,K"R|ONq4 <@,q@{qh{f B`zgq\ cw҅Cރ T%>n T2(d6HZ)+ T6F~~!%S95B6Ɔ_ Pڡ22|U v>(A=,{C@$ޯ#ێ ` 3`U)#J o7 {j\?h`Ac xZ23{hX}CdT(63*Q*xGTjAoӞ#ȲtES?WӎzUI>&<߁d\8%\Hɡlg=%.߷҅=@ aP{ ?AB0oGZ2 /~3PNɡ,{GPX?ABI#Pn;sM>4َ?zsBa@5 "3{r{44öj0ȁn*{x(Qm%÷4Jj T p0 {aA8 (F0 P_1ٞqBPQnj:*e{+ դFqE=h,x2~Gzcƫܞh)@eJ'@{ ( ';Qe8B?١AF21Chp~#+CF3ޥ9jqڠQP>C`گ$=.9Rʌqkm9?歐6;%(⡫9کl@prHe٠RFR0a'z6׽*ީ0  Thy5vU J(ʎ09qZ!DC }([r;h͆IW#ȡ,?Y0FhEpqUjl{Ѓ `fZapFAxg"{sZ(?j6sB18oqT2A} FzeNhAȈ(e RhQ{8,[8知J(` |Te76s{ѝ?[+V\y.A1kW#Z)xI|\1g޾<ϔD65 g$RX>R7c sU"C 6yv0P B0*.I5l$1)f{ц sڠA< @chm sCH68d!F11 %؂~/(r{`Pq@rF e2ǽ(V')E6g4\84ؙAZ`אH;wK4- @?5h 9<[qKTq4_g$qZA!sD{q=[x8Cy?5hC 298dnRH/= B"X-CI#(`}zX}(lZҩa8]c뀏ާ{Ǹ3=^{uY|ؖ0@o( "Ҩ"0Py1czj#>pp>~sY6O!CL{sJsBPd{҉TGn0{)@sD U ڲh{~րN(e!=j0a,0qX -EP9aRXf }@"?ZSӞ+|FoٌsPw{c8mGs@2f =X\vdc( !$}k@g;у A9[ 栿p*X5Kv ƫ"i?DZ B~/wq 9>;աm)@'zY=*`8J yn ,QA8UR~I5rtsㄲ=VOXaaF],*dv3۽~wꚙ=mG^"<ʹÃݒicxW-?$WdBXPXh@r0 >~`6`_19#3*Y\ ֩Kjɾ1sڴq/q←(m1aER;RX9E @2~jPQQS_pJ+ N94OjV629|Pжc~~jm &e AA8' OH*ّ$ƀ[Bojx8<|PBX''Gx,0(bۚN8@O#Oj phKX x Жq{p{ƥ+xhA5!԰?Z`8O?5 &H` Q#=6MiWhH[27, czֻ*— Ơ˴m{[ɩ姍  %N8r;|4JϲQ[i)qk=[x ڂFF0Fcnva#<^ a*^‘_\"5sr˂m&~YZ&Oq]`µD$2x~( 0TKO?) 0yШeO fGڄ#@[r3 X!m#Peǰ橁N"ms Bك(QO{R@&^-8=_1=(6y*2jsF[Id~+ *$a,ކFG2[w Ar2ddqTP(Pcoj} 1PC1V c@`}σFڠvl$qT2IW88Ⅰ19?j<`s@ {TT$P1m=ћ%J/dRHFY7M KN+tHnD +6%ԒA?P`A< _zyNQXtrjzۤۨzQz4)DOA(0Fh TfjQ=)Eã34ҺK}G[.2ǔ`Zjqo!?r;Hc-<)*m r9ٴǪ?A<Իv (l@3rڌhRǏf8 TeCK-^~ ӻ?jՃ5L%N㟨ȱBرa0 о@BqBXH `U*d'۾(l~ŗ3ES .mST_ϥ@?0, PJ;U#?<:]oG #}o!@0a;koGNQO[t~mkwgk&nM!GpN9Kyp-Y\]3K:voБ_ZVPYv2+oEl֣ߡQ<T czm8sڔJ|T qP>8a|PsօP{g# ꒃf;PA?j,J?J b[g&!#4ڣJ79le =CBE8- ܚ xQݳǵC&9o<|԰2ʨت PAc#qPrsB\sWzc\$sY'NU?[G[57ItI،>HtXTߏ}YK>~A<g:bO}- af7%qľndv|QwmntO^_k_LCc\"!IX I!H03[g˗4bٌG?Egwu=s˵FҸ01Af(S':/!yD~(`P .{bVyz16B B4%W4(g#bބ"Eq?z jP{Tj1QDFIRp3QA, W)&^jȏ(chQj>Ʋq^X/]#bCkiq1H@Qٔn"?2R&?oU/(Cs#g5AM1YA-F (f^?\pkUG/;χ6]iAghM) q) A=Y_g1)뢟=|rE PFWiR6l`fdʏP\gaR$F=$c ^= @yh<աAPx϶ bCHEs(FU#6=kB.4%P`4#ޅB'1@%;4)[^uc2v6ɍdYeVa`āw1|MIȼ*.. :'Gz)VF%" xsmakȖO(\O_{)vˠ㿱v[^K-cUV}/KSӗئ\b~~b =ipHJ5b ҆FO @OFh0~jy(,{r~=TSC5Ib#WN[~Qh螠kΚִ7U׺v+TMVngK`$鼂!6լ;(=fފq]*Eqs`xiq q @iihP 8gJ-LTac xϽg.G#4گm>P`Sy_^>(m@w"6`(PРOb0;Ѓ#'CHr~ ڀ0;Q3v Pڠ09Y9szQ{>1B9(AZ Ȩi۸(VkABFMzG '4PqP 4W# q@жK ~{Z>9⡢L7n(F[>jXb ('<ЦV:6A!#:d– *2Gl}ں}狗 Vfk^ae e̷MfEL[ܻ~SY&?=jzt]qڜ]{q[$vȗ񇍕~:BoN owczYo_zCezOAPY r~(Tvj?"D`chP) n"e|2}ȢڂÁzKj# …hip=(p( njՠ ;SgJ{~j,`qQcЄ4S4#'U^3ިd\# +Ͽ G`քW!&.3 |P1քC*>hRAw?ކb|0ПNR[Ͷ[S䬱EbۚǏX$oͽjmkӽ Rh'W@ΑǫZډݧK= uL#T>[\ӌzO[# 0OtPhZFye$:uIl"7qrCe@7gq pקrcIG9 lF?_cwP L>~I6Є{PC[^q@@hj'QqDNT_{д-hAhϾ(@ <}qLA< mn>GжdBz2 3P;l[p1ڥ+VaSڨLj MSA TB4(P ~կHdwLxYeJ##Vx$3Fj[qљ(1ْEZ20yi 5}dt2~ c}*R[=\ǵVk^!hsJk:V7\$ Ͳ,0YJDm,eѳ/ ~c굓_K_48*xYu7E>zPck}5v&B7Y*M#-YslݎّEj:Pηmk6eЊ1j P¹2 =}.hccǏG)}`~{WT sY6"(Q**6vT3BXڂ( C>F[q@Gڀݱ\l߽,a@'>JDC=P橱?5g?)ܚP 9(`"Adq{qX!޹F%2r~ Ы[F=A GzJ# )BJ/A8J"Y,sߵR8:(Qc#Z5HI@?Z5e5(X*ڴQ`f~LޥH sPжfd~HL xwjŚ/JO4.m GktUFZ@r.˫xNۋIs;n˦M2]b B9VNM)ŎX 9T&~vzs]/Y-Uޭx{Liwx@?2 hP{jP@%${P31dq ֆ3ڄc =_44<~Ƅ U Z10Vf0 (J%д=sЕDO 4 h^001j F9{(r8[ D jހx\nFGj1 ir.ֵmzwMIN#q%7JsMke,?Eb_(r!EVo&_Qv$<0p,ƺ?f)GVw=Ժ.7!Q7^[$ sϕ\La/5’QN1i ݪmb=S! څDj\sR=gӀ`l!O{O(j>*ݫ%#&B'8#562fcg| Þjٖ*qP=(x5 LUbs4Ac'5YA?jFҋcA`W8ڴmP`B9e59 I#G&ޅ.}sHvd]B\L]@Lg'%fCDQ(K?roުz].t\2u)aRb2v_PsS;Gk7c̮2kZQ4kɧ,6zUEI~0P{㗸?,hI.RoWwfNq,`` *U"qBxd\vdc#BY&_ b X2kE(0\ (Gh+@`P!2jBO4 $3jQ`1B:Ti\q4Gn?MAxi4%㊞EW ~h08hAIcPAI=$sJT8 r{PCsV 95QG)HiDK(?5Lv"@'|԰=sO%aw(; T =0zfϚ18un)Ι^h/1zènֵZK{02 F3:$*GDc>~)M,IzOCKꮶ4/R8m) Y\l}RpgeaR឵q>"b귗GgqAޱ(QϲՍ9[㳪Nm/ W8]#}Xʂ{b"5h5(p*" [BzAVAs-_?jGEhxӃ%I Y֏'ǯJ_ `X2ßڿ$g=:HS|trCn>9+ &xfkcY0>t>}븼Xn+M.'_*dK>dg%Q4,`!u~*6( m(E >o X`dСŰ4K~hnT PǷfC 1ޅbֆCo?4(/b+'Ѐ@@3S6ڔTH ooAaU'&N+%<Oj c{wNs@R*Q "aU;?(TcXBN9 RIIBѹCgT 1t Pl6^hjb BtHlqCAǴ}D{P q@Y|7+=cV4>ˣe;Yp?zӭ/ߢ~p zXXj7ztdt*wzn9zQiY|{ѩxvİOZ[Pɒノ%trtsM%B}q!*J62(8&aq@@vaA>jF ̗>rrEcuFNuJk3t5&Gqw."k+of` V9*xx2KfE]zפz+c7nQMvkۥwF (gKl@þ;[ص{c)DTgW1fXcV<emدjY1n0Ȕ;GҝSykkO{b0$#'@y2:rHS[Gz5)몵##'^ Ͻ Cfym?zAjӜڅ$Tc"#޴N#5;(4a^3P fFhd| nqB"[q(hAs(/j+}TkyQTXi@m hV0OږJTFmm@8U91C( qjEF*Ŏxe[>j6kmnLJlb`H#\8zeGn.adL&CpGrgAqP2?l@ǵS6K4jtQ 4D9jm cB}3ӷix Oꗖ|Sܶ1\͸#gzr͆+ſo~i'>]6Ⱥ$W%Xf<ବ<ӄ ;A(FQXT\jI}˨uoOY[Y\J0EwɔQ$:Kmޡܱ\G4aڊ@ZZrLq\]h04r&Yw#N `_Uha'31ϲ*u-W-cmUDI@d*Es@!3@hJ '@h%RL@?Y7!.rEgɫ[ \w? >P7Ibޔ,Ԩl;P djIQf6v+UҀӢ(ڥ~¨@>QJ/{ӲFrԗk\sOkuk"1W]8*k;j2%}PAJ$B8`1K(mBlm憇 tGD=YdRU.E##>G=s_m?Esj_بL\}%cgjC*u51,rK.8ۂ=DO#Ws'ׅ<ƇVx1<P.z.m5tZ4OXu >$߶3^Nj\wW6J sԝl:WK"=^鄱efp0$ϔ7 C,dNjޗ1~>_Sj7%uQeţӱas9(+XQFwx>'ȆP!6OvKf> "'c,04(T{3,"0G_ KT*pCfS$9Oٜ{F{bgAA'(F2"*˜j"TO%([a߱2 eRr9l?Nkt.~9C# XmZD KsPRp) 1کPB ꑏo Q ayD4)Qзyr3 b!2( P.  # 9KhR.;T?zۜH^7ӺWN° KQQ.Q.dAB~Ҫ[w0s}^O+go'<ꮡӴnu .kN9\;HĸPw|dsn Yi2i)G]uTtׇWXiw}Cc'9H5T\"!f'i1F^cʳٓN k5K7DZAhb7ɿ{JWdݬH!\ ZDp)2|Lcmzç4H`ilY=33.rr8<c},ORɣ/z|ܚ1@' f{PER}Ch{ 8)-DT G+FE5m5=Т+@sڄހ ۚ9 f B *QD.~fPmF08㏭@=kQ6 BR[y€{Uۆ`D1^m,{r84=IB)ّZm QYjѥ-ѕ<n!PHqJqᜒ 89 {P4ހ z;>ZM(H+e--̬ <{>kG_~%'^"e6kJP#~BS;W8 <^zL]W V)>Mύ]-xu=̲ӖC-Q@qhKj@ʁ5`J];u5? 4 mV n#?)+ɏrdaI4NQJW|ޣ# e|KҺoJzB +UۂVZ{,Icz'êzǦ*l)ھz  ?/`sڂ-v49TW#1BP2{T(q@y@(n;܊1@sVaC@@ |P 23C#@~P"3ڄZ01K4 PBO96=" (eABB91)DN( d> b+Ky^P5+EqvyDAԣӦsJ KtLp3XhڏMjZޒQi$CAf8@* |R ˊKO&(2k׺,UOQү Dӵ21V@dF*PړSR\tG^=)Dꖒ}f "pAhE}>Sxt;3[kj9%DvvG@Lݯ_߁T}?gBHֲbb> eƣ'Q%h;)ᚥ%&6kax/9h6m<Џ[ J)R@@Ef5$5nN$דqۥv֭Q$ #g# ʪ2AԤvLrԹ$o__?R厒*R_u~o_3GNJYL:\ZQv %TX' A9C KI#|S_?Bѿ9藝3mt7LhZI=I[Tp6-F1pUJ>=hno.[Ťs,~w=zlI\/|ޣ]O?;/k /[SA4\$+IQ$gUށzTxM3JM~f. } Ƿ4>e8 ' (P'(AP ~[  AZ{84- fhABm, 4(y}ZcB ˠq(A'byFT2޲N څF"9g"K OqV@RȠ\3C(F=یPtq>d{p([ C$\i|ǂ8S y5@ڄMC^ :^Z2Dƺک{x'/gkI G9?mtIs"Gqh $E&,o7v }ܱ t wZXi_W+<ҭ;cs"*SHH#=FsO_&-{N?׺~q.'wrІ^6/߄+pROsk&rYiiyӗF+-@!$E#ҠUi5xv^M6싗ΡmiZKصͲMi(E<{ +'nH,,~O^o2gcT(FoP4%/,9J)Da"sڀa8?ZTҨLs@=Ad|ЁdД0ǽ,P0*]K+ARP $TdJ# Y m|ۏކ-Va#5h`/>^{ճ< PAd>#[yfEڂa8 X*YW$b:Y{ c@+TBAx慲PC e8"Օ:=l_(\o:15H=QT!Hm/cPKZ )#էEk!kq0^XY@O3n'2-O h媂PuJmG&W*O==Qx55bCS!9G#nv q]][7 j_*;]c,2<DŽmй=#Y1~zު\ɌrAE׷k.-y\y{K ~e? KjvȻ.7S1_62TX*HݒH0+GG-F(G&_&xMo$xNzt.溊J/J A)Pp iSRWoSrk.2k~\0H=yu @bn8(m@qSY Q!2ie+ڡ lh -if@/jy*{S(E@6r3@0__2Hh{1@i'@S fN> Xc\3 Y6H8le(J$ֆh{AX[20@Aj M Bڡ=QP >?@P~(h6sC! f+P ZYSH@^"~JѶ1mԖ]aPy}I<{wG+ g^h^{JS.5ۈM?KI|0.3&[vcCSO>ZMxJ*DA!B1P\ʜgҖGfqC=yv縭yd-,1P)١( (@UPP=+dTgTY%% NscnmmN+O|3X۽AOwd #㌓_A(}lonMaM6HYU2wM)G˰svO"#s5 =V=tn.5mrhv\e ig;ofaQD͜veߎV*ÒZ_]Uyvnc5[7^B~td.ЬIv!\_K%AtP~"kմǦNum}<BFP(Q *AOOÞz_3Ϟ:mTq3It^kѴxu3d$yal}^᝝&jrFXcS[mJLb?_{?Gz~ާ$>M&(Oڻt({;`1T1bϥ,cٚYh< CٌqPGC>*Y{qDDLD kvDBR5Rȸ5 ۓq@0Z^]PRQ,;vE"|VEABo #\(i $q$@0( {#B ^Pe1Bh[ O[8{8O[䚖  lg@2~-hjų歔TVlŋgJx?64vkQMvtD]R^JDBAeTQ_7fPtL/oBm P"HM $ sٲ{yO  .:sBdzf(fH$B¡v(a g85sK$[WeVˤzLWD鮙a"T}~U(z(N7۞I*[dЌ"ٶt/^zj+/[4~`C f52aT =% VM |suJuHȻ+43#RLqީ:P|VllilЂdUOj6P*(0R .9{j0T&5&;TeC * (0ղ8hH;֮6{VÞԳ4qK5CK2 e2j&F' `*f(e)bX$hO C؊Ĺ9 Zv xc(0$\wv#V.=O krmNI6UP>e|2>t/*r6âϬjCh\ieٜP gq OrGyeS=&>TM.%=jEb1r?vtRNӃ*SPi$]1}~k #R(&7 Ncla>[b.x8MbjR=Gδ:7RE4zV%սWk+ p޸IMgke3\<:k}+#]2doB[dQeY/!wmT3mK.LR> _鞊ϡ۴JN'o s_iR'o>״U+H>>Cٶ|PvH/H3@OڈPlZATPЌxhin~2([8Qm5lK*UC & Q4{3K sXL P} yhb>;Vl$k% . @a?jYPS{3f$ԳCTH%ޡX P4KTR c*(F<{U4/+l,>y@=2Pm6jY|T%^p=j-~&&n讛=)PT`2p' 7w眧jog,R v9;>aJ["01U7 Hoیּb+dzMW҅x~[tlvK=W}{eM|F; d;{`8  cxig^qwgR F53|? Ąq/v-=;ۓ_,ٕ~9t%Mu4) (3++R &"6%m^j'Za89}X'3dվパUȗ4oO}_ 7~`]d@@ϊi"4N > xǡ_z|6mswK6vFrq"gX_V8f^TtayZ 3509 wǽ[-N4DGҭ{{qCIX lCfnidj( cZ~,hJhP ߊ"?Q-f{U#*YPlA ڥXj a^h m CUA*X!RDQbC K Pۚm'AC ,ԲPxL4/+61-5,1VT;D6VKT UI}7ҺL3\^N[)cZ@CI58r?S[PUScu9iz5,סRpLcqt8RJ%z)ܥ%9mhTQDZGoj3C,ZJmIQ';UTs#bM(ݻ#to3[HzwWtwza,%m2bLlX6OltqO=mHZæzFTA5iSb ")']#9WIj!rX:{0kMQߡ2O+$pv^=x%G^x2G"}r,pGC&Sj qO=ۥ_[92$%5tQ;q/?K~w;Jy=RmAEK- oj%"I.{qR .GдYz(K0,Zн, Gf h6BPlT {U{>h]#₃ɩfjdzST^M{qPہR ln=j(y'X`1Tg5ET\c⥔9(?z\RDTTH3C [H-K) .V. UifFSYh[/MQ)dhzݜUT@ZYQۃJڇv=!s,a _7_Ӹ.sU7i~ޖCiFvE6 $WL;&uR>arw&[|R}u5BNGox)4dJ&' bgN\hb4 O:X-6xwfoDZ@#1`F=e;<%R|Itu%jz2/?=[ᶣj9=Pu DWi%$w.#1e,mKU "{/> u?Dxm1u9Rŝٕt;k,ژ$yJs$5=-Tuumemsmqn-,Rn2, F<07-Q<#Fk*!6 wo8DG]cp_Vl yq_M2,_T$k?\[O[8Pq% @+^ VM$qH*Y=Y[FF`=;AZR.-)jՒU#"cRN*6}id 6Rʶ({>lnhDm C V1P"<հ=AF/9٪5lPjaBP+j JY j͖J%@-$YQzAԲVl&JQ Y6Koҥ4GK#5whljɴF?FHxF[1Ω_1mPRCfA؜ W&Hr62>:M"YRp !j]l=iz:jE΋xsEt俞ma$s2dXݔ.F/%~8ܳs~U4t ZźZ9Yl,(̾epqR[u:NZzvisRT! R7;$M:Cg~]V fD@6հX4,{jQaK(sYg9K-1|6{+WTs)+r6@ナEj6q[a0Vԑǵ%*ٖ//X-TJNhآA~S(})dA1SqRMcmvRxtl0,m-Y9S5S%ЄB۞Ux $h({V|^g @Y5Z$:)-fVl?/Y."),mXibFXA$bs/c%ї]cZ~Lм!%4ݽd~oQ,~ (#K6L~-SM%F! y*udܗ)Ot{23l2La~o'V([tn,5;&)c9&!Pad+(ol=/I)$G8b>~Ω˥ʶ(6VXsRf@ٚ([1K%K=JYEK=ޡR TC l=PYe (h{4%歒c,PRT?/i)ږJX ޖj`Y*P*ٓږ(6~L= H)e$ ٩e"Č>+[ڄmod؄֤vdxDMȭ3bm]>n1vJ`@&f7,m$#jn&i0,P{rk-Hc [-/ J1!*?_.\3&dc OR-l̸b"m9W9dׅז}qRQ~Sm֧p3@t-Ky<8:nx +R]]-+P0,=Y8Al#rAnF015z0 +S;N⾶ύ֓D㮗WI& |Qr^`ρ>RGɫ7}cgեh5̱˓ŶC2 K;wo6'՟w5"nԮmL]f ]krvk#yF҂25ן֯V;- 3j=?qGrG?fyڒg4f.2q~TjdyUSCV2,P5 9SqCnpjYF"V?(6N~j&\pjn+{܅01jn^*ءWq+MŠ7 vbR!T6i!|M ihHRAd,c3Sp}#eF"=ٝY(\Բ [% G͖, %]H6ԲRidYhj".Nu]]tU- £*<=@(FI87ɓq!g3Nk[ia[/K- s"3ߖ C Gr{,ҭ^ .dfU%^h/#ڭpnDp+=@.syZsytC)4ϜyN1~+ɒUQ 7ovz3wޘ%0ߐ&^pD@c@9 5\M>yZZռ, IC)A_ey,/lβu~fNOjhb_Ïyb";qyrG ?{:_6O.<Z=;[9e#C(uk6pQw{w>56 TΓԽt2IG3H'nUzx8w6zr/N賤]Զ@'4k 76ps\Nx1gp·sT,E՟t߳gʪK\o39>O9-8Ur,%.7)bK8:0=Grr+c-w#VYu'T>gKaٵ:r6֣`< bNz1t)Aʺeu\)UY"8gS;AF=vWfx/NʺdHQ}:/-bE(k&G#2;_%o#<\ϦzgB=7zNNai o4ODŽ6l)chlTî^KǪn-mwGc/}|oSGz$pެ ֛Ju b{f^'+T (QnX/sA<:8 M.RB-{Dm>PX7 Wi<7(oIMV[^haio5d՗BI!v#XVfX~Ll$;v|{ W'lgi6z j8?s]EZcڴ..@,⯸OeAS/ɮ޲kI{jؠ*[*@R0,Uo4{im Jne-J('(=yʱȫl"P,ˍe`ZMy%2xӶ1y~.d+2aCq i]huFRK5+{K{JwA\N䑎 pԱÚ9cO?zP([/^6X7ѕO$ɀ0/#XS' }}DO7v^|E~h6ߥTD,P*hepjY(_,PFZ1dhxRٚ̊Y~_ҭhyu,PJXK5\ڶAR,m!10$[I1 2~ &F7$ߎu ek8=-bC%ZOih1n~: m-a` -ʕĞI`k޼,'=L$t؎,w2N)I[^FVdY v0;C9r+(%cc]΃mi_K4c,'t\q"tۧnֺ hZ=emIm.#!ϥa'8;F yvvﳃ>ܸ:}H:=?Ve9~ω/њk^ SFe2P2c8q}Wc-$RޫgGHŽ/owu1!܂rrn109Dն]SAsouiP]Ѫ$]i#QwfPXdsyS[N/yu}f'":<FA_AZE9 ƨtW[^"iRj}=GX$qvoc+:4njqldܟjÙȱzlQj"fdNZVN73,=QRlhztp؄y"1AV05l|Vw)l U6Mk 6 4( TE6 vTJ ^NTvw1ܻ"\FwW8I,urfljn9tJ-IݒUʗcp`98P EyYNkk=~9^qyDok?;suy%%PűmTdAbޢC ďy7s#R[JYGi4qK$knK,ѬMʍTq'=GAk$gߎm^+ງ*,op8dzG Y)k86w}v DE+>$nH,Pd W}pxs)G|ǡtޑm-aë}*ʩa #x i)i~\˾S^X٤bynTHF G>?RRM0iV}{|R$&Frlm3]0M_w"jv-5hն`z5%h :3[,H-, ',m%mLqhLZ`Җdߥ, >K4jdRi *d8sޮ6T{)!NIT$qeɲ ="KW6S^M%Ź0 ۖp_#-U-ڽ2|Og/PiډnTƆgbA#8 2 xZ4w3 Q ]QO%M%ܬ" @ajq:҄jOY[H尰h?2@uZn4Zq'`㝹n"2RܣT\\\vhVطfg([~i,Df)YDf"VJءm,mveH8&Z_Vm,xbaVH[)e8UuVM="E! m9P?b)KO#I.exgkw*1dX FuNN<)9c{Fqq㚟Q:Gىӭl2q  rIGQɖW||{Am>qVʷws3Sd 1pI'sm磰/A}7M[ڲ"!KOJaXsUM6ڶyKԚ pI&֑1F`Fz-(7+YnRhhvn[%]Z΋$~~]qF1޾S~ţol|+2EiwY/ӹ1Ms|ۋ1 'y2ً&MӢP!4HLq_jGP]*-G1dZ{VxKKۊXVhJ%RBRPcڡhx⥖,P;2L8*&(BAسACmKkzTM Fhs ]W<*@X~>ٮZ}r> 垘"!s#1S2)%=G#ff^{'Vw)# 5ď(l**>{e"]IwykK5F.24c|v9^ŵ$gm^ .kBUnn4ۣ0fb,;r<>?Vp.,"[@+DVʩ;>:4jgUyp(#Mǻ`!p9${C6Z9>S:>?JkWV4\(1~a6P9K`'8=z9 h.Z/h*Cb;nMYNeئ[b?jn&< o bf@9AjL[Bh2qKO_˃Vwܟzo٬ 45($c+'g{Gy|Hr y4{c3]Awe,A.XySʏg׹f~Zơi{.1ZwJ˲ʪ`>NPS8&mtjUN-p 9R7&$F'tgUxz5t= =ͳYZݬr2ЈF@@Xa^'ߒ3uqXjuޫӶ\kZum, Ψ%$+c 1EFVG&_]OWx/QTgȢYy`drȯƱ8E;n,tn7}'U$+"-a&ʕdzp$m$hU<,C4!ѕ*_fɵ[;߆cm]'i۠oLȲ)nVOISlA}38 |=N;r-P*I.qR\9dc5lPcxbm,=ZM,PlҖ6Աa9ZL9cmʥhRѭAClj WV@ސpő6'f1uH#$iK?NN30#$kr_#.Ʊya! 5 8C]I;?v,7urn;g6l8:qsvf"eHèR 9ISklS$**Wݛ[+ F6kAeHL@DEYpgn7n7.~fZmoKy" Y#"bJ)/*ASʱL㲻GӉFtz\%ƒYZ,CzF8`y6}:te>v[WӯU\Oʁ#i(,woE]--苩,uX1*F+wmgΎ RFinP5BA&2 n#ܛpE%6bů6_^lG'I'7pB>ҥsΨ Y$8Y}ryrsm*y6Ox M,nfUOo8U;$lWiVHKO;Gн1'KuDmtU ' ӣziÒڻuH5N|U\+VBA7i/-G,QO#7EMA>,,C֝aoGֶ.ZO]# |% P1pR@7fyZt}npce'Ole:]>cb!KTXgg/tk@:|;keȒ]]?RiP\y9؈ a AFzi`V`r4{YZʾ\b[IoOmrJ m]Yȴ..5;(djK"n# YVDG$]g%jH0n?(gI1,kIvUϳLcQ>u!0h߮i$3Vpx;bY&+WnM]2-J8{iqobCǘ2 4R4e " _K)ku/VV雮.Nڴ6w8LDC;CB5M@r'5%giŵWG=SjGweyވx.[k)rq+ܮT(5ݣU]OOCYܛn]'dMMMc`10m̛ٻ.NIY£NΡ=UJNC={G3/X3d X#S^STD-WP{ - dFaNLꋅ@Tm ]Y2)'\ˉwD`NAdS|L'vb,X$,hDOzf@HRʀ5,@K'c)``hcBY-,VB}b/Tae΢di0$3ܐ*M >-Mֿ-zwS3.8ի<߬mcEmseworf !CV}(Diaj;9!+EO{9.7$[ l]wPǹ<Ϸ$u'ZR[Ky웢nw m9`0lAN*Igs|Y\ &8d.VaD9]z4WQUTk512K<$k"Bv(@\W #ղҮQ;@ta%H8>};яv~IcVhPH38$R<(?;.}ۛH}w\̭q$42O$q+FqLj*n#?5k6z<әv #~AlߵbQMno4Jׂy66 }1cvϧou>W*Qm&>fqjVn Dqʍ b1*TqJi3 ;AkXW1+`S O33q{\39%]ɐ յNqVA9b̾pdr :ijP 8nsUbJ<4W:~y|XlV[#W˲힞\#?a$Rk+"3qj W*z ;׏O\KܞiǣR˯mn4&-CVQG𯰪G"A1M#4r˯$=k/jO_Kko#^iP[bI@2ayn[S8qs`:gMuGjھ]x}#~m 5K 7G+"eA/+PAOrXQ=[v=&-+MqwpƉe5,@oLMɪTrO6gSϠt:<it٧=UP̊NFBij9٩fǁԙ5ŧN\AiiƧ 2mI Dt/PS>3ۏeH?PƺVkRI{xGf^bTI1$F$rK~dq?RKT3]w/{P- ;Y=.`m=/JH%IcŶڮld3/p6 HνCGCz+m4??/$r?R!7D`"؄ ǂy8#-.l\'n:8Lk5tOSnvD]q Dyi¨6kFgMtߓtRc:_V\jwլ,׬)ǖd|4"f57P19MQ!wb065?(fN/%09G$\~ǂKWooձ+`k,#l6k min2{c8Mqg.+QŶ2YLfC0Lco5(>U*T}VƗ5FŽag7f³ F/bqz(bRFfM$$' pqt:N΍c[[egumDaF—1I$919]%VrR4Wۀ\O#]4_'GhI ܱp-?`$~?3ڽTέzX$ ۈTt4KmOl󉕕d $2B~k)`<{#-4o`63`3. arKR7aXlFRq5{OOe.4ks@P+(Pʌ^T~w#JL:8C@HZ?Z*8@Y {X59G!u y::I&ݽЏ`/l`Cpv96},XB]>Eӿ7YYP!l/A2MqJNrG;;_Һfk6Hs}uS ';ڿ:NѽtF1zj[}$\H&d-R0To% s 9gYmtzj+OZ' ߨNvXⱔi*b3XWs&~#U|'}e:im,2OKx|AoX(Wq+b|M^LoFâ|Fӝ-kvz.bNlSD2yr$Ǽ+HJRvt?RXuM=Kְj6b;m%F -<jƛ:W3}}[})I7ʤ% 9%9co. Ȓn' *o%O Kq#ګi"onp"vi4p69S;K V~*& R5prMQS|xYo>}bBW(tlD^Esp8=);䇓 {1PTxIw3Jy5huwe򠓴ɖWgj꛽f+J;SfbUYvĒ &0rvm+eE3:k@l ^B7w?\T,qcfid(2iv+n݌ QQ$fӧgӵּg"Z `i,)%8/zgK,w-}c׏j \H.с# AzڌMNcqX_\v`"hR**28 pN95+vǪ,:nj̚Σ+βyy!qpamh$6ѻoMN{ڊJ#E 8}9;G`;^ m2Vie'q͆Fp<8. 0:.Ri34R/X۝.Uye"FX#m_3yV*JX5)K7FU^ B+*wx7~X&w)ʀdaGw2ٽ-ƫ 7L"o)[tg#xq.hS\"Ic1E< yPq䓟_D:$/ɶD"b  FG+ZJ&5wj$+wyqR8?\qf5ч1R]]\18/u~L Rc.Ө{2ʅA9 8xexLFIM6Z5KXoo.đ ,|d?`룋$ŝ$e>LTy5{E*Tp6onzӤnVPHB5zcIюK3Ie $[ (Ӿ+sެbl4tXP2y9+G,9P,~ѭkMR(D-<@_,*%4Vg'ޗЮ5ޮH {Kp]JMΧq!n Lĭ:O=twAׂ-t%!w򘬬/zc+M&LnG[85:G6ɆIFq5o5͝'$R r*X Y(]>5l>8!(kӽQr˯hV2r\F6%68<N|x>F뎇9eyz%U(d{_ *mWan޹.~kovj[wk oHX +α/%޻T+bmKc ]A;X52XGs.%~r~4) n"ӯCpIC̃AYRs=[ni֝:OQ0^XErIoy:g +rp!1xC:wQ6z K0pࣔު8W>. .K1jia4WER& CU,3ܖ=ǭS\&t36zeyVQGou8>Y' 0+zq ;yJ͕&h8Bҍa$`ɇu،d 8|taON}YDHqfY6o~[Fdn).t$dnrN2WۃWrL?<xiyWX=K8y.Gg,A'9 uCǧaKoo푽qX)I7^PGݟmۧ4F {QЭe3*7 'O' ۩ޮ2MfzvdHQ,?'IIsZB.oz漄1H $|@qz8uO T~R:% VihvK{9 r4-6+,enR<'jejA8T(ѧ{.&*Y`L3,lXΉmXYØ"WIvyLYS[q!mN>@nxQu!=c\] )CX*$3ɺR;>I( օ῅1xI}MNKu=ODD\ <)\80ۘFwdR3˹}j>!@~'ݖ}3Rag7²m#VYcO =x'&нLd%m1d6K)ۘz+\g5kZޛvgWZi7}]5[%Ics9$sG7Q |6vzfk-P I8)aHbwz v,G3#Q?zBk"uxom0`*z*K :M$q*mLǑ97O"'G찗!}}6t9uQ@;Af2>~Ǎy)6:u^cL>n:Y 6 0r8q?R'OKMnj-w,}͝yDj#co0(TG`8}4u o/5漶#kYG~U[ 0< U+=ߘyGEL\B۔?

?#wr3v]AC<2.n'P$}yn`^ӂN?OO+ywk$́bevNs TYo@)y`VQw%enӺlhS(Va/=ޤt$zq95m {jr Us6F18bqgDmlH Mg8r?g\z'9*9F8#=\2͕nLhB8e?zϔ<:so:r.X<gm,GrTlQQ+F@dgO' 3md J0Hޱ#qc*N䆐H켮| {~_,Kq[PO6OuӤiuk_2=ϫyϿ߱ItqiWFeG.ItE/h6YdvI}Og*vcN\8=~kKe#DKx,TH]c+ ޒ;~xj2)_nK.e/' J|m$Ѫ(EFp{~k90,&0[%$zʖQ eϺk?=dol<0G|x`qMOA<GVbeIa@2}ן9M <}Lr:/~=j]@IR;{2kr2PKMrΏ>Uiu=6vtpAө !pUbv 1֔b~N<3MZtnԮgA(m ZsKPXjdIi7.ϱ? 7^j_ǫjw[H1@ļp?yG`=.JgG3~Q2h9;{~%2̻&< n^RՃrD?[ImsFo6jN~ sFok;R=:x5}ij.p,U'8`xar\^|)NivZ7k9Bې3;rci;,_}o,K9iYΜzanJwWVz>ǥZ: FImfP3k$)"?Owf7,J 9:=ƣX)[.|ܽ.Ѵ(q+껾O?-+LJTb "}X9'4zTwkF2F%lDzIVp?> Com:zX.tY! 4ʅ '!JǕgGAuxO6k!t,JȊ|нE[cmF.ܠ ɮ)s]O,8Tdr$Vڼ \yȢ#*e;nʒAGz ^#l=D W8 r;y8"8(#MqGՄѨGbhm'*O`r;FB֛UXnHW,싴39RX`sqώ_R6:FO3̆8<ƍ9aO*89v}Kx+ i&$3:=u 僮L} =FIĆ1 MWpN\B. 03H<,ɫL; y|e;A 9PInHuS6IC hiVEc0B1#nHOWe#ÊSnG2H}G[Y v6Hb }=LHrwr8f$,sBa/ucp;>_ⱹ9$elՈ5HF#aN;N>09i*2ѤcT q\q3;ck-PLEg2QOF[#=x|\/$Z,DۘO9߷lĥj-2,2,2x` @9+ZI#4RH_ьrۀGǷΎB3\sej37zno՘5. Y_4D)}>M35.7rGzm22R6y"9>ă_)MbU=ٚ)5?r$\qB{bWfxിkXٔ#Y6؝0{䓀ùɮ$qTkdKʱA4dc.ܜ),%S)R8ϊAd 1{9rs_MuNgxv>EđLH|I'fcFrº}x5_3 k:èPH}92Ž<Yd'zSޓa}X3ƉH}! tK$?e"% aY􅦯M[A( C762wR_{`^ҵ++Jשd[ !pM5mu}O׺&]uk IJy*EXȀ$T1' oŨ4~=P%i-eBYusSgѯRRXǽL 6`s93^[;υ~Ůt4SHT TeR8Ϙگ1j'&Hͥuc܎#5k*v4- t{Z6+O$*?Nq9%sݭOvwMYM]a<&r PG0?œOly.ϑotͯQ%k^6Q4I$^L}xf|Ccb<p@mLj$ޏ#Plr) y km0 Rx;HW7aiZE,.ȱd{xK c_8!?SA} wuy$Y'RRgvX X3féJ.cSI%@#յ'(Pr$5)B{u'>1E'?)8ҹdʺ6F)䱳3+[G6͜laH鑻6?fY ۈBdm=FO{*8=zKcv$ݲ = vGzhn"[98$1\ 0صW6c֤=3 <&VK;8H⻚+ym&ҬP>X'yxAm1@Hom6-',gprN 5G$]䴇[ɁpK"F [s""0 [>{W5ga; !mKX!?VFR@^ Jva.MWGH-kk⛉A HC!$`6cۮ>Ȓ-#G:< "Mce{n-bV݄(Q)Kq]|ڜkoE[@nMӸY&LLHfe,ƹ5J<4w]\i %&YRr|ຂa0l{įn_t/cNy^C,^YfHS r͎8鬍cGVYxjv%ޫҳAu%:m,:ڻه;-k%Q WκFx}Һӄv۶?"˷#؏`1߆Ԛ>w=ja;-"ktE$aU>_ƶA<@;}Jץu KHxQ;( p 3\َ|o ^u.>q<]Ć5 %sI,M4HWJ[d2W(C 0D&z= xp)E}?BI)BonNIds߷ji>{qwH#T};;c)B٬1\~ 6 2y]* g#81nΞv__W v 2̧ˇyBnT dWB#֞ɔ[Xuͷ!@ݸ$CY6pO%Ѫo7ҦYclYdq9?Ojᳪ:.ѵY fW |=Bw$eE)+嘵Hʕd\co{+VYFMy+Z2I8@$8<| V5Y,R_5 u }-ĆC79<0ǫ#>d4"C\z 1=;@/"K"ct CH#s=\IE7[ s +)F,NT{rC9'Gk|Z4|@/=w󁃟(sY8ԾGZ5 s;>5Ls&btjFH(HGc׭Ҋ7S)?P e\XHF JKuj[4ȒoYcU y#cTG9'ѼMs=.s|m"Ul ;drޞiNh}%֩uMq kpec*}f,ؓGl_t1N\9yg#kP (۸pbA*@3cty'Ǟ_2EGl?I $,f;{=2UΫgۢFy[3_?YKߵ Ծb. Pyo%x7/]KWwy-ސu[͡Ck ;"!NWq9h^?+BuáZݽڅPfb(gvnEsF,IO<Oo%EK1,D1M2Hs$8kk}Dt΋X Y,ǛR8ԦP` 3)8>7_f:f6 ylcih"{iw#D/`2W9!JBtΕF>ZmZ# +|ͯ#'g>KueSLGMKtXE8Dؒ6E5+:`l$nǟq5Շܥ7.>84տ:}'y<<6%e׮ܰ ǹHrQd60*ЃwX`3] j携(&ZE ]AkSP`67`qF66IYMq@ ɜFq _O@WI䢹+ڷ^YhKąrh2PW8-]ig<>MwB\k]OhYAsv,Ѽ260•9,J|W>M yls &34\F5'nK0}9ͬn#ӄgky,P]34<*NҾWp\uٯԺLK{r Ѫ'И *ĜpF/kڗq,ʸ*Wv}IdkKTb*YXI;wUGM%_CֿcҚN?m#6!rp@ $GiM%(C="-oTFq *UsZZ<]b9]ZPZK g{Zga<'> h D fW`~'89ȓG4%;zOk#IXʖF(w[2{ kg#Y9t-$'舳@veaH$['FwΣ~{s9X6TXeWhP}$ *E٣ѵ U:țex3!_!#w%(F-¥-m|LKoE!I-0): u,}EV\z糋\PUى3*̺Fj7zr_hikGǵخ\+\sKp2];֚qBK;K淸fpX&/H# 6]#%7JM֭ooahMk.gjE 1C2gsm%I-Mm߻Y$fX RC pH*H]j`Y'Omg?m뎾;}ZuΠnŶK(k9oqԃTLRvYO\Ե:hW-2G4,1=53.Lnt_i-o:o:W/)-KKh*nZ5` CFryN{9\zR$)s*U@0Mq}*JGϹ3_u]Cuݤy$}'<)n _TQ\D*^5 6=YU \xqId͚Q_뎄4Qoo%/^xotU[lpOxm2Dl@gӜMQ/ Tz}Z̈́]jVU화 s`G$72eSB-쭵Mo !lHXjαm@8s\rDx_[%[hK4kv`rHrHʉzᵳU_}:ܒIuus<ʢiZjepvInQRR-[uGE%3ǿvF8gN^X v j\XvƏs>S;I/ v98],+i#:gi',32`5Ġ5f-ӼcsH8y8\3KlFfJ-F4O\3l Le r2?X9J;l'(FGU\kחN5nGWT8 vvj.*)7'# ]M*ϱ"nfFtJZ;If8>Ͼ)|uhT9Q$Ҹ2RTrESȚA*W}\X3Xу躆cij#*ͼ$Jy5#\#"Ǥ749]Iqr2A*p=0Ez|ot^ 4v~z5pd&/Y9Q/$㖲> }[c'4l 'Nq!Hb ['rix6s-ɪiYj6h0)qc`y  HHVj٦K>8l5!bGѣ$VnUibɒA> rNeSV#%,r_t8'W:U?<wC,@ϫ#QpaОm#6K-/ rmr"rv(s=CRpQ6NCTV{[n$&,H`G{ggZ:$!O F.즹{iXۤO es+I wۅA_eKT醘ؽ#܂%m~81ʵXGdWm'.EՙeYZ B˹YrO'aIrK^ڊ*E^Z6g ;3` 䓂p>k9':tqfPWgZ{rV1X+I]T#WS9&m@2q%Y"3lP"we?G䃓4m\f^֞hu|3)># +YY&i$K}CQK`[42r r1klNކO&Jli?NtuFu+I4E!]Eknv8?o{N)tV4(m-1$,fI^4?8gn a棫:[K66нMoXhO"rc, 28{TWŞjIL.4jbة89\>qF2ks+G/`UzF[;y#.%#~A]NN.l:RE<#R0rѐq??ɍv'讥ִmJK VU(Q*A܌N1ƓTmOiүwտt@ZKR n3,!J78v'+Qs~٬TE]|<髍R]&1Y0yhO$ mE5~#SyqXy|v; BQd'5Rwq M&t_MoYOPFpY\ȍKw 68e϶E<炕Ҟ/jQj5yqI`}.1,v26<Uw򤒮6;GQu.?NغoNL8H"p Hq!c6輰 vqjQJec\g<;D/%u[+Mctf2a*cnd͏"GT2x~ zDѺ-6WG3A,PA~Q!?}Er9l7"Gҝ=ڛ&[WYHy@$0G] <9ju=[kH0ŗhS'<|G__DoWngR4\o 9џr $PgkVRHIs[tM˫%51*n0Uӑ8'CIq3Hj]=ӌ\T$0ŏ5לr?xe^=P.aٙ F~>MkM#SE'ミKOKUk%p"y 9Ni>#ZKiD7=_5jN[HC@2C$Ɠ~,m'I {55W򗱏_V]aDpi9賟^Ne+/~; ^-eno o\0ɴ(Q,%U|LXjpeg-decoder-0.3.0/benches/tower_grayscale.jpg000064400000000000000000001517560072674642500175260ustar 00000000000000JFIFHHExifMM* (1 2ï%OnePlusONEPLUS A5010HHGIMP 2.8.222019:11:26 22:37:44.6"'d0220>R fn v  ~|0100 d2019:11:09 10:59:362019:11:09 10:59:36)cddMM*3AD602695602695602695R980100N:ERjr 03Y'('+ ;$2019:11:09(HHJFIFC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?.)إ{3i3bq?bQm"=#@Hv\umXXO-٢e=iLFړmh 6Ѷ6F(=bhF*LQ@G)h+Fړh(Rm@K~)v)qOh&(@ I5/٤lm ^Gwe+۴p[9B/ aGҸ1U ;#:rlv)vK8mmI1@ &*LQbF((I1@ъm2-T K\S3P!hRJ1&6{iqOK(KDeV :F=D\XI_˙C6qRL)cp j6?Mc?+|cn<\S ZBv$.)^ F)&( #F*LQb#F*LQG6Ԙ(1E 6ԘL.G]if1RbQP{iqODh8'5g\л=tl k*t[Zp[ 1`=3:{W=ռxK,w`/"ַ21 zד~kRa4kGFړm.`G&6x&6[ivԛh4 KS1h`@\`Z].]\vvѶ"KK㸠:r*McHd[hS=@"3*3nA=)o% 22R>\gi_[M*;Gd.FRϲ8Į! N8y5nh|[)6Ԉ3%(끚]SwgQZmmmKmY;hSmmC66;hSmm !KFm6(i@6c6ԛihXf;QFEhSNo*]GU}>|<_,)lszϖ.LAJ(/-K&>ߔ0}^usw}  :S ؂E<Ѱ!fϕӶjZD W;u$@Szsx^޹+ruV^qߓSwN4-ԌeB=?ukTSO"Fʛmk{"(Slm leOe mM!KK;hQE{iBXˬyH҅|F9m;m?e..&KWvUMRk{=2yxNZ[Eekm~ltc^l=;GuqZV G8f'TV~l2@w@ݞQ"9c_1]`T).+KS4lttu2Qa5 wο-E 9.]r2p^k\{Ick+Ag`I3^pr\NLl}.;iv(])R"1nʟimAeOs)6=G0rmE4y)vW%ڝ=mg>+b5V/*Mt&KR-*Ph!6T)vQkץ"Ŷ.mS Ej:e)c7H. 9=*丼I#x7 7?{?1rb*s{Rq\|1 \KFUH1¶5<:116nm;ȑH,r?^NDCqV* &u(SrG=3Kp4N@8>j}=Մ̃qEJII HHNkZŔv맫$/1l`c 57O'uRyxx tfYeX$nOeMs!\{TiV4gv 2I4/c>&RK&J=ԼUypBA/Ljc! 7gD0x(#:R3y0e8<EgO$LTcs޴,:?j֬aUqZƲdJ`TKadgc>]gm#MXWQ@a%j3byҲ&[ٮp_\fU8zvMT F*0<cuܞJy3h`Mȱ\b?v@>8ʯSD;*mnmmyύo&(j(~%3LۀTf2 ͖Gt8n6H>dW9bH&||z f_MIi׆Y #[BI%FIHC.X㓟nZvL _VW~Oojs"~=dvIok Ibd'J*Z4`퐝q,@$[s>Y3U%޺OX.mg̑H'G\篵9=[١O.%F%sj4hix5ͩދ:`H9jܷ"hfM-Թd-J64cl;FvY7H̡dqm,5Z d &GqVӳI.CYJdEW%GYsPI@/c(KF[,0@r3s(e""D#8#oCp.Y84QI7aO,JI+S~gNk3,I`mçҊ*nݒ"*?JG " ۜާtQN[SXm%W&@8-u{Tzn,vraߞO\GJ([&~e++滐I!a$[NaD1G'󢊧3M܆mA#eRPH-@'j-r%Q&)1D@ H:zEKtCD{,q^ H{¬J##~g6Oz E J-Gm "XBGF#~UG+Ehݳ8t{E8#&T7Fcs`dMQMpL http://ns.adobe.com/xap/1.0/ OnePlus ONEPLUS A5010 72 72 pouces OnePlus5T-user 9 PKQ1.180716.001 1910081948 release-keys 2019:11:09 10:59:36 Centered Compression JPEG 72 72 pouces 1/1547 sec. f/1,7 Non défini 100 Version d'exif 2.2 2019:11:09 10:59:36 2019:11:09 10:59:36 Y Cb Cr - 10,60 EV (1/1546 sec.) 1,53 EV (f/1,7) 7,40 EV (578,68 cd/m²) Inconnu 4,1 mm 23 octets de données indéfinies 602695 602695 602695 FlashPix version 1.0 sRGB 3456 4608 Sonde de couleur à un capteur Photographié directement Exposition automatique Balance des blancs automatique 24 Standard N 48, 51, 16,3929 E 2, 18, 1,0441 Niveau de la mer 76,711 09:59:36,00 2019:11:09 R98 0100 C       G!1"AQaq2#BR$b 3Cr%'4Sd?9g#S1TF;L'MS>(>j3~1H#ښy~*FN*~m|QZAz3MWi?ZqJJ8&?z\XA@N1`` hEE0^A< AN2)xS Jj2>~84^wGJAdS g4Rf>0(ir)ލ骜cOnɤS Ahێ>jq/F~*>ԀF29V4r sOiw4mqcO֨(QTqBL'-ݩ~U⤌F}' > 8i^ojcvcc.;F{fgBd7g\-Rܲ7. 1m9lj2 qH&OmȠaۏ^1H.} ɡTgU2F8Ƕ~j1;$l{MN8Q$cj9٩)?O3߁I8N>{7)23@yb{wMq^Pp>k(ޚW+i8zs5]aOqK˱xRqR3IA ?r`Rwٸ=Pia,s@MvFsޅPޑLgs &R' PmſNLo"wNިd_N92A r1)9jp 5]o,9 =%_VE^{%SqOa'(oGޚ4"p3M=)~6TGqMW;ɦQ4cހ>Ԋ|cւsv@36aۚ=zހ=MTAAPp*OfyN6?= `V>F̓;=R-je0{ n qj Q )U*yTq%GNW"\c89 hA} 2NSیR1 fvc;S!T>hrJQ 9ǵ%( ٦H  2?Fܞ9^􂂹ޚ?3q|T$3ނzEG^خ HATOx'*r#cxUړ.3h ګ` ֘\s(S )0>~m'<ޘC[1rP_nƀ#=p4D}I99MScⲖ}w}њohmZisα6Hk. *rp)HS!\{x' i'BxW$ cU{9@L{Tq*BccApc@^@MW'7j 0L#$dgMW= &Qtx䑌vPSO$0&y**>#pI^8ޅB ۚkێU +ϱFG'1P^{0~=궖$e ޫo#KcgޒTEpjvKy#b7q7 9HP(@yޚ.Ͻ6Uc1n(Ojj}'4*zr1Mc#ޤ.0{x8Җ0{SS%B{w;hqex]߿-ލɧ;ޤ.~1A\;|RٌsWOi϶1ڍqKpހ2y|r* '@RҘQ‼S X4B},)8F=i֘wQ'>l@^~۽^q؊{sis8Yyp*u:.%:b썝܂άG`#=}CÃݒhۂ}Ƞ|vOnx<^ &l jXv4c(?Z2$`gIW)mi<mS-; \;88#8WHۂWbFp=k'Mu$C~:V\܈WtmJ"$~xkM{q=c{њS`CQXJc4dGW} tQ.ci=O(](e(i%8CWMƙc3S-RaNWԀ}5 4l3_zqѷ‼ wvAi*p7E5SڤQ"Ȧ)jdgۊ[qdMQ\1AL?,c*qX$9I@8P뢨Gڤ.Q#P3WcS gIcB|ph?<MTS1 >*)r{})` 2ݑڙQ#2?GjM8dҶmOƿ;tMSC_>H¤h+D7A(WT`~97/XAmHrI?^. uw|ɷr8\d1prH0'ckiN-:<]\#k08.ÂFEesZj<\wT<⍹D`{w5R0>@>撏|QsւSQlc8~(vM G9&xPdR x S*&`j[wvQ^?M{;bb8^yAL"\}f0J008ic<d sL&N1Kg=4(wUIW#⍸8jsL/n9]dl~9!ASva蚎KssmOʤlFLW:ج*Ioo@< g:ͺbO}- af7%qľndvs?'ÿ /!S}B. L ,s$dy+./w^}̞q#. J+{UީWj`c98yz03)HG=f"wg@zaHc@{Oo cH08qA?1B3s gڧWcA9IHxF8[=hhhۑ IPO)O֨.{Ԫ?Z;=#4L 聒p; **sL( s`s{Q1WF{F01KfA8 8ڞ̏=VÜP;mi0=P>0oaj{[u f].uT91ܬ"L"_,8CҚF'DDdQat/arPM0; R՗AǨXgaxn-TN%-cUVmq?\ VIW5 ?Z@9 P`s@L{s[=~{S mސ_SU)Q]00~֍cLwSOh$P~i?>fw gSO{?z]Z6=" P\*Nj q SXoluo-=FeH)pp/Uк]%5RtObk}(Q~_A^t麭ӱZjs:\ &7M''; F8W2wm( }M cj g8 .0Gj[p=g>4xIQ?R r}9T=L ?6J0;ьwFـs`Pt99szk>ءjj09EP]ǑAdz@b.d 5@02s@\AF0) 4{)mZ6Aa1{}i <犦|TqOo)s_RjHw;%HA%v1اЃ=gdF9zM=RTzRUmg`֑^0oG 80*>jw?"=N1QiZOO}O{-i-VXmlcǬEBWGi>֞t~=^զN:Y(MîbawWH:w4t.^Ilt̒Dn2HĀn@ᙳ(wU"m#MیRǿ5A= 0h?zey@x4OZ6AFq%_K${s{r>mIPsLsqۏ?Z#4ϵcKn3WD1Fwi9`hю eNAW"~@zjCߥz[Zҵܩ%(^mfR w;mc.֍yR½|>4yڅ[໷Y2H2Tmm:.Q g[ԵM6EyQcTƇa\^B0 ڀWsRT}WJ5XnoޑRG֙9pOic۵0qFh -hڧon a0{~(20F>!}Cx'3[1ۓL`}(+i 63On2}0'r~[F=pHAoR 0GUs( OF>TUoޖh)NTٚ~{O( ۿְ(_kcJR˭ىfgE\n e aAn+/4ޣպOS.b_4˻MuK{Hl5Y8!63;ucUԩ՝Z?I%xnY]A9FUPmǓɺ#`c@ -0㟚jj^m8PW悹{3FnjBj0~v~Z3h+q-&4 ڑ^h =y=13ښ~*zi~i4J>xriIWn~*4sz`ccXDZڍiʎ3F~~*Sۑڌg XkZPV9gufn'۸wYql9uOMu/_u}&k:]5}>k/Q iACW rktZH!Ե2H h]|F c yyW+*sP~ig}'()fЫMSXLԄ caq4(,O,ލޘL})c{Oi jP jxc{mjI[K+[@[=*7/HʄFyϨ^6Q0ޥXK#,2h<J"y_;v, 尿~զf$Pӄ2gwp!#d8b26oI ENMy}-?Z{Fq@N~"@mُj{* ӏ~P@MF2i5[3DŽ!3MPA4\ ֘i3V| E~1Vrږy< w5* =F9ZarEۜȦ`lkY/Cu\IiZ̖KtK 2K+W LoTXLݗ$Q5xa׈=+a94Tӷ /¡8BU3 [z?3@ \r)P[{ F28L9#h8zxd0@*N2 H/z{~F#G4m{PxP\ Ԅ qѷj@A=X~8MS'ީ@A {)($sT0y=A9.2q_lR SL xS*j_&GTOT \uSޮ3E\&>XM[ՠd s l#3RB(qZKгhM>Ԏ6~"cB`W,[&O AU;;2 ~IB }V/-B{/AAnؠ .j6 U`'`AP~ Fџ0>jvXڐLU\jgA p6BϽ>{sFߑOg`1׷jEy繠zN@ @{S'XPZ⒦>L`oKsB@ 8oj7T*\;Ѱ/pҞ~yyT B=h+?14qqsTH2)#沽!hozCT.ehʢ_Ui;mrotV35A UVr_K9SįN[󠤊昣>响ۀpYO]_uQ7V4TΥ- "0m N n:oa GmS,aGRyrT98r "4lPF1J>2AjpsU>(P<_a]?ozAqMb9"y*_mPIA {0=?dz?p 1AA]AB\r;Lpjpڒ~B0;1b8RŁp>)#9㊕_%qSp c-/N/^?^OjhI,Xqßڱq%T+]BѱCK>–zdqsL@p*]@*B~S8 G<{SU8?zXշ3Oƥbgb)m3~!k[; mFTl%]NYOPm9[>Oi/SW7cKy=j"2mo8FC&HsGh#;B8}q!Jc4mFaxWT=zaF%BheQ"(CvAOn9rXCjE}Wލ0)~>0R`+K!eQu%%Yy*o,V[{SU8ޫn[Eqڂ4ڞ{U,c=FB]CM]6{v Ky"T-Lgj/zz[Q+ _դ4&y#k>)A[9#=&gKאy=1{ֽCaͨkjꖏ<-˕wuUKo~^\-|D5T$!9rwsPNQrxfv@޺c^{fW'4 ~~m۵X\F3IaXEqQ5HAsH/|(TiނM-WAQ⒨Ԙ+8ZjQLqSq]?4f?^|(U>ژ^hu?z2;) 5 |Uh"j>icQwSPA⬏RzhzOŪ(1Gh1-#+J:âO:uKWz"wkgBGy[0BlHWOo5ǹݾcϷK,ewA}O֬obխ}U8\a[ p!b+]KW{x$:+ kj[vAOG~hU0; l)q5\n 8mOօ\Q1TLj `RW=;j\_ږ~^Lboޭ@PGKT=PSS#B'L2`PF@5Q$-'׸^p{GZ6=QiȦm% Vh<8⺽AiuyZHJ$q9s3o'ow4n4+BLmJ ۉ$[d$i!#Ċd ɻ۠kz;LMEK,aFFV'xOg_ֺVK1_K$":ɪ@"Gݱֽ[ ˤ!No򦀟ڣo>cF?:}:]SDʒi3FpVVviXUݲ_wOjtY[Y\J0EwɔQ$:Kmޡ˩x{io9??%WqZ(ZfYۋ7|6 ڤ k^_6z~Mꨀ #k4 =ێ@f*|Sx.=+)McW9)n1x0RF4jim4Zq 4qL(sW$ R; 9>J'=U22;ksHG>)*wګ40jq?Z6񊠴m5A}TmnkQ9u="#a@aTH2Q? 8FU*?za{1_\7}; 5-BkJ\9DQ }JmGgP]T:btsrO5Y'b\`(; >=Q>^kia ^[ q#յݴ:bG H4- F7i[ ,۵+^m6aӚej[4d,fo99SɫQjr{QKh_z[2q*ڤɷ0 -4=ǽ}s@A꧍QW ?Npj\\)6_jER8Kn>/'tږiUQA\7B9 j^UNwP 损J\\9/{jhcB_>6f1@\{ނb)c4k}oj:ODV6D^#)lnee` s1SZ?/e,ٵ[X2TDV9DG%i{vp$fB|%,rm=vj>Aj5&,mcK\ie$6ڍc@"r)ST>dgޞ|qHЫjei93MS)5C>‧ oiN18i>#p Z]5-O>_(oM}#ܶ(MO\#jcFkltfiG*`FO@eYhڏMjZ撒QiCAf8@* v^`y&wS&F6GViȍm~+vHsLxMSv#Um@^,{}*c~Yޏ+'qOi'4 {yg\;Z$N=5%hHvW[iWb93Go`3Zӏu8;kV(3eU R;gxi{/YL:dZӑv TX' A9C4_kz%L;M.a!Oap>sVcU ~+3wu]DIW\g~Aצx}j~h.c-(.!2.Ih0 OmP_H\{qAOSTz{)*qK` )ހ4dbݣZ+S40r+gW4z$zJWڐ\caIPeۃںJ(X#= Fh cڨ怽N_aS*qԪe?j\{SGY=Ǹ,+%}?Ҹ x#GL=] A{yml>|sc k2kJK_Y`vxNOpMwz>ҿ/9Vy[KwvDU>G%>wI&K5ua;s0L~ ](::Z^tъ@!$E#ҠUtW\ZjL/kyslZyQOH yےlL'85;}"昏yo (TA6gڒ9R5^i]hw6Zqq$6 (mpA#n+M`WM'K=F7\XK1BH2nM.SօޑwҙBUEuG!]sUҼ]+*L +d3h8#\!@{S&J1BǶV,y|QٚcE捾ԊUs@Ny&ڍPL%8Wޘ\L PUhXOh4cjUW&ITS0QTWfRnI RE4N֛G*,Qѓmel`NAUt7UˡiwǦ+%'#$lb䜞+9Csɂi~y8 qU?O~1fQR1P>*{T @mL4mA)짴A|waB'[23( NσMTL/4mⱡ*y^c{be>fϡQTqT#!iH*z{j})X{PTg#ڬe[ 11F6浿tG>ͻ4qQH9 850j&$kob&Gtv9 I @ H|b螡C&s>ˌ,m0<șCWއoi=BmVv׭# " +|He?BݏQk մǦNum}<BFP(Q *AV-q6Q\ `2G`?j6 cڍUq6`v48> 1/$"@%RǟjE>ir~>z적xvGqLcAOo&kQ=I=OgEWU Zj(TFa>qF3BI'AG=ѷ0jB|%T62ږ>x?Җ,vkQMvtD]R^JDBA:u$L/oBm P"HM $ sOZNZL}Pu | đhUXT. !lZˤzLWC鞘a"T}~U(z(N7۞kV7Y~R٦a,ѢƲVl*¾G_<<]^O1pd><1z_k"GLK_A 崃w9bIQ4Va3=R M2; dU`MF~Kh?j[HA5%;R)yx8gҞ(Glϵ0mSMLJhT74dVڂbN)4cژ\}b;VA֠WK捇=ۏz{)\S) f`f !{\:Y\]/ Q&d~zWM_ڝ0!l2:ᔡ`篦K8tIBHmK:1̾B 3l!Scj)h!=DtOkipy/e1Ub+Np+Vs?DK5qbEF)m7lEM{GKe[mh;_ȬK{/ ׍VA[pu_WCWLFd?Ȣ2ʲ^0Cg?m:+K['[%F'z9&~UZJ6f;UmUq?ͫ%{J["01U7 Hoی֮==>Ҷ..ۤldcX|+SONCY?=~N@Aq@vFX{r[uM F53|? Ąq/v-=;krK h/?Kw4) (3++R &Vy<)D qũ9'.bPxo^~e`\w`I9@ xxǠͲ[\]%Mbi qȯD+Oe5^{SU 09 RTS㊭ f֣fnhj cZAyA_Fi_&LU#oj{8&8U>Ռ4L'5^j⚯zaxEXc?ښryyOjLаqKHqKn( P?(kMKΛo]Geլ/Z'[\-ʭ R$UQk^ID51LI*zCSg[ڌ%қiRTEp@U?Z^]?޻ofK=FX/!6*+UmH%k+ N P֗N 4΄w  VӾ7ޯMi;%UExn ǽoJuOM^uEOr.oyot? }U֭I$VZ0 ,j8k?qʰ Y?7N]>ao./F AbG޽c=QOo)U"3Ѷ}R~iكF( y|فڏ/& 6 oڱH$Ы{S}(^1\84@@[i P#ZR20q@L{2R <NO&5i>ޥ&ڇv=!sJ;V֮7L=8VZ5˲-l$ra66<&ԥn]Mm к>S,Mdɽp4 OzX-6xwfoDZ@#1`F=e9?=]ᾣj9qc=Ai??m6IgI%] n@YK1A|6T~&ZN=JwfVG]G[.]sQ vˣɬ' V2[X$7?!Fk*!6 wo8DG]cp_Vl ՂĒKGUc0>(W8*UD+bޟ{@5&.{TsS>*Uc( ACF>}*1AMEO1BTub?lsT23 F*ځVG;SUm8HB($]w:wh,bPI H];Fmb+tkkq-K39ES|BjTΏԟݪir7Xq!n# brT 6psX> @N?W8m8xN;v^YkxI;N.q2 {]G᧍k:OivM _6MWyTDi #֭ZEZst2^Em( 98a+ 6BJo[O4Mу;O3 lhLr08k+5/ zx1xV,0<Fm)iނ()@OF|AJ6ڞ rT#C@qkQF>3RP^MWi4TNњaqQMШ?X6J/ʰ9`aiIŎK8FA^Q>,g*wcǶh4*m'5DU;J=8yxg nL{K81`v{@{_?]_iQGg͝.")q?nA>qu iR].C|ѭ 1"'p`B1J f{^WcӒ&q$x)S< C+ RJ7~E 7KZ~#9dbI^aQnb//lGIc'1, 6n ލ{eiy1K4AF !YAw:T.4-eͤ=$8V;8}zgUH!?+4l'⍄P#??-=ޗ13Of2yaX{,_ށj;gޅQ jI8RzsƺRzHw3zyLW!d\>J#>n+WnXFd.s!_G_JmL7K%Otz$Vj[ܐ{ۑ l{wǜև㾕WnFL2.9jmXuit,Ms,rm̽87^Ԯ˨ۦՐ+ CNN 1;kWubtQFrI8W9r=En);UFv~y_CLi4|qLii~ph ޟ~h9qAGV0Gwּ?nӵ?R??Y6gqG8WRk)4&y [eV*7)B q3cz1xYKcs&s^>a5bЖeI$WlSqMSHڞS<1{3OKˣ\7Sm4Z``bk1NZ 0mCQ0G޵[^ҭdyK4jKA܅8l ORo))fE8$Sh{STjaN1A\6s{9+:͖ w0I/6w|`zWk[e}P|y=!f:(ۏZG$kL^ Fe/ӯ^YLʪC:A7} x/N?ʹdHQ}:/-bE(k&G#2;A龚tw Hm c@dFϥx=i^9uezŭ,b~U 꾐i'Q`+h}Bv9$,:"״N 5cy!0vK0Hl/c{o:W=C Ony$I (¹͞8YqUqS{SeqGp*zEkHQ>-J6Ohw{iR#r`v;H`ACʷRK*H87X]K/HԮ-*WpXV\1/r]ZFs`WK#%oS^4tN zVMFtۧe@H{ gI*oI 03=Y kfӺ:d~9VUJ`?Y${VKM#pK5LЇ{r L֬CzQR&z[@ifEy@RQkxt v.ȗ6ĕ8R}ZGSm L2JRa@' $;HmvV;WYbU ,[&FL~V-$0Hn;MNYY#[uYfemUU.Tmb98Xe.J6s$sxkrNuH`t&)^0!#t*@bݻ bFz>4gRZU*@,Xmƕk^, ql1xA*$ܣx#;'ZUp|R$&Frlm3[Z0sVNRcف`TSX AsU@zBҫUl_Ur2(TL5>b\NIX_&j߆ѩ>P鱻\$;f#\[r+ kPiiډnTƆgbA#8 2 xZj[DI[DAA8cV[ !d QUF ~H]Mΰwt۸]<]" m`Gy#I9^╎MqPI O9+r2H\g^CIss= $"G;&^#??>s{ahDα2 ~O {:"KI !}5[64~@|c=EDCu=J-tY#'1?FGy6zJXj}vѕ"ڬB܌׺/Xf,=6Nʶm@!2n?:kߘ>E&μtA #XċPl9wM>i᥅:ơPj|0лfUS3SFŬ$4;]ėvš̃hKx)*=QsRu:im%mRXac N7qWs{bR^ocp,1E hm$ݸwS[-2zӭu;KHZY[M99Tf*8+=8ρZվi+kiฝ^Kp%ڮrѓع$k=Q=WuƛiZNf{wwTbmy.䳶-kIw^jڭ sql4Pv `A{sR5Knb\(]!=#S ' ȼ 1ǥUZ[$rMsjn6lS V8'i;]\jȋmh.2#.-I.ΙG8aZR]ͦѥ3,O`Cr yټ/^UIwMƪAI#`ݒ+e$c,3amF쫁<95ދak\ <Ն6;w7rAϪ7KX8dRQIJ&ݰ vIǣ4sooA%ƒ`|s3" =k##)-OAr(ǵ%T> >+}7LL!IX!F>#\W GUkkɣ__GI )f /p}JrTcHe|Cqi!|$i]}_Սuu63Yi7G Z row_+Mczӡ8m9meecq:'缹Yn3 0T''$ԫbC+SMIDKA$s-]dF!R~.ϩȯ%ӵ LS鎀 C7b.%̾G ;񷏚~ԟ^/LVu#Bd2nd Ap!hԑk[_3Ij-Fc#Es̉uAttX:ed9;}W㧺6>6wpőO5pPd?NӤt׋eyWHlGlT6n 瓶ho9T*ecå H]SY%WGVM}[+#Ȃȹ:O,R}¾뮓mFdY7+'6 z~)qL4c`|F6ywCIc$ %Rr}[x{.iHtƚyUXaQ>^Q؍dp2BůiK͂(BT$Aݵ=hM{, Pn9bΪB #'j݀y=C-$=Ĉٚo nS!%s;9:_[߲0$XX9 rq=k}a2]B1g.`cpqVu[3/Bn ?$vWGCw73Y*7*PU{}\+^񛥺߭@n$;nJhݸ|PAT{R ~@xA>gmgrn%v7I4e6 32ofuIZFv6r%9I| R0Z`I#D&uE *ZN6ye9S4*2G"4`B tMH6>[pMOaz $ -u#H0%8W^"iYtպi庐8ݝ#HU?NS۲ȂEjyARS=.VҚ.9 d [s+F |k(.#Qx $JU]ɗHB0j:捦[5HW m,e^"6Džޤ6J Xm'+q.mB[abĹ\⓬cEmseworf !CV}(DhZuIs&`_%b=Fw"lu8mżɺ&qHӖ 8v[Q)ijd].'ĭ2sz#os޵=VMDB 2GIȐ>2>g7aLxE_:CpPyWMѴ3e%vV֭J g]@ @'0ϺM[OI^i%}I dH<Vd|~q4mCaߐ[#^nJׂy66 }1cvϧoj.gqjVn Dqʍ :o⋦N7[^8įL3!>N~-W.RcJcڧ8ǫ nުNsKv;&tTx֍ׇA7 ST{ry-XһM&-'MqwpƉe5,@oLM[Hy4nl{AުXfEv '#!|PYŽc̀q$(o%оӹBLxBQjI&f{Oml5Η),Pivq JV?p֞F.h/y>F>Z,VْݔX̆`2ǜ.s2ky ѥA*m0>WlSk0Tn v w|wX޴"{g !CrO'=n@͸zCMjtV8D8YV@H$)/ezVHM l #9>q.%Hcs!`K#9K iwW 3Gm ?cF?W}G7dov"nXcH)נ}㵗_k6|w,"v~ޠSF']C'^֎I7ot# cr?.+:]>Eӿ7YYP!l/d+fn4?'8yZ(ڗQ9.0sn=zF>5w-ξ.$2)79e$xx|e+L>B#8 |]e/UjIٴiX|" 0[ʦ~==CwZ6qY߶va+:D6Ъ {+g[EI|1p0`8Q/K=u/.u;mV~b(ܫI< S!l _` 5{\bM0\bUkM7I.pRF4F}ϰ<םOh#k]:y$gubv*d2x2T;d1o=ɮ :iWO6٦W blTvkxu; YљVcg%sH,+5Bl ^B7w?\T~id(2iv+n݌Nϧky< DXRK3q=z޽=ƢG9v )'䂬5 ^?7Tʥ< 'xM5]UZdֵ^u̷ˌ+ l;A!܍C?Si:tsu>Cm! q(F!>;H}!jMĆQ<({} 2ߦD.jUh.q1&BS +p6pc S6nG`N7Nxc)i5yonY ~QWldgÂ鐜#cIiaWntV9唉bD|X* bwj/Ρ{;K[<@,;@V`Ųk;B5m`\oldERFZv3 S+ෘYU9wI957]"BGrH##]һEI2J\}Ԏ>qՎ]]\18/u<ӒGkyl(dT\v#~8nr43,w6Onʡ5\ ~0k ül#9nP98<Xi2̩?Mt!Y@[siY`Zv`q6<:=ݚuxFYP'8'j5KHoonđ ,|d?`O|<Ϛ`IA=v.Nm !]X>[w)wm{ՖMnO'%{¿Otb^㾰VCIV*W#] !)S w'N;Q חPȰH!pN}5ܽ=u`Kaåje8dHfkVz5mpɪ^ZE%xh Mf<4ޚ֭RI?7Kgmv@9UbAC8 }?X(/(%\ڋ/SCHO?_uNtqp2E[ݬRXCrU nu;A w0VCWOxwqz BJ[B{k/)*WZLV?=zFi9|rCOӽQr˯hV2r\F6%68/\t6P? wk-Z@#^TcnWһ{/_5@z?5cn,^Pg ÀB/%޻xo8.m0RH#(*Wo N(.LM ~kyV+:<d90\zAֽ:OQ0^XErIoy:g +r}޳Ӻ Q fr;Xg 5K 8+ZX\όQ<=?_>k<﨧AqR-{kƺu[kǼO:!,A*G;VYIqu}oxK[`UP. w0eRÌiӢ4ԤhLҘv)0=j:qMlmf4*J-U/e =9%L$k& p ro'U_Ey%eLgI&6hTTP3ǫ2G$vf[fӴpnR$,pF{-J,l  &<[#,S(xYQ9'+=Ak^B.a!]ޭ,NvHfGuC=]JĘ-\1TcrX [N֬QE|Ipqn7 ]xX|[[[(ã KU75jnn=3aHxH,$WwOO7_F9cf,F!PHp9a,-Rqg\4{8Md8m0]6v7 ֙-Ko DR{a#BĄ@Nns&782GȧfTڭ'9fl).t$dnrN2WۃWB<x<㽨%wdx*vcc? ްv;/,v̰lqk#*mѧ}dxc<{d`Ҥ3V!Rf]/n2 pqUʃkbX6F2==~Ʊ#8e |.ӯeرn(e\r UP׮5i=;CQx4i`$](]F8s_#:_K_,[- /|`:>6LT9\nx?Fyhz~qr˕lZ{xΤ/h$Ml‚}';cՌq1è\Cq~w N-b`HiHl2םV~^mj.i"vIvǕ<Z}f>ӭ<%;J[- *XRy,R:Mg0mOI0L̑񵌠 ȯoG.O zzGb ^@vS1rx@=vu=Fuym&[Cӷ-#$RG"gvIWW+Q[U3C<א2[yiUď`;'1A5r< n`1~=#nѺI oo_&#b~p8H$a䅷KX*`xl{w&uwagc^Y%3eLmĆ`~>oQu!=c] )CX*$o #mz$yRqa1$ɯ? weLԣY s`pHg^7 t/S.m'lDbvLY>0fє[kZޝV_WY7}a5%[%Ics9$sGt mg($ t$1nd;C;p_>skUu:r[0\nv;kKSni i#YSjdVEִ/è]'%?;s(ǧv f--bNe|ylݢc bcܱY2ka4ͪ,6Q[[F*ʭĜ.03ɧ=:R ؎DU}rޠpBbooNNH̳JY$36*mhZrk1\J& [`H$R1֡TdYCMwG~yWX#)QnXv2rAxCȒ1ϧqpxnRgˎ'diU@0 q_4A;FsW#F\ŋ#wnhB8e߽vu-Vߧt]y$ۆXyZ2&d.kC籕so94qL}7cB^4фl3s\·EpD?1f bB۴ QO4FNft*X(ap?-YIU!P ċc  Jc[;/pRAA'g|Գ\O$q&FV w+ yiY9Y%)0W^~k|iVHme #a.A:?zZ]OM(EtCH\6UXmFv3կWFkFy H/e 3 Ncy  _c~o)z]]uW.bxPJbO;9Lj,{1e+jv3{g~&< ܽ=zW/zxg'UXN4iZǵ!mc9`)|I/Ҭ涍f_:pV]q*@Pq^c[[a <ΌHٚ_-!?GzZGQԬjV;-ϖE6;./"D4J/! (j,㑙:'H"lddJse0+~ g}6)zX.tY! 4ʅ '!J.o zYnMcO&:}@öp}~C;zKWgYG-"y7"!dkQT\{[{8mhvս[2y4Y R5 Y['jbAk", }c*I'ֱ}l#{&p@9 vpEsZ]XIqFAI!Tz{܌VO@UX.HW,싴39RX`sq/Śbyd14mryU$FY-[ $`ː@Td׃+_0A!R# HQ;Fs.=\D6[C)e*hʂNrFXQyFg&(.-XFY=Y*9oIے5͵Ӭ.w$QLuS6IC xZB1#nHOWe#,x.bed%!!*1 mCΫm /`Վ(1|+#|#yv[Ҫd 2HI9>{jmY9s9]btnYV3/r#Op-E$jF8$[p98`ݨ.M E 6yMU0[gY .XJony"ڻcTH4kkqd˵[` 98!SӴ'P鑬#-{60 TIOoցt:~oj.^$\*/0A  Qަꗾd:h[]S#v #, m\~go'ԦEt؀Py^g2q\_YuSKc,P&L; n _iIu xkH$ Fa۷ A֢(Yfu*Z7|q26*3%O|j$?sXn3*ֳ?to8%## YF1 d`q߂q+[W,*w+^+)x62zjYpDx>`ffuX<0O r{J٢iwZ1Ap8͋sh<G}OW{W( $( {cO^[CKH}hldGb\ CX7+z8RI>9A(q<׋uPy,re'_EOki2C&Rgys6 C2=55+}iSi֖c:E  9lč ޡ=Kj6WڕRmi%C7#VcB{Sw]ihc.JV= ՒCqXO 0ivUԚ6iJ[[Gf%G>x6=-. Nu pUK\LHrwZT$X]Kz&"e0Ic c -՝My wVw:x Goɾu;+ YՌ~rBv)$zZj:f=v:DQߟ] m`G\ʺH̭m6q{pJ;#$VCK!A[q]UQH|ocv$ݲ = qZm栻Hn$hFTr7@H#1hlǭH!@9( {g<yGggIWS]Eo-U9h<11BHom6-',gprN iOޝQpK"F [s""0 [:n#QӍIk'UP9璙. wM۠V!prz>qE Zĭ ;f`P('uEaw-[GkoE@nMӸY&LLHfe,Ƹ:MK(MN+y.%Kur8`=]MnIl^{ן:3K-֜#ݱ]1{T}'֚ݶ[Mq}vݕ]9l*+[A~A{;}Nץu KHxQ;( p 3]<o bu.>q<]Ć5 %sIOtHRKu P[yHa`֗] guBI)BonNIds߷j{V BB"I tUPwDKIxڱR"hUȏW` =Gq9O:Εn`[,|w.FO`Iin}fONCO6܅:v{R,n?̲+>س2# 6r~Ӌlnji3+Hmsw kz吵Xʕd^\co{ՕE9E$HoZQEo."oۈf'=X`dcz)-7@/"K"ct CH#s9=pVS. X9¶! 1yL$ RG8K~]J2 G9#9?[bY" #nr;.Gge,$cw#׾jWƘ:$qXpHhyoz\nKhĈd1N{HhEj}K_62цl8O| ޴A[O4څ×}B9 $b<]?x`2MGل?H $,f;{+tG]{u[mO.yjK"<07m*H:С5ЅPzェ+^t%Zhz\:i}?Y Mvf+b>V}o U:1u4zzZ%h)Qxo(GLEly#Je 2n8'Y#`16'r8 H J/m?Dֵ}ڵ,F@W_GV~N "׋,豴!"q*1$%&uH=>kQ\GlН;Fy}&C.xfX7gv='P Frz ˼B 4MW[G4<>fa($ ln8ullI7Q4AY302T c u^ё#B?[} eUpZ>OGeosv,Ѽ260•9,J|Ws4f+HFfﻞ vԬo% w3U9CW ~Ԛc\onZZ5VS؅յn캒;֖ rT%zv,8KsEֿcҚNEq'S(\2{d21zE[yT` %F օI h D fW`~'89tWP]iIpwi2KRn8sOaߴg舳@veaH$WmgRduDEGg*y,2(>Pu U:țex3!_!#w%(F-Go1{Hk L NKQbW95.nh俿Г֏qk] 09!rVNuGP9$GV1I%`umgKYֲvP<*_qw6'%O;Y$fX RC pH*H]jĶ֟ |K@4nYd2A5qHUSru_j!%Pjos_$1''Y.Οt^i쮬ro&e<2*~"=fÙtDְ[MĠmņTqnO8zE.'noYts"~ b@WkOl3Oj[uOMZCLy/_Ŋ4 uX",>R;u>=8^/L8۝ɐH)PPxs]]7TMtT˷r+%ďWWП?{ޠЭt vKo^h6hXbp9\c +/oYi!UUO)hij8#Gjht=SӱnKzȎنa>I;GּXk.ne&YZG.c'9XFL:Smc\e`¢oNq݅z^ZVm-S"^C+$Eʂ`@$ܨr-/QkBY[G91Qxyӽ#~Z0?&,6\)4ҴԸ>Ցϩ:[T ,%Ao0'vMBprʯ5u|D]:I;{y se6+z⼻K)VMeC`*<3WKCe=F3cZ\ȧv8ؐx) ]jE.# pJ)MĒ`iU3O{7QZiwAO+njr9Rx淒Lc,X4nn$ OZwpF-(_)DxX1{8&=uNzǧ$o(̑<)db nzYk{]mڿO$R[j rXʕ7-`#o>bu;W1=%fH VUG+V%ikܢKx΂VS H 0.bGCS5kNJ4xKXX]2EhS߈=/ӟ-:NYmIx 6I]6V`=e[5.oo+yb-I $Ds$Nk~^6dc]o"ZT`B4+Qx!^/G dԭ 3)AI:,^'m u!ː7$m^X)|;%#lt]XgMt'PMٯc,ha HURF$x,OivzjڴeB7#,bb!XkntMX-Jش$F+i"noVm^Utֵ[ͭj7zuc_' ţ66yvsZn׺jQ֭-:+HPD!a ljWk0ǺN^.Yj=@~Vribut#)V*^wpI޹iKmӰx~($inM[nbE8\@Ӭ㩴,w yGIeWgF[#k-j g:xc@=cX#Fq dBWzB+z+uB?R=>#fB2*GG0@1}oa^I$WW3̪.nvPKk)Do]K:-,ѝ͗F=FkOBQ[.}#޳:-vv_3v@sq޻HM,32`5Ӷ#g143瓌Y.wRQ6%SB܌1Gknl'̎{ëD;r;}k&^nYYgWIEc Zƥc-À$3cnyZwëBH? >ؚ kWK2^6S;?ںij#*ͼ$Jt&+).#"FH%@cʡbJS;.H#.-6M:K-gۍW d9_PeMRkn.giN[< İ|stFxcYyB;cI9s_jz[]EomIlLYD0Aa ~K5oˤO es+I wۅA<=E&yeq$7$G/Tx ;{puOf{9!gYf,n 1am5fnXA /;rOb?Q(Vi)q#y~YpNkA!\2O2  d9\?MVT$sk=^\mNAHryO.sѥDf <>S}EVW0FV ﮵/5 J-vilӦʾ'3y9O?6#GR-ԇRhOTR܄Y6Ij>ӌ'NZDriR`3$oyc3s[.нEMoXhO"rc, 28֙]C?Ph:ŝ_S{=1 `pr}/ =C[Dy&@˽ gH$Wvp)*w>0s9+.:*uRUe&2qʐw#2z=Z˝Yw0Ax)@2C36Nz#ōgéjA5(d.[A3p sHP8e%{l_>_-ؕH7K!a'~tOkIUR0./"r^{ +arR4*P e$YOPĚc +Kǯ+."V85~1]Qӝ'akeMҭ[:MU F6e 9 jpeg-decoder-0.3.0/benches/tower_progressive.jpg000064400000000000000000002050650072674642500201150ustar 00000000000000JFIFHHExifMM* (1 2ï%OnePlusONEPLUS A5010HHGIMP 2.8.222019:11:26 22:38:11.6"'d0220>R fn v  ~|0100 d2019:11:09 10:59:362019:11:09 10:59:36)cddMM*3AD602695602695602695R980100N:ERjr 03Y'('+ ;$2019:11:09(HHJFIFC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?.)إ{3i3bq?bQm"=#@Hv\umXXO-٢e=iLFړmh 6Ѷ6F(=bhF*LQ@G)h+Fړh(Rm@K~)v)qOh&(@ I5/٤lm ^Gwe+۴p[9B/ aGҸ1U ;#:rlv)vK8mmI1@ &*LQbF((I1@ъm2-T K\S3P!hRJ1&6{iqOK(KDeV :F=D\XI_˙C6qRL)cp j6?Mc?+|cn<\S ZBv$.)^ F)&( #F*LQb#F*LQG6Ԙ(1E 6ԘL.G]if1RbQP{iqODh8'5g\л=tl k*t[Zp[ 1`=3:{W=ռxK,w`/"ַ21 zד~kRa4kGFړm.`G&6x&6[ivԛh4 KS1h`@\`Z].]\vvѶ"KK㸠:r*McHd[hS=@"3*3nA=)o% 22R>\gi_[M*;Gd.FRϲ8Į! N8y5nh|[)6Ԉ3%(끚]SwgQZmmmKmY;hSmmC66;hSmm !KFm6(i@6c6ԛihXf;QFEhSNo*]GU}>|<_,)lszϖ.LAJ(/-K&>ߔ0}^usw}  :S ؂E<Ѱ!fϕӶjZD W;u$@Szsx^޹+ruV^qߓSwN4-ԌeB=?ukTSO"Fʛmk{"(Slm leOe mM!KK;hQE{iBXˬyH҅|F9m;m?e..&KWvUMRk{=2yxNZ[Eekm~ltc^l=;GuqZV G8f'TV~l2@w@ݞQ"9c_1]`T).+KS4lttu2Qa5 wο-E 9.]r2p^k\{Ick+Ag`I3^pr\NLl}.;iv(])R"1nʟimAeOs)6=G0rmE4y)vW%ڝ=mg>+b5V/*Mt&KR-*Ph!6T)vQkץ"Ŷ.mS Ej:e)c7H. 9=*丼I#x7 7?{?1rb*s{Rq\|1 \KFUH1¶5<:116nm;ȑH,r?^NDCqV* &u(SrG=3Kp4N@8>j}=Մ̃qEJII HHNkZŔv맫$/1l`c 57O'uRyxx tfYeX$nOeMs!\{TiV4gv 2I4/c>&RK&J=ԼUypBA/Ljc! 7gD0x(#:R3y0e8<EgO$LTcs޴,:?j֬aUqZƲdJ`TKadgc>]gm#MXWQ@a%j3byҲ&[ٮp_\fU8zvMT F*0<cuܞJy3h`Mȱ\b?v@>8ʯSD;*mnmmyύo&(j(~%3LۀTf2 ͖Gt8n6H>dW9bH&||z f_MIi׆Y #[BI%FIHC.X㓟nZvL _VW~Oojs"~=dvIok Ibd'J*Z4`퐝q,@$[s>Y3U%޺OX.mg̑H'G\篵9=[١O.%F%sj4hix5ͩދ:`H9jܷ"hfM-Թd-J64cl;FvY7H̡dqm,5Z d &GqVӳI.CYJdEW%GYsPI@/c(KF[,0@r3s(e""D#8#oCp.Y84QI7aO,JI+S~gNk3,I`mçҊ*nݒ"*?JG " ۜާtQN[SXm%W&@8-u{Tzn,vraߞO\GJ([&~e++滐I!a$[NaD1G'󢊧3M܆mA#eRPH-@'j-r%Q&)1D@ H:zEKtCD{,q^ H{¬J##~g6Oz E J-Gm "XBGF#~UG+Ehݳ8t{E8#&T7Fcs`dMQMpL http://ns.adobe.com/xap/1.0/ OnePlus ONEPLUS A5010 72 72 pouces OnePlus5T-user 9 PKQ1.180716.001 1910081948 release-keys 2019:11:09 10:59:36 Centered Compression JPEG 72 72 pouces 1/1547 sec. f/1,7 Non défini 100 Version d'exif 2.2 2019:11:09 10:59:36 2019:11:09 10:59:36 Y Cb Cr - 10,60 EV (1/1546 sec.) 1,53 EV (f/1,7) 7,40 EV (578,68 cd/m²) Inconnu 4,1 mm 23 octets de données indéfinies 602695 602695 602695 FlashPix version 1.0 sRGB 3456 4608 Sonde de couleur à un capteur Photographié directement Exposition automatique Balance des blancs automatique 24 Standard N 48, 51, 16,3929 E 2, 18, 1,0441 Niveau de la mer 76,711 09:59:36,00 2019:11:09 R98 0100 C     C    }WʩV% B-IUDTRA*R*@@@\i-ʲUj*hU  ;9;8ur P JB)E;"YTK- T¢ԉYz7ޏ DJ,LH ,Hcʪ U *TIJ?zU ((Yj@B&;1PPKRU!HYs<_eRZ-T@-JP(PQ`-BU) OپύdE"UX D-XǦf!QAaeP(BBIJg/ ٬J%\J!HR- UDՁ:fb*T@R/g~[fQJAeP@XB)(T@ Vˑ__gOo=m Z -!RVQ@ FUDV-`Ɇ }_wp*( %8&RNHU(@R(BHRNL_Aϻ7,|󧖔JURHŗQIEXbH:fH@KEB*-{Qzxc&HUA*E[b tLBQTY B% {_?bQ-Pa!TD)HP@Y3%T*TaT@D9i|ci\h @TPJ1%XPR AILߪAD -@BV@$:P (rZBJcve_  "[HXB@X K)e%b!`B;;93䅒)(B-(R\XU%HUT*%7}_usmJ) %-IiA(RE) @Y?atnnב*JejE@RX( P@E(JȂ,J* ,2/ɿ F8V (V )P@ZtJKVĶrPV%lA (,/3]QW,ER%RЕb!HV! "U"*yDPG=[:S46lϏ,EX TBH "U*(Vĥ.5bPWf?F|N QaQI@`B!@XȘ9䨴duԅ V (~>Ϡ|¾}_!UH!i@BDAeX9(,`"PUTl{w-Myyk0:HR@)* @A!bBԕD T +.rq- TO|vuu/_@(R@`@bURPcWjBgўPP BUfy~=^Wwp(!H U )yK -b)Am@BaFxER//>ǒӻy=/'-J"`yy2#,B %R gӞ=?z[/;Q}/,@RRBieRBT1.[T(%ߎ}Ya*Gj8<'^==O @BY@i (*dǑB‰@ZB!JӖZE">z?w!VP,JPJ "--j!BZ){qˣ=tPi9sy:0}?7s>T(PRP HSlY@j>/_>~׃{Ox@XHU*@VD/)yՖ)(T3re~o=(B HU(BL lJ՞UT>whݏyޢ2@(P b-^iV1ZJ*YV9 oW~^{~=K h!@JYbRPZ*Q Ai)9]ybTSKxs|ѕ/n @bXP RYIʕjXA*PH {zo7/k=JɒA!T!@*İP iJU劯 BV羏QrtwoRU,Y d% YqPr! !@x :qvvj의ׅ<{B@,*"YV JXeJP-[!,!HH_Mx*rq|%` i$**dJ cL Dr*8 R<_{x~$[ yqM{`%[   F+ QEU [D\J8ͼco~vىg_abQȳ.RY*Y(P YBU`YmYV %R4;~3q^S~Kfv} >YĢNxgeew& ܜ^ T YXpXd*IZ}XeVϰuqR)J !Bʱ;iϮ9Խ/+^9<'wɸ~ߣceن|7ˍYeV̰ultx/[8saf95ztwZIK-QN2G٫ke8o+8fWC.N;дIPD M[<g;z6jXܞ^}ߩ{7(JPРH^sZC];÷Ư&q//m@BR!@PTcc~IzK~w5Ėt]:[=&kYwk}ޏnNS!̼_,rVrfcڞ yN5}7oj J_=~YizonǷsuyyXm>Z=?ѥկ׻g7YV*XCy>Nn՛[,6rNycullú3a)JDK9[ Mtۏ^w^Ƨ_GZyXxz;vcwJ `.<}uמfE|c匳ag׷"cvvJOȅtuhϻ6FNf=gF9|O0yt݆u]Xwa>:vL|z??v~~]/Qt?KӫtzGFS?cOgѢݯ^G yɬ_ 2ѿދF;z4}{X^5|>rrmseuhe[1|:ɖFXhN۲g<\qvq9.qsfF?Fm~ݯZ rftm^}z=cs^?n6L zvsz',r#,'6bn8̰kf1rnLvˬه|yb#.;1{7?V}+/jݵ)#<7zN[غy{֯\2a~z|5j7ż:z9\c>ӫn9귺1ۧ-fdjû^ztoǖ7,iy/ 0sÔg}-/y|2ea_Y˻15|n{9W~z+V\YLFzv2.<4&F'[7NA^s&z[{qtriz/9ק߆&])o7ѷ <|7űt:8l|wjѱF^_&ݗy[Yt,ّ56Xqtmճ?FF;:iz2ێ<+.َ~t=:|{q}O#7EKՎ܉ /)1,:KMCcnY2V1yo1R5J+MMt?n?0 )~/w[ۏlbْDzҟmxpEL| ibR]54z~-?]*cΌR2%"{OجyS|.Xؓlv tSC|V:bi3\1+lɀTgc+tWО^呣_D( hic8ƈ@EߺL l͟G!QnW;̏\R9:6:X2^[ [c ‰jUnR7`HIP1B.V=u;<z|~+U3X鎣n̻ ȴq.i+uCҷ f+}[X v bIT5ԡ;\{Ǔ1E*g+d&8Bk&N 2޸Xy1{K`[) "Sk2ݤ+L{Xyq-@`#\fGI˞|V+ǀyX˸=F#ѹ#_ oqe;<8cX{ѵ5S >&IW#jAYdh{[dMTk--|8Vdm:z}m6kWy%D3,KcfiwJh+6ycgÐ^ϑN;GFG8cIkIz¸ȴ]SS:X[jCc)GF\e){]Q2_z-/$}M7 ޥva{isRsGHWjM3[Bj#8W~U 69yIUGZ];LsOc$<\M8/Db?M +~ljw2Dkvvb|w3g vFQc"Iܗi=j˶WiD:ǻ6bTDg ^? kU UҎ5Vq1"^]wvzlb"'2e^xn"1ϖ7 -#gøG< 'pM,x )Y"1DK^'iH ͫm HDXȼ{Ok`kKfx_ oGmB>b-Vsd(ڞxfP aZ,ɊJ]<IrƼFts$$ K%IQoqYcG=xH%CmpUoZ!$5ۊA>`Mu<Cw!Gҥ*Ht*ԅp&pn>*]걦iMD<_!#$ˋba%ۙn÷(Kt&Llq.G0Ux# ml%2AðJݦloFVG{(ƿUhE)aԙ~?P]+Z(HZdGC  rXhYo# R]S{3^!^J ,lEhZ,Շ;d,ZoӍ4`Hn)$AIt'^\ds,I̋w)sm A ![6];CbXf51m+J.1V2!1 "0APQ2a3@#BRq`b?+ν~8EvrqߢG O2~k.deFщ&%FeSwjGiT8Իg^끢?]~^*NM{H޶8_?}5x-{hG% Tq5I{ W̱Ro{Q7FO]t~¼F24~Kd)nvjQtSfJ1Vݚ[O~ëūR*V/|yw8ݗd"8ޗuyl='gVI]KKc|ǣ4=ޘw7dق09NSy-L{K} g,\.W/_/|>b4-Ж>O!nVU#iy54.#Kr嗩~&IRG_F'FE(Kb\zOG)r{r^##ބ*&(Ҕ"GǍ ކCKEOcBLF_iej2'+.tvZ_ȦI9rdefKj$贷:&rRZ#-.7!BCvո%{ۚj3K8IIJ.Jh6B%mGԞbgܷf#m9KclTjmt.OdxD؋Chn,1ӒrOMzо}9_vq{ 7,#>M+䨊Z]Ŝ6jNC槹c*ɓURI8u;GEHyMHսtv0=R"2KݎW+kϭ:Pv)Gt2'U!={fťԥfF"2Q1!1 "AP02Qa#3@qBR`b?˛ҡ;^|8K`/fGd}cE{Wra%bnPM7,'ޥf&{2I2Eo |fou%Ks)`c^tOν%扶7s}Jө/֌e7+8vx~f1k,KlL䒾ٚ':mю6gSiymuF^v̛Eܶ4d>UGHi߸%8ij/>̼?j> 1a&H3tcT 1׷A^4X=jf'eOnbǡ\ }㷜ɤ؍%-8گv[d\Z*oԅ,cc8K=*5} rK}$G&E ܖ '≮)6C mkܘ dKٳuF)ip>o"=%]JԆ'50mĪL0QqL18f,# F9q-c-FJ4}EQ{8~ǿҡd`\5&IʨO)M޿ʍZ~a䌥qbnLp׉qw0Xw'-].],xZ87xW1GJs1bvF?VpSJ./xJmQf_6)#rp{uvK{2A麳C8Y_ۥdr\ܪ{֬PCC8>Rd6p2Qe_x{X \:a)8IhYeYe/r;7]%R5T7,e/eI)}6cZa9Z%'=z/Y|lYe_+z b[%Jٟɝ2qF^8iFQ_ıJe%_wBq{!ղ#=9c.TW.ƣQ&_/\D VάFأ*]>ƹ}GUEj"cMdmr,eYee8vOK%;Yffͻ6~a)S/Hy} jDԨ.lkǙi9w%JCșƾ㚑wuYe>2..̙%&]K(DWhv9-[YgQMΣ:^YkW}uN:cJH]DHATtr;*1̍@#GDs[Ye_2X(yu Q}4t= N#B )G Nđ-JTJ;[Q]Ɣٛtf}Qћt^:bG[F̆h|zIcDCrѩ٭{csމ:uEmnFu+_<6ܭa;{V捬dJՑ"brم4ї[ џoTǹ*+b cTYe'ap?+  !{d.3UEۈJΞ`^VYe>6(} fÚ]$[cB--K&DW)ŶcUə;Ν!Oo uCHrsd1Jd0;Y|&'2+CXV/R?5\TR-x(Hf6O#+DbH=da茉P8̊ *JǍF:t ӽJ&DEodZ+{ѱ%lOuFEJȺ5uC̎Tm:U&2\}JZqYD;;GӘPaיMʴK#϶Gw J10=5 uP Jʶy]ó2)ACEq;0/ 7.uԥNJAR?V6^lh}e.6R"|Z=-D %\M L}2*>'߯4P ?[MiS/4мB=yXByʞ8&Nz/eV Ҥ`P{ˤ48f M:0X+*>΃)uonگ7ۣnTϴ/ /I}ִ fTO>{kPkhZKSIzF^'cfVY^̧)eNOP˟vJW]d4Z Ck2P.]|=yoH-rb[%ͺ\ZM) Lk%ǒڡc-xO`kyL%6L_}3 C^ڒ8 Taٴ^ o! ~N)esZYYW -miG:{#i(JܷG֢08mOΧjVqJ5󯿱vE\ӽ,M9g.!xJ{tJu+FS˻m_yyʘZڭ`!B7㧿XO7>4F\♟XW0TbR=XO9|:x[]UW}~9B\SF+G  1@Kz[!ZĔ\Q<n%r>]q >; ̓|a!$PS'^Du*>탯Zm幐PQVwSXt ߹i. Tn!+uw!ÐђLaM1;cI0|3+2?>XqG E[AN4JK~4BC}/#ւidD+xSKD/GR9k9v-KY'^*NiKJh:!^ˊǼ~2S9ư<ذ־lFcչyxd%cZ(V/yH0pJrFFOt^2җJ0PtUZ*$:Tu#f)o%izPu^ܾRBB毲[JGP4_|~K4\8Tқ^|g_$|>Bҽ{i=PY4ׇu*¤->4* i0y1LlO3H9idZ@N/9;uKmCay}c>] 6d:VL;qƖ9Y *}lۤqصkݺEb1K1Ju6Fw̤Cd("ȺMefm`-'W'^vn#,2^q$'֩Q`*UTZG2MLEǟ7饂M*Jò)3r`Ǖ`ז(}=aa§xs/UFG{We\SwJ?馀/xP_#R'짥ZJ[?gǴ?3Kqګw!l]FwAϺk`p;&P+,. #RۄV鞏#OfE7O)Ï{K )8稃m4 eJġmα[ 3!!/F|&WjԿ}YMzBoC)J1;FW<}*Sm^Sp,증Ôb1 7bws̙?2g;5()CF J7'CJ/,-rM\>eˈM:`xsdW;{oe) gm=#ۗ#V5>R*4U%;P):e'nO_Μ!B6#頫`TۖLO9mJQ".qcbn=}G5\<_f<m#olQzXptVCfƓ6onT5=yI*JBD8=)/GY*i)r[%`pn(l)[ &*RIs>Hb:Hm qd-ҳ%7uuVtZQJ{8|#sHWגG:ٛJb kdQ+!zM5+ShlqH58\ivffO~79:RTF]kf gh?JAkpp-;NiJz\¥EĬȹ-_⤲d[ !sX-ЖKG{{?A$1W@\U?P}xGF%+iYŶ_-`9V4"]QѤ1MҒ@P#YX"9suҥ odSR2GDH "m=ymq-c.#*i6H⊺.L jbfG$ӸT:}SO6+VYkR&*Y*T v}!ʝSpZ 3F?LyeXtwRAErMT-ie/=d#~@(4ǩSpHs<&(xVDV!+K4ҐhHd|Ml u%K<$|h4-PN?zt +hQ;(R;C=Dٞu )TYJ؅(fIk5U#1u!YB JKn8nIMaІBg W]Y e$]b^$eHPyu.ey!NJhqJoq;67CԓǺ8žQM1R$^HR>eQjE Tm%Us/@)+$&!Ɖ7^"[OtRcFSs yրRSW TgQK9ҧJmY'uQE 9sʄ*A*MAJQM 5$s*PAIr) .ʟخYJ{knKebKa]߆[so67~/=  t6'RLL2R[St\1 s'.4_u^7D;<7M`D!C>yѽt' 8|)ǜ,[UH;w^NWs{(H9E:l{,Ϟ┨,$e~~sjT}$LrII.ߍ ÇVbۉk똥z\H>tTkk4 h`\{cd#Awxt} QGVvgE(ZoE[_V)\,2V]0:Ҝi8İѓF3"i8p#e',t09l-*m&܊/ QۆͭYY:olej6f`pbdPC#vyw@ǝzFk>|ikV1-iRQ *z?ï'p6GL s9FSJsaB\*$yJuP|#8cg{֘dǪlɻS9Lp"RgUŬ?ԣB oE&~?ʂ|+cBR]{8?۳i"RG6 S.8ٸU\2wژʮZK8H_bkdiU'>=vvZS)'J qZ攠@s*8ү& xQRށU]y3Spk2MKә9!\b^g, &(';u<^†vV堫EÄލLmٸtp|k%GTA v)J٦#ZÒ aQaTp!$N+i%J:<8XTb~Õbhq1[73i_v<ҟeI"I=N8IMawOYwgmҐq)!LIx]drbǵb۲ǏLnV(H+hr1R*o 3@2sƀ(\ Iyh\houtW+IO))O:M*܈@/ ʸޭ#N2d?t[Eؙ늱 YlU=r9>yp&LdFnLGhR2O,<}iDQ@":r =?@)̌M*0 ]Qh4Fap7)-'#^-#N\)I\ 8S^kgM'eĶe) .U 2~l'hSdu֚)E +g iXMa!I²2Nu%0+9 <Ii<]aZcv¡oi Ķ$TPD9V)8I:e;tbOhDD\&nSbz*J@[r2)D хEn1KI (,NN/¢mPObQ UpxVy"(A%'?uA)_EvoZLMwGZ )nSS*4Ҟ2EIMgwrRJ7'4/Tnr)Fj\%:[CF KBOhAxa}v^sÝ}TuSAư"i*5Dp\$4H(H׀2M1-:d^w$ؼ40)8ΣugP\՞rB%wHZKy"gxt@9 9EJW9IOIA!,.tMsKBJsTU&]p5@uƖS%Ѹ % ="?*qZJ>"E."[??Υ5ʞaZ[=t-"IBM dζ̸P`QkmcJnDXe0iRDʸvE%jr&Odx͘p2F ʰ-N(te L mR1k ңi!7¿(!1AQaq 0?!QzNP"QA1zPhZQT("hD4QD(WzQk*(Q-q%p) /38(B="Qh53uQE4ZE,Eh&FmKEPPQh(QB4QLj"zVN-PXuj((Qj(DQE(Z(Z(\#EQMNB.(E;-Sm'KED0QB5QL""E37дQ$`~tQAŢB(QDz- (B"(]hZoQhG%p06k"A9 rwUZ("-V(qEQhZ(E1E^JeUo1lلS&ӽ$ŀ ,pyEEE(QTZ(QEqT"(EQEE-J(A q *Z`8P$P7-(`1cES=TQEM^EQhд/J(Z+LBQ|00K0hr N=G< (D+Eh-TQh/BESJ(Z)Tb}|1s"e{ B&b՜Y0C`QhдZzT EQjеZEr$D5[T CtXtW;RxbzE Q(QhEKEZ(Z-K@4Z(} (n +cs= =`Ţ@EUQM%QEA'EQEZ(.(a^ ,)17pv`wGa%TP/JEEqhDƪ-6Cs}ЫUQB"(*( W"fS"$7uV6-ht]E(QEbЍ@(Šj@ EZ(EC&O[&.mF`WG`}ĴƊ-PLдZ(Z/BEQDZ/BmQEEqR`mmI(SJ…CJb,ճ-EQEQEZEQkZ( 4QhE& l%8#  b(((ZQEhZ(EHMQhQzT1@"C:{p=TY^LSoisB7E*ТԈEZ"CZ(Z-wj-T^&{2F. A,6eces1L&V(hEQEqAB(n(q6ED3Z5\ĂB '?N4`@́ AZQhQTQEQE %E-0QpjEZ-G0I%_xA ɧOv-9'`" W&0A2{2rD*9?-Z(EQEQEQAb (EUP"-7E-Qa!" oA@2 Z&!rY "PEQE((( (Qht TQh(9!F,D#Z/BhK0 DQ>>j6(%>S{j. otN EQE-QB+EQhQhDGQ(BEQED^߽((] rp@J z6͈jK6{%E<'-Z(-QE(QhbUb(QEQTQFXJ:B+(@@?OJ@ G\&g29>`X$>J(Qh"(U(QEEQEQE/B`8hZ* VD#.c2#{. b@B(*((((DQE(((EQ@!V㈢ДQL`@3!6IRd :1(oǾQߑ\:}r`~%aaCNB,F[uˇJhB(Т(((- (QEԴ((j؁&R@& o\ET`H}o& Rr(EvΟfqhQEQEQEQB4QEQEZ(EQhS(7QA YpNKɫh:!Y'-1_r KjU)y**@􈯖 (- A(!EQEE(0(()PLD\+twPk8O`%oUeadWS3tQ`*QE^"QEQEQEQE(EQEQEQEdP$!PUJ >6LlHʀ<U &(nE25 +b/;F17VDT 3QEUPzB-QEZB(EZ("(-QhZXe!N ;T+^n 8,fFr&dƙh1[OQh-0QEQEZ(((EQEQhZ+(W`D; V ģD.hqD 9p,Ȋs;P80͍ TXVv''@hF(( ZQE(((QE-{s"e3iBP9I<\/i|AE+fHf$`g.R9B~qɃl(((-\`hZ((|GEEhQEZd@E]KLv*c_N`+qDaC0@2=1+ MʄA((- (j- - (B H}Z-H @K? B#1a`WS+1AuG# ډ(- ((ТТ-Vнj(BТZ7ψ -C_95i G$N6 >ad' (0޲E_vcF (܃6X\QEQhZQ^L"hr&8;f-V(j(P y_QLC,V⡄<bXxEE yg@{"(aR82-n%Џh>3h DQEQEQE%*'N0LDّ+4@^Ej(-6ïM%֢G.VY,=UDXWdQ=MTd bH brPE#DF0XXѐ]%c g8j(#@9*}e"0! F"`:"Т()HQ@VqA[oR@r0]Jxw$>,]77p-h>HMyP9=V+wQEQhD""z〞3rxq |9%: CK3%.hIf+rWoFR")-|'DPJ|f0~΀ ہbdG0qAG~(QE@_ } .{dG7av ~ >Jc+ 8@=vH;!zaG l1VD;%xyDlԀ4\9$DcR(EQEZ <#( `,eSA5|YpV؋`|S,nDјnfrd C;AT 6a=6a9&C oCdšE:p0 TPȶ ,O`cТPT"Il`" VQ/e3Քl*Ss׈cT SfϺÉ09({|At8#o@Hp4na#4gGE ܇cx`C|_^"`O F@5 i{ 86Uĵ.lTt^,I0ɕp]7$' ճ)`%X&m$Ţ** 2x:P8%G994$" ̰ChLT0P`dE*(Vi\ʌ `@43DEB Dze0E*EQhQEL`xV(9x7 d% KJ7B4 "M+b@' Zk(!nv["-9lH85 (ߘv W^sNv9# {pC ;ų⿗҃X@[}ƏU! im8b `ՄvYcO={=-c)9 ÝwBC!lP#K('$)PN*F v@ֲZ.Rlzm?oEP$~" 9W#o8댔x2Ą l 4(r QO,:so\@tn8L|!Jk(ٟpN3QThkCW"J-}2`ǕnѸM(=(015BP%[2/.B`R |<)Ds)o Mgge"#%Mw興VaDCB_8F,^ $0@ƯRx>oR,$7(_QfRnC\g 2{:$``. kTɂy7mEܮ[;ȂByȨ}$K6, /Wt2.@p\ '!L;Hh@P I 6 #Vt p&4$EۛU+$H3 jadg$xhr{eX>tr  [!}J5K`Y;'$56 #HJtrvRXlع&OcP jfh9nq Hwy2`\mq &˳F,ρ 7D28nEa4=K_#!B/DXxo `0Oeufp>aŋa07 &WTFl)fwx+;4HmhDؐ 23Fy>#2a B`_Գ!HAgu htgM$XgHOF("t^Hh# Lly ha\lNRj 9&g} ?8q܁3 K*`VEhwV{T -̟1n@̬X'<3b/3wBX_)RȺ>qGx$LnA-"5 Hj\$v2Z^'P !0A YJIbO5Pr d 8(8 _A *M'h (BXC0 )yYa-Y`߼2TO7C @aZe/J.5WEqh|QM}^.j7[#Xqb;`.(3a0DtL`,EF$C>h `)+" {BD6 ~dkPEV? 9n(?`Jb"6G@_Ņ* 1@\lN8*g>f@VTloU`&p6}hH,Q~O-۲wqU܁ (2d T*e8?ȇ5̮z c}H+`~|6f{5( 7M pAjgm($PA`nb @3a'͛1E2r|òm|DtnXP!Q.<#Ow '#MM=XqE+86 :_pnEr 5~;_T@~&Q'?dDH.[g<@hH"fQAuغ#=7(lh]`8p$|uV6n@~؇p, x!8PJwL2"P阺>̱3BY$s"tH^i|(23u ҋEcp2{FBxB%ZVƛg9 C{ej`|@EWo~A2<CL% M Uc@5_\,l?˧u!o b-'C0&!0@iY[ăO357LZ 5]@׉Hw8Z*b2z%OIJ q@9p3l|@A%yŘc[Y $' H0*Q{}A<{êk+w <0D5 1jv Y`$i4Rr NJmFA9 8RvWOXSA xAll'!D~ 6JDt\ .yJU8[F` /4g x<b lc4Z'&Ʈ(m/4^8ɖ;?\TyF/Lqba2"3)n"%6(ڛ.ꉼ]`kTPJCyQp KoQe'o`(lH9HtÉ:xw*[ej0#pnQ+ie%gA߸SߐjV7Pưmd*Of {K K۩Z`k'@V >G:3D (U>T8CGbr 6UL^'wD{_DXvmGgvm qZEܒ"m#bNd" Lm*RMDJak樛/֪G,AwGj0V/8cUG,t2 88+Aаd; PDpbbW 4% dǼIM 8oof`D#/0%r"L;1DN)@&\ NoCxDh ;*iѤqV>z;6g3FN/B  ``g"JDgL5x.aZ2qc0Э D "b !PK;1D/Dx9 `|%Jk,)'4辎L=J?a 13m9%Uk!z&{TN"GOhW.6`AUp\fIFð"pbF#C4 D\Gh_Ōho^]M. e n'נ#$d!h8'cO8+7$KFIJ0vrl &p\<7D9t,i{v{Bv o/+f'̧m+#a+w3YOIJ¡u M`Id2RIɀHBWR!omKE-iB`$Ppހ7]>PA%-XQ`Tp"PpEL ՜E7]!NiD=8*pLN|vYGH,@m)=m ՛]b6͟[.ih> īlnu>P/?ե\ҎC`/q}žߠ<$Mhl1W˷!¥NOkoXi;3oo6AHO%oQ2モO}m/f'zNvokۭKowcu }2ooo?&8Gj{Kq"(C8XJϫM~{ʷMCߠKz]v0W47]eƕ`ՃKo|I./I'%vZ[Ћ6 {.a"=?y?J6T<$6%[5܂y+eh ґz/ \"[n䰓xa[dQJB%]]2$@$ \ܙ:ڳTtGcj,Lkj́%5 A86ˀQ!aw+]0GuwM*%c}K'}Qb0sh 43g bItʐ%0h3Uͫ {QfC>VFX2`dAih!`YMZe`_\{8ۗ%r jÈYL@y<1GEeI} Ȃlf4o:OiGܸ+ˍlǺFvO,\oe!vԐפ"N-Ay&|`LbOb RCxmy=9 &b 9~f1LzTV {+Iqrj6VN]A!;| CbHPNN20GIuFhTlwKj |t*~EeBW'z =/=9(!1 AQa0q?RùD2yzAosbJ\&6l. N̡⡼x ҔB~ X[X☇!{Q_:"Nb؇-_>x\1ᔾy{^JQ&74Kv=H 7DnD؇={<:5Oyד=/T$^ !SИG<.zL_Ctb#1e(%5K _Q3n2,po~_X𥧢{!&XEEwPDtqK2OCOXXHXcA,D618YW-"b(N G7y\j7J~C7Naˣ!!qs\s~S,+)a㢷 Ez3K˗b/#W\9ͶF"grQ tN9S)o/)KҟVlZ.&sOLAaɽLN)>Yb^0!߂ JM yE[_!~3b(ņ,&S|RR~&P)̽7 Er{Ax? X_'|9·ARq$Ax]hbYR:vEt}c=a,B.xty:Rbeo: q`iL} Lb)pؼQw Ox}yRøLxTXę)T{2k$/< 'HC- {)Y2)+7- F"=9/;0!x<"/+)\ .ƝMwX,,LtegмB olѯ;w_IqbNЋ@H;S.!1QxCF MHcSIGg! e7%ގ ?TXX&h1?<\AlAr 6,L=="ba*T#bo\k׿ZrM|>$l0Ɋs3)sK|RO"xܶ1T%< OWȚ48Ru3NY_< o06DH Hw!?}n_?1<.f#8! 38s T4>hZ]IdW]ro񸘂!>>eg14N&&<45h>=m~YB3x1,Z5EyD{J85x5B{D Nu%: &Q4AމTP濢6" #v-Vpl?wc$mI ԍx-?ha) cw3 _.dzV; !*bBD5%[vGwW(?ɡ5D#d&5C& W nBG'bRSM$}Bg;дa$DѲt"]:{'I BDEl] 5_(b_|ph5=և5ҧ=ec= cłthH64h̅c{CJ5G!H*8Ӧ&.k QA"|>%bBB{/Ĵ.B), 5°6,e+cC1A P1A(/U I +lЂ6obtct*& AnMAr6&h! R%mP"oEb;")_G5:987HTS'pc]4jc} vB+gL/ldBFhj#]8;>f6H'RhGCR'X7lr؋ifƶ]4BUX=h#vDq;QL/kXTZX{"DhTtHߣrQӈeGj0еT7a^-hRc4QT5po&l0D="\&b?|I)[CDѝ̸gf4&QjHT1ױ#_k5Z*rcwcQ!%Ii2i~C_{]oH.5Ss鑲 d- .gu0DDkE7o&ٳC;0i[/h]b!6" C|!r{7EG)!1A 0Qaq@?D'g؇QH?h^&8  J,Cߢ3׊QN! -v6&E2n^=wLr|oc5&X:\s'qȳ} |f)}R Q9W| )VVݯh_nl0W轘i/Xb)|>Jv|gQxEVwtN`ڟw#j.[[6\_BǂF͆$?ɥϔR)sJR払7锥J_:\JO ZT#RC}h77Ɨ7wCb)qNKJRc6*wCyÆm!To +)rR戥/)KR[F%EhA ThJr_R券OƔe/(JRo};A5H~{>þ{負kH?#e(|)D\R┥)JAJR+^ĺS6V+0c&ehQqf(i|nn)|.)JJEŸWxpr)JR9iJR)tR K,XiKJQxivKw%FJM ]JTR\QJXRl_/)p)J{PCBҿQ!JAڵ6͗)JRJRJRx(2 풔9,)|ƉQRlOkF_#oG8TT\”#o nAKQJR”)qJJRCuN_kh)Jk(O {'ܦ1R.Mv3Js )F&VR)JR UInI)gw-6CB;v4kD '3VC )[P'02S4RwQ"L{1#P8%*)JR)JVQKmASmfZئwrD\vJaDB8(JR.8U]{ | ۯj)董!ؕ'JR(ؙKdwb;")6!GLPb(|&픥.nn)D˚QheCb&*I_I"1[cECI$\/)>1pM+ !bfܲv" %RFzK"ؒk48A%H[D*'Rp9sXm'Bh;9X;7Z>E)J+Nű7Ar!b~ \)QHzX+OٲSM )tCD"2G~C*F\&5M4*&i"zBE]-A3H2^ -^-Gݔp2|YQsI;%laǡ4oHQZ; ,JJBTPvU8ˠ]#v~`shy] -^,887`QhUp6GpmG"NiُǔmMNׁc d-&Ǜ#+4\$ 5pƍ. S@Ml\{J4ŰA&% 6šCK=mbݯBd.Bm@D=Hؒe n6s}>GpKX^ 21toNJ~Ґ'; 4kX{nf[b[\ݻ(Y1)&Ɛ"ʈrRДbE{ : *lu hklDb:׹BUEGGssbc=4|I!CE=mp LIq/aiD^r-ҟ= v4lS,K> 9PN N#׽IA4AD>Ht+q.Dmn8Q!Y/nH c:cK]bV$1B7Wۑn)ظيnbD[hcu}1t6A+*c;LԒCT%] >#r/-&KP@ T-;$m1$9v4h^h3l A S|m 5X n$5k?'!1AQaq ?-{Dn W J(mr`cUe'~ԥT2ĻW*a~3 _@d`+ (W >ɭ WsBwzr=p{]},&Wq:yp12M"Z̵cF)1y ~>UW"o4l;{%~ȭD|Op9??u5P_cO> A ZB&P cuЉby&DG{*p_ol%|KOż:,;xU4pxoeU0=]kte}%We`T~G-d8no楀-W;1Wk :AG^y)WQT~lr;}_q e ,%*\FUP?ġsK. .#K:}."+JS|M -o-Opԭ1%pIN٧7(g`6*עQo0{6 qQL ly?Xiy~#FUňQp3Kd@(,ߘ*}9v(Q 5߈T+|m7aOǹR?/ۘ@HX|nBXV/7!ecZH0(MaPUPM_t*X]_0J1F7^ny5޳RJ% ۩ĥܹg//C{~!¯2LA/̭>%>t3C5x%.ꐮ{ J@Ue ~ah[+y!_x1OX7o%y:?y>A̪qL#!H'*oA[0̆6f_[:y \KLZ9ڝ%P]39i ,P  wN{R2)KĺF_0=KgxU%J2#E%4~Aaՙ(Oi@~~/hySlA*+C ,kc>W%#yځl ܢ>̔:oRbő@ԅ,;V-iر]SظU(~"^%o!Oz7&^.5)Yfsf?ke]U3^ %]~bGN~vYg {So[e '\9_¿Пp\JCcFi+W̎~4"*Q*Q-qw-"+*|o&/8=qAZ*%_@sl*Prt|=D~>-oJ;߉c%]oӑJ~`PQHb~r[9{*ۅ*IP,~y=(g2|2>lANW}dJTĝ;.H(yue_"YFrı*)ωxC QrMd-P+Qܦژ~+A-l|a >*܁p2ݕ4c~TL/_0,>o8gDaK8?1DvPR[,Jf6AGtF-]r`qZ%_B>&*W@S*1J+bQm_ܫJ{ 1)<9_0SeQ~]yKJ=.%,˘n]ŷ~_WQNĺY+oT="TJ([ ٸko+90.AY@64#ɕre.ԉ`5pM_RL_@<azH76^r`g6+>_0_\u/`2SiUWP5/>_{ B̩co{DæJUٞ',2^E|!' -ʊ\0TP&)/SiMi FP-K{ta,d Re/ JG̪"Hg'ca>*7v[q?0B%d3@T(UaY٭ JU+L V p>\a tcl2į'aYU}s`8%#l/#~U/Q'ԗM:Oij|rB`Zb\hf֚< oP'<^|HG~n2SR{q /TރnyQjфҧNyW3h@z%Mxg37ԡ>{.?}bQl=/3NdE<|A !ۋSXZMhJSbE\ D <Q<|?3T9Ԝ݋GRh *,`m cB &PE_km]8M2{7Rm" 5>LhS rw3|?])`!C)D UFxN҈!F"I:Q|J>ܤG4~HRu]!o _EM*ɢPWnYWeZ`Ս##zc`)JV =-T[g-|rcQq:P6aB>=@Du[)_pL Qbv,bUd3Oʨ <{wy =Rv~vpr[YC ]*%ZoW]e!S!7thv<-W Y%xh[qlO<5 Tj" K9°ψܖ\*Yw 9o ONOxFxk?1F'GKƳyf㬆4O(?+ {ȟ0[~OH1s]yW[F)s]1fy30, LkC%$iEkcK@BzjѸ˘@y1 t(Z´X]ReLl UӼl6k JG2A˖Ǐ_q8r%);.|U>̲9qL=yJ2 31y2J}Mml\@BwJZcRvp-,Yd&T+A` |)Jը(vBk6Z4&hM>[Pɯ.7f>b0 >?O'Y6^Tga[BMBt~/M#PG ~cy~_Q7sO5@'j,)OxkO@M =DBKԠ1y+Yw[p>qAK^|N~%Q/ڂB]ވuU*(P/-) .?3sF]3 @BեI@kits˞{}fo_g~*`Px"|~bQGVW3OS93o!+S>s*!P) T9*>b;=^1n7B8\^$ ZWU b 槣;kgn)tخCP3HІ^#C'e(!ر5ѳa?ܷ|O+3f%z39Yy QK?U rQ\ '\e|!IOu3]]VGSX;Њ:Ca^C"L+ijӭ%.+TGū\)fX';6,(+P%8'" 2 ?Ǻ& fA8_YgNCpG bq.MC_1E]_ xM{`pG*AqP UG@S1Nijn.kussۚ}ފ)ԘPTXēbRicؖp*"ܦ hWȠ'|AsqTkcz*ْaqD S̷=glL/!͋<2ljf5!rp; -ʆ 6 ¬@++|^ zp3l@!WҵY(J,%JTMEE w ]u;9 ,_nnf |Lg?yR*UgQ.0G_W8*i?mO;SŸM,CU~q>avZÐ)aGf=脢; x )(Ah^Q^?#ToP4"-m.j{&Qi`AE EMU"OQhͼ98!yxż\dp_0.e~S?^ \>ra(W*3bRyoǯbKYx%o`YjeE^iǻntK/L"z\2pT WQѡ:@ZKC;!l55W!fe_6- "b""{^B>ϟմC3g&=HIh= > GԯdL{s JmI5F9WxD2ꍫW~XRRkZJP<)dOĨC'^-pj^(zDh4qEĖ0xr(S~#TGﳸQc%B¥C9EF`+ЇbdS^9^S*OxJ 53@!)NFY$p*1\MQ`H nͨziڳg}\߷&ثtڌrbRp3WTT 1_fAeآArp}ih!Ϥ,ei I4Q1]lZ jV0!kT ,<9(wg%|?a*e|M/fɨ\Z0%C A"g'7m4zd-{ 7v兤T i6 (:5ڠ1x4P<P7Vo (4o*XIChhTFԹ S~6N|H.(e Xс2&,n-emUr8S*ve^#kug(B 6+8413d;ĿQ.1OHX~_?WKMbFSnkuwhjϋWO^-Lr5I!t3=V`웡eZܑ.VۅaOp pStlD@jXx-8W(ߑW~ܴ<"vD|3 BwU$p6ZuD4 eŻRe#{\jQ)Lg%/Pqk[A- v')B*nT@Rkje=4Gw-PAt<#Pl2:DxX0ه"Wh ,vX4]uFPb0;hUf>RTTvj?t hj ݽ [Kk1XR6`ZVz@PxGP#HJlJn$fR$J[8V U `X4-`Ui +CTض –6%7`3*O1 YM*WH.)Jxh) Vƒz !{ݠU.u`P<'*. 8E%Į^ _G AATm|WDJ=5Hj-,+K#7\VP G6VVЄ_ۮšQDcۊTјXZBQyL+ *w@x% bVdTu06(L bFU AkaTȋp km)v%TJ%Fl 3?Pcp[7N'ptm%jvHl$5SbJՐYͭ2 )G@)W.beꂓ)ݎ +/Hv?d7em-*WK:7$+E躎 Nq۴]~}V.HJѥm R(]},QTUKQ ]Ɩ 2V-d Y~ ND_2hP(hAQFWPx{gj!VQQ;VE0 uWZa XCڞfWJۘ #]$LF!o )Hgje h&EiPkFhHhjñM, Ȉȝ )2cB)Ic*q~"G¬C?B3Rx%bU ꁚBMPBtDPE`R@\-@+'QREZAYiB.Ԗ]Xl/`@WtZU3Y"<~. 4.pYo9uwlT Ai ݪA`>3lA..OvVb"תp A^Kj1K h ;eh. 0enZw`a{W)|AX+Eª+nIP[E4QZҗK6.'ejHKeZ7a[)kQކI.yZ^XgnGw APV튒R-""_dfk@BQR&peahݪEڕ LQ@˿ J- T@/x/Vkk dA\蒃d*䀮yr¥ ֯El976z8q)Kꫨ 3R]ƦU*A`ӐUjV4 TT6kWš8Ytↇ1D\|dj|("׫Ԡjg3`h-Z"phu8i(0#~h⤄M==Md*,Z7 b _J+)L`銂lbuT `%Wǭ?} ,8PEaصx ReӦ4 3uʢ{t}Wp|#z?0j Px"K^DžF=,VwΕi7V&] /#@M]mXVЃTqCRo(l]P9[RmS$`"(r[eTRSkeSӧ'-$CjZsY87 T|a!Bn 2if KE#7L*!Մ֢ #.ӽՄ i Ea )Ȕ"]~_؄cqۛq܀Zӟa|BW2κ4F|'l+gG_(*4m% paCT􃯄,Ÿ>#r (d8Jk-d) 4^+2I,]qK,Q BZhT+c1a8hë%pqB:6ӂఛW yPUp(Ev/e u +}aOE-vju[Ʊ 7^%j5=?4a*åm[iӉʅ!tiaZ/ 6߳' Vg9Z:ꕯsQ8+}e%Kzc(UzO J [zxFr%(F~c@BaiZZ,6^Yae]ז HD.M i) ZV1/6|&!8£Pi_+ǖZ4 /ϸv Hkp DR%VS  (?qAD`3y[՚)v%;6BTGV.h6M0d`j9BWy nܪV4N@ ]5-(>* ,TXY㪆B/+UQ(koA NƏBR8BqJ-.d1 pX7V=fG4*Zi4m[`/_4SVT]j⒛E50J4ABRD`RDoM]X 8)F}4tPoU1V[L]chWkQ0uCTiJ.)JL*'[JCCH-t'UUi _~s@ vZվ#]y* z"ޘ-rfTL8] u_2쏽i",U')dzr%gsBT GTU U W@ vC8ŸqLmhW)'2^7RfAr{Za6.3'^)V8y. ޗђ܁ k6 -4AUAZK1SfU4B'€J P68[;qho0\ŸMjd7P=O9R{kG*>EMRRm*[EՏ(`bFU4(E6xl3&=(2I|pEkf*X݃:WizXUXF5u۬AkTZx8 .WVX(ԫiiEIٲ~X \7?RQmAO" a @/^#>qztۧ)] -e(R2'h.}Jľ'e^5̣ vZ: (^kR+i{@5o ,%T͐]o r`߸BӇ+Mx;Db}h..8:V/'2 .)hiƕo|y#ey`#`6CC  F@Z\.xB{dMҍ`+x ѿ?MBXt VJY`R%H50*"K/v^ tx x">tsJUsVW6,c lدowV n\),8-!MX;T^9VmI5R JVg_0=ΥG$R^Pym*ku2 d`.-@xw 3 ֫EzE%IhH}C|]ۙpUYhQK@:}!s%CKSgIZYCvZ"&R-Z5lil t-mZ+ *80 U%tm<@ (XU6 Q0jD `M!0'"Cnc"#PK(%fPz&] ͣ$@e"qkQxAEdK|j}{1(q7rFT+ݬ"m 0'zmp)3L"WǶZqr[G!C< %^շb/ !`OPh*]MPCC+sD."Pbk!ZE^TimߘukP)'HD d.U@ _j!@Oe1ȨmE]!([4Z*´T%.X„Vѳ{TS@ᠳLAc^ я*@-GF޸(e$y%> rq A ֥&pQcLtD*\V ,sȨp/c[E0STB=kn ڶaP[C *l {z(Tc :IUR1uSP^ƨCv7²ڡ<"|pEcYUl4X@:=; (J+ayX`l!yj/v6{G\]-t!m)0k+Pl+d}0p;,k/A+b4zB&SŊƒ%B֣31e-]i#F<'.5eiWd\5i,FE3@M(RI0oTڅYFCB5ku<AuCO1)g|* 8VGڄ5~$Ea1zh9-#fRWSiv%")FV.d!eh^&8 WHI2!(](y@.- 'Wad^<Jն /Oa@}@#˺,fH1RP[/Z\W8!G.!t+ͺ$|P|/w_} d9텗eiϙZSȿ g  9|gA_QJt>ȐJy/,lP9JDT !vMcUj CWgtٹh͘ 5ZQx+Ulo:(JՀ#`Pף(*(9nq 0[Ovu:*8Y[ޭG[N+" 0ؔx}{"E* ]Y> zU.PYe2~JS-w]PE]I"$ ꔤ7"x' bR@-H), CATj /U+ ! { write!(io::stderr(), "usage: decode image.jpg image.png").unwrap(); process::exit(1) } fn main() { let mut args = env::args().skip(1); let input_path = args.next().unwrap_or_else(|| usage()); let output_path = args.next().unwrap_or_else(|| usage()); let input_file = File::open(input_path).expect("The specified input file could not be opened"); let mut decoder = jpeg::Decoder::new(BufReader::new(input_file)); let mut data = decoder.decode().expect("Decoding failed. If other software can successfully decode the specified JPEG image, then it's likely that there is a bug in jpeg-decoder"); let info = decoder.info().unwrap(); eprintln!("{:?}", info); eprintln!("Exif: {}", decoder.exif_data().is_some()); eprintln!("ICC: {}", decoder.icc_profile().is_some()); let output_file = File::create(output_path).unwrap(); let mut encoder = png::Encoder::new(output_file, info.width as u32, info.height as u32); match info.pixel_format { jpeg::PixelFormat::L16 => { encoder.set_depth(png::BitDepth::Sixteen); encoder.set_color(png::ColorType::Grayscale); }, jpeg::PixelFormat::RGB24 => { encoder.set_depth(png::BitDepth::Eight); encoder.set_color(png::ColorType::RGB); }, jpeg::PixelFormat::CMYK32 => { data = cmyk_to_rgb(&mut data); encoder.set_depth(png::BitDepth::Eight); encoder.set_color(png::ColorType::RGB) }, jpeg::PixelFormat::L8 => { encoder.set_depth(png::BitDepth::Eight); encoder.set_color(png::ColorType::Grayscale); }, } encoder.write_header() .expect("writing png header failed") .write_image_data(&data) .expect("png encoding failed"); } fn cmyk_to_rgb(input: &[u8]) -> Vec { let size = input.len() - input.len() / 4; let mut output = Vec::with_capacity(size); for pixel in input.chunks(4) { let c = pixel[0] as f32 / 255.0; let m = pixel[1] as f32 / 255.0; let y = pixel[2] as f32 / 255.0; let k = pixel[3] as f32 / 255.0; // CMYK -> CMY let c = c * (1.0 - k) + k; let m = m * (1.0 - k) + k; let y = y * (1.0 - k) + k; // CMY -> RGB let r = (1.0 - c) * 255.0; let g = (1.0 - m) * 255.0; let b = (1.0 - y) * 255.0; output.push(r as u8); output.push(g as u8); output.push(b as u8); } output } jpeg-decoder-0.3.0/rust-toolchain000064400000000000000000000000070072674642500150770ustar 000000000000001.61.0 jpeg-decoder-0.3.0/src/arch/mod.rs000064400000000000000000000026000072674642500150330ustar 00000000000000#![allow(unsafe_code)] mod neon; mod ssse3; #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] use std::is_x86_feature_detected; /// Arch-specific implementation of YCbCr conversion. Returns the number of pixels that were /// converted. pub fn get_color_convert_line_ycbcr() -> Option usize> { #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] #[allow(unsafe_code)] { if is_x86_feature_detected!("ssse3") { return Some(ssse3::color_convert_line_ycbcr); } } // Runtime detection is not needed on aarch64. #[cfg(all(feature = "nightly_aarch64_neon", target_arch = "aarch64"))] { return Some(neon::color_convert_line_ycbcr); } #[allow(unreachable_code)] None } /// Arch-specific implementation of 8x8 IDCT. pub fn get_dequantize_and_idct_block_8x8( ) -> Option { #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] #[allow(unsafe_code)] { if is_x86_feature_detected!("ssse3") { return Some(ssse3::dequantize_and_idct_block_8x8); } } // Runtime detection is not needed on aarch64. #[cfg(all(feature = "nightly_aarch64_neon", target_arch = "aarch64"))] { return Some(neon::dequantize_and_idct_block_8x8); } #[allow(unreachable_code)] None } jpeg-decoder-0.3.0/src/arch/neon.rs000064400000000000000000000203370072674642500152220ustar 00000000000000#[cfg(all(feature = "nightly_aarch64_neon", target_arch = "aarch64"))] use core::arch::aarch64::*; #[cfg(all(feature = "nightly_aarch64_neon", target_arch = "aarch64"))] #[target_feature(enable = "neon")] unsafe fn idct8(data: &mut [int16x8_t; 8]) { // The fixed-point constants here are obtained by taking the fractional part of the constants // from the non-SIMD implementation and scaling them up by 1<<15. This is because // vqrdmulhq_n_s16(a, b) is effectively equivalent to (a*b)>>15 (except for possibly some // slight differences in rounding). // The code here is effectively equivalent to the calls to "kernel" in idct.rs, except that it // doesn't apply any further scaling and fixed point constants have a different precision. let p2 = data[2]; let p3 = data[6]; let p1 = vqrdmulhq_n_s16(vqaddq_s16(p2, p3), 17734); // 0.5411961 let t2 = vqsubq_s16( vqsubq_s16(p1, p3), vqrdmulhq_n_s16(p3, 27779), // 0.847759065 ); let t3 = vqaddq_s16(p1, vqrdmulhq_n_s16(p2, 25079)); // 0.765366865 let p2 = data[0]; let p3 = data[4]; let t0 = vqaddq_s16(p2, p3); let t1 = vqsubq_s16(p2, p3); let x0 = vqaddq_s16(t0, t3); let x3 = vqsubq_s16(t0, t3); let x1 = vqaddq_s16(t1, t2); let x2 = vqsubq_s16(t1, t2); let t0 = data[7]; let t1 = data[5]; let t2 = data[3]; let t3 = data[1]; let p3 = vqaddq_s16(t0, t2); let p4 = vqaddq_s16(t1, t3); let p1 = vqaddq_s16(t0, t3); let p2 = vqaddq_s16(t1, t2); let p5 = vqaddq_s16(p3, p4); let p5 = vqaddq_s16(p5, vqrdmulhq_n_s16(p5, 5763)); // 0.175875602 let t0 = vqrdmulhq_n_s16(t0, 9786); // 0.298631336 let t1 = vqaddq_s16( vqaddq_s16(t1, t1), vqrdmulhq_n_s16(t1, 1741), // 0.053119869 ); let t2 = vqaddq_s16( vqaddq_s16(t2, vqaddq_s16(t2, t2)), vqrdmulhq_n_s16(t2, 2383), // 0.072711026 ); let t3 = vqaddq_s16(t3, vqrdmulhq_n_s16(t3, 16427)); // 0.501321110 let p1 = vqsubq_s16(p5, vqrdmulhq_n_s16(p1, 29490)); // 0.899976223 let p2 = vqsubq_s16( vqsubq_s16(vqsubq_s16(p5, p2), p2), vqrdmulhq_n_s16(p2, 18446), // 0.562915447 ); let p3 = vqsubq_s16( vqrdmulhq_n_s16(p3, -31509), // -0.961570560 p3, ); let p4 = vqrdmulhq_n_s16(p4, -12785); // -0.390180644 let t3 = vqaddq_s16(vqaddq_s16(p1, p4), t3); let t2 = vqaddq_s16(vqaddq_s16(p2, p3), t2); let t1 = vqaddq_s16(vqaddq_s16(p2, p4), t1); let t0 = vqaddq_s16(vqaddq_s16(p1, p3), t0); data[0] = vqaddq_s16(x0, t3); data[7] = vqsubq_s16(x0, t3); data[1] = vqaddq_s16(x1, t2); data[6] = vqsubq_s16(x1, t2); data[2] = vqaddq_s16(x2, t1); data[5] = vqsubq_s16(x2, t1); data[3] = vqaddq_s16(x3, t0); data[4] = vqsubq_s16(x3, t0); } #[cfg(all(feature = "nightly_aarch64_neon", target_arch = "aarch64"))] #[target_feature(enable = "neon")] unsafe fn transpose8(data: &mut [int16x8_t; 8]) { // Use NEON's 2x2 matrix transposes (vtrn) to do the transposition in each 4x4 block, then // combine the 4x4 blocks. let a01 = vtrnq_s16(data[0], data[1]); let a23 = vtrnq_s16(data[2], data[3]); let four0 = vtrnq_s32(vreinterpretq_s32_s16(a01.0), vreinterpretq_s32_s16(a23.0)); let four1 = vtrnq_s32(vreinterpretq_s32_s16(a01.1), vreinterpretq_s32_s16(a23.1)); let a45 = vtrnq_s16(data[4], data[5]); let a67 = vtrnq_s16(data[6], data[7]); let four2 = vtrnq_s32(vreinterpretq_s32_s16(a45.0), vreinterpretq_s32_s16(a67.0)); let four3 = vtrnq_s32(vreinterpretq_s32_s16(a45.1), vreinterpretq_s32_s16(a67.1)); data[0] = vreinterpretq_s16_s32(vcombine_s32(vget_low_s32(four0.0), vget_low_s32(four2.0))); data[1] = vreinterpretq_s16_s32(vcombine_s32(vget_low_s32(four1.0), vget_low_s32(four3.0))); data[2] = vreinterpretq_s16_s32(vcombine_s32(vget_low_s32(four0.1), vget_low_s32(four2.1))); data[3] = vreinterpretq_s16_s32(vcombine_s32(vget_low_s32(four1.1), vget_low_s32(four3.1))); data[4] = vreinterpretq_s16_s32(vcombine_s32(vget_high_s32(four0.0), vget_high_s32(four2.0))); data[5] = vreinterpretq_s16_s32(vcombine_s32(vget_high_s32(four1.0), vget_high_s32(four3.0))); data[6] = vreinterpretq_s16_s32(vcombine_s32(vget_high_s32(four0.1), vget_high_s32(four2.1))); data[7] = vreinterpretq_s16_s32(vcombine_s32(vget_high_s32(four1.1), vget_high_s32(four3.1))); } #[cfg(all(feature = "nightly_aarch64_neon", target_arch = "aarch64"))] #[target_feature(enable = "neon")] pub unsafe fn dequantize_and_idct_block_8x8( coefficients: &[i16; 64], quantization_table: &[u16; 64], output_linestride: usize, output: &mut [u8], ) { // The loop below will write to positions [output_linestride * i, output_linestride * i + 8) // for 0<=i<8. Thus, the last accessed position is at an offset of output_linestrade * 7 + 7, // and if that position is in-bounds, so are all other accesses. assert!( output.len() > output_linestride .checked_mul(7) .unwrap() .checked_add(7) .unwrap() ); const SHIFT: i32 = 3; // Read the DCT coefficients, scale them up and dequantize them. let mut data = [vdupq_n_s16(0); 8]; for i in 0..8 { data[i] = vshlq_n_s16( vmulq_s16( vld1q_s16(coefficients.as_ptr().wrapping_add(i * 8)), vreinterpretq_s16_u16(vld1q_u16(quantization_table.as_ptr().wrapping_add(i * 8))), ), SHIFT, ); } // Usual column IDCT - transpose - column IDCT - transpose approach. idct8(&mut data); transpose8(&mut data); idct8(&mut data); transpose8(&mut data); for i in 0..8 { // The two passes of the IDCT algorithm give us a factor of 8, so the shift here is // increased by 3. // As values will be stored in a u8, they need to be 128-centered and not 0-centered. // We add 128 with the appropriate shift for that purpose. const OFFSET: i16 = 128 << (SHIFT + 3); // We want rounding right shift, so we should add (1/2) << (SHIFT+3) before shifting. const ROUNDING_BIAS: i16 = (1 << (SHIFT + 3)) >> 1; let data_with_offset = vqaddq_s16(data[i], vdupq_n_s16(OFFSET + ROUNDING_BIAS)); vst1_u8( output.as_mut_ptr().wrapping_add(output_linestride * i), vqshrun_n_s16(data_with_offset, SHIFT + 3), ); } } #[cfg(all(feature = "nightly_aarch64_neon", target_arch = "aarch64"))] #[target_feature(enable = "neon")] pub unsafe fn color_convert_line_ycbcr(y: &[u8], cb: &[u8], cr: &[u8], output: &mut [u8]) -> usize { assert!(output.len() % 3 == 0); let num = output.len() / 3; assert!(num <= y.len()); assert!(num <= cb.len()); assert!(num <= cr.len()); let num_vecs = num / 8; for i in 0..num_vecs { const SHIFT: i32 = 6; // Load. let y = vld1_u8(y.as_ptr().wrapping_add(i * 8)); let cb = vld1_u8(cb.as_ptr().wrapping_add(i * 8)); let cr = vld1_u8(cr.as_ptr().wrapping_add(i * 8)); // Convert to 16 bit and shift. let y = vreinterpretq_s16_u16(vshll_n_u8(y, SHIFT)); let cb = vreinterpretq_s16_u16(vshll_n_u8(cb, SHIFT)); let cr = vreinterpretq_s16_u16(vshll_n_u8(cr, SHIFT)); // Add offsets let y = vqaddq_s16(y, vdupq_n_s16((1 << SHIFT) >> 1)); let c128 = vdupq_n_s16(128 << SHIFT); let cb = vqsubq_s16(cb, c128); let cr = vqsubq_s16(cr, c128); // Compute cr * 1.402, cb * 0.34414, cr * 0.71414, cb * 1.772 let cr_140200 = vqaddq_s16(vqrdmulhq_n_s16(cr, 13173), cr); let cb_034414 = vqrdmulhq_n_s16(cb, 11276); let cr_071414 = vqrdmulhq_n_s16(cr, 23401); let cb_177200 = vqaddq_s16(vqrdmulhq_n_s16(cb, 25297), cb); // Last conversion step. let r = vqaddq_s16(y, cr_140200); let g = vqsubq_s16(y, vqaddq_s16(cb_034414, cr_071414)); let b = vqaddq_s16(y, cb_177200); // Shift back and convert to u8. let r = vqshrun_n_s16(r, SHIFT); let g = vqshrun_n_s16(g, SHIFT); let b = vqshrun_n_s16(b, SHIFT); // Shuffle + store. vst3_u8( output.as_mut_ptr().wrapping_add(24 * i), uint8x8x3_t(r, g, b), ); } num_vecs * 8 } jpeg-decoder-0.3.0/src/arch/ssse3.rs000064400000000000000000000271050072674642500153230ustar 00000000000000#[cfg(target_arch = "x86")] use std::arch::x86::*; #[cfg(target_arch = "x86_64")] use std::arch::x86_64::*; #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] #[target_feature(enable = "ssse3")] unsafe fn idct8(data: &mut [__m128i; 8]) { // The fixed-point constants here are obtained by taking the fractional part of the constants // from the non-SIMD implementation and scaling them up by 1<<15. This is because // _mm_mulhrs_epi16(a, b) is effectively equivalent to (a*b)>>15 (except for possibly some // slight differences in rounding). // The code here is effectively equivalent to the calls to "kernel" in idct.rs, except that it // doesn't apply any further scaling and fixed point constants have a different precision. let p2 = data[2]; let p3 = data[6]; let p1 = _mm_mulhrs_epi16(_mm_adds_epi16(p2, p3), _mm_set1_epi16(17734)); // 0.5411961 let t2 = _mm_subs_epi16( _mm_subs_epi16(p1, p3), _mm_mulhrs_epi16(p3, _mm_set1_epi16(27779)), // 0.847759065 ); let t3 = _mm_adds_epi16(p1, _mm_mulhrs_epi16(p2, _mm_set1_epi16(25079))); // 0.765366865 let p2 = data[0]; let p3 = data[4]; let t0 = _mm_adds_epi16(p2, p3); let t1 = _mm_subs_epi16(p2, p3); let x0 = _mm_adds_epi16(t0, t3); let x3 = _mm_subs_epi16(t0, t3); let x1 = _mm_adds_epi16(t1, t2); let x2 = _mm_subs_epi16(t1, t2); let t0 = data[7]; let t1 = data[5]; let t2 = data[3]; let t3 = data[1]; let p3 = _mm_adds_epi16(t0, t2); let p4 = _mm_adds_epi16(t1, t3); let p1 = _mm_adds_epi16(t0, t3); let p2 = _mm_adds_epi16(t1, t2); let p5 = _mm_adds_epi16(p3, p4); let p5 = _mm_adds_epi16(p5, _mm_mulhrs_epi16(p5, _mm_set1_epi16(5763))); // 0.175875602 let t0 = _mm_mulhrs_epi16(t0, _mm_set1_epi16(9786)); // 0.298631336 let t1 = _mm_adds_epi16( _mm_adds_epi16(t1, t1), _mm_mulhrs_epi16(t1, _mm_set1_epi16(1741)), // 0.053119869 ); let t2 = _mm_adds_epi16( _mm_adds_epi16(t2, _mm_adds_epi16(t2, t2)), _mm_mulhrs_epi16(t2, _mm_set1_epi16(2383)), // 0.072711026 ); let t3 = _mm_adds_epi16(t3, _mm_mulhrs_epi16(t3, _mm_set1_epi16(16427))); // 0.501321110 let p1 = _mm_subs_epi16(p5, _mm_mulhrs_epi16(p1, _mm_set1_epi16(29490))); // 0.899976223 let p2 = _mm_subs_epi16( _mm_subs_epi16(_mm_subs_epi16(p5, p2), p2), _mm_mulhrs_epi16(p2, _mm_set1_epi16(18446)), // 0.562915447 ); let p3 = _mm_subs_epi16( _mm_mulhrs_epi16(p3, _mm_set1_epi16(-31509)), // -0.961570560 p3, ); let p4 = _mm_mulhrs_epi16(p4, _mm_set1_epi16(-12785)); // -0.390180644 let t3 = _mm_adds_epi16(_mm_adds_epi16(p1, p4), t3); let t2 = _mm_adds_epi16(_mm_adds_epi16(p2, p3), t2); let t1 = _mm_adds_epi16(_mm_adds_epi16(p2, p4), t1); let t0 = _mm_adds_epi16(_mm_adds_epi16(p1, p3), t0); data[0] = _mm_adds_epi16(x0, t3); data[7] = _mm_subs_epi16(x0, t3); data[1] = _mm_adds_epi16(x1, t2); data[6] = _mm_subs_epi16(x1, t2); data[2] = _mm_adds_epi16(x2, t1); data[5] = _mm_subs_epi16(x2, t1); data[3] = _mm_adds_epi16(x3, t0); data[4] = _mm_subs_epi16(x3, t0); } #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] #[target_feature(enable = "ssse3")] unsafe fn transpose8(data: &mut [__m128i; 8]) { // Transpose a 8x8 matrix with a sequence of interleaving operations. // Naming: dABl contains elements from the *l*ower halves of vectors A and B, interleaved, i.e. // A0 B0 A1 B1 ... // dABCDll contains elements from the lower quarter (ll) of vectors A, B, C, D, interleaved - // A0 B0 C0 D0 A1 B1 C1 D1 ... let d01l = _mm_unpacklo_epi16(data[0], data[1]); let d23l = _mm_unpacklo_epi16(data[2], data[3]); let d45l = _mm_unpacklo_epi16(data[4], data[5]); let d67l = _mm_unpacklo_epi16(data[6], data[7]); let d01h = _mm_unpackhi_epi16(data[0], data[1]); let d23h = _mm_unpackhi_epi16(data[2], data[3]); let d45h = _mm_unpackhi_epi16(data[4], data[5]); let d67h = _mm_unpackhi_epi16(data[6], data[7]); // Operating on 32-bits will interleave *consecutive pairs* of 16-bit integers. let d0123ll = _mm_unpacklo_epi32(d01l, d23l); let d0123lh = _mm_unpackhi_epi32(d01l, d23l); let d4567ll = _mm_unpacklo_epi32(d45l, d67l); let d4567lh = _mm_unpackhi_epi32(d45l, d67l); let d0123hl = _mm_unpacklo_epi32(d01h, d23h); let d0123hh = _mm_unpackhi_epi32(d01h, d23h); let d4567hl = _mm_unpacklo_epi32(d45h, d67h); let d4567hh = _mm_unpackhi_epi32(d45h, d67h); // Operating on 64-bits will interleave *consecutive quadruples* of 16-bit integers. data[0] = _mm_unpacklo_epi64(d0123ll, d4567ll); data[1] = _mm_unpackhi_epi64(d0123ll, d4567ll); data[2] = _mm_unpacklo_epi64(d0123lh, d4567lh); data[3] = _mm_unpackhi_epi64(d0123lh, d4567lh); data[4] = _mm_unpacklo_epi64(d0123hl, d4567hl); data[5] = _mm_unpackhi_epi64(d0123hl, d4567hl); data[6] = _mm_unpacklo_epi64(d0123hh, d4567hh); data[7] = _mm_unpackhi_epi64(d0123hh, d4567hh); } #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] #[target_feature(enable = "ssse3")] pub unsafe fn dequantize_and_idct_block_8x8( coefficients: &[i16; 64], quantization_table: &[u16; 64], output_linestride: usize, output: &mut [u8], ) { // The loop below will write to positions [output_linestride * i, output_linestride * i + 8) // for 0<=i<8. Thus, the last accessed position is at an offset of output_linestrade * 7 + 7, // and if that position is in-bounds, so are all other accesses. assert!( output.len() > output_linestride .checked_mul(7) .unwrap() .checked_add(7) .unwrap() ); #[cfg(target_arch = "x86")] use std::arch::x86::*; #[cfg(target_arch = "x86_64")] use std::arch::x86_64::*; const SHIFT: i32 = 3; // Read the DCT coefficients, scale them up and dequantize them. let mut data = [_mm_setzero_si128(); 8]; for i in 0..8 { data[i] = _mm_slli_epi16( _mm_mullo_epi16( _mm_loadu_si128(coefficients.as_ptr().wrapping_add(i * 8) as *const _), _mm_loadu_si128(quantization_table.as_ptr().wrapping_add(i * 8) as *const _), ), SHIFT, ); } // Usual column IDCT - transpose - column IDCT - transpose approach. idct8(&mut data); transpose8(&mut data); idct8(&mut data); transpose8(&mut data); for i in 0..8 { let mut buf = [0u8; 16]; // The two passes of the IDCT algorithm give us a factor of 8, so the shift here is // increased by 3. // As values will be stored in a u8, they need to be 128-centered and not 0-centered. // We add 128 with the appropriate shift for that purpose. const OFFSET: i16 = 128 << (SHIFT + 3); // We want rounding right shift, so we should add (1/2) << (SHIFT+3) before shifting. const ROUNDING_BIAS: i16 = (1 << (SHIFT + 3)) >> 1; let data_with_offset = _mm_adds_epi16(data[i], _mm_set1_epi16(OFFSET + ROUNDING_BIAS)); _mm_storeu_si128( buf.as_mut_ptr() as *mut _, _mm_packus_epi16( _mm_srai_epi16(data_with_offset, SHIFT + 3), _mm_setzero_si128(), ), ); std::ptr::copy_nonoverlapping::( buf.as_ptr(), output.as_mut_ptr().wrapping_add(output_linestride * i) as *mut _, 8, ); } } #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] #[target_feature(enable = "ssse3")] pub unsafe fn color_convert_line_ycbcr(y: &[u8], cb: &[u8], cr: &[u8], output: &mut [u8]) -> usize { assert!(output.len() % 3 == 0); let num = output.len() / 3; assert!(num <= y.len()); assert!(num <= cb.len()); assert!(num <= cr.len()); // _mm_loadu_si64 generates incorrect code for Rust <1.58. To circumvent this, we use a full // 128-bit load, but that requires leaving an extra vector of border to the scalar code. // From Rust 1.58 on, the _mm_loadu_si128 can be replaced with _mm_loadu_si64 and this // .saturating_sub() can be removed. let num_vecs = (num / 8).saturating_sub(1); for i in 0..num_vecs { const SHIFT: i32 = 6; // Load. let y = _mm_loadu_si128(y.as_ptr().wrapping_add(i * 8) as *const _); let cb = _mm_loadu_si128(cb.as_ptr().wrapping_add(i * 8) as *const _); let cr = _mm_loadu_si128(cr.as_ptr().wrapping_add(i * 8) as *const _); // Convert to 16 bit. let shuf16 = _mm_setr_epi8( 0, -0x7F, 1, -0x7F, 2, -0x7F, 3, -0x7F, 4, -0x7F, 5, -0x7F, 6, -0x7F, 7, -0x7F, ); let y = _mm_slli_epi16(_mm_shuffle_epi8(y, shuf16), SHIFT); let cb = _mm_slli_epi16(_mm_shuffle_epi8(cb, shuf16), SHIFT); let cr = _mm_slli_epi16(_mm_shuffle_epi8(cr, shuf16), SHIFT); // Add offsets let c128 = _mm_set1_epi16(128 << SHIFT); let y = _mm_adds_epi16(y, _mm_set1_epi16((1 << SHIFT) >> 1)); let cb = _mm_subs_epi16(cb, c128); let cr = _mm_subs_epi16(cr, c128); // Compute cr * 1.402, cb * 0.34414, cr * 0.71414, cb * 1.772 let cr_140200 = _mm_adds_epi16(_mm_mulhrs_epi16(cr, _mm_set1_epi16(13173)), cr); let cb_034414 = _mm_mulhrs_epi16(cb, _mm_set1_epi16(11276)); let cr_071414 = _mm_mulhrs_epi16(cr, _mm_set1_epi16(23401)); let cb_177200 = _mm_adds_epi16(_mm_mulhrs_epi16(cb, _mm_set1_epi16(25297)), cb); // Last conversion step. let r = _mm_adds_epi16(y, cr_140200); let g = _mm_subs_epi16(y, _mm_adds_epi16(cb_034414, cr_071414)); let b = _mm_adds_epi16(y, cb_177200); // Shift back and convert to u8. let zero = _mm_setzero_si128(); let r = _mm_packus_epi16(_mm_srai_epi16(r, SHIFT), zero); let g = _mm_packus_epi16(_mm_srai_epi16(g, SHIFT), zero); let b = _mm_packus_epi16(_mm_srai_epi16(b, SHIFT), zero); // Shuffle rrrrrrrrggggggggbbbbbbbb to rgbrgbrgb... // Control vectors for _mm_shuffle_epi8. -0x7F is selected so that the resulting position // after _mm_shuffle_epi8 will be filled with 0, so that the r, g, and b vectors can then // be OR-ed together. let shufr = _mm_setr_epi8( 0, -0x7F, -0x7F, 1, -0x7F, -0x7F, 2, -0x7F, -0x7F, 3, -0x7F, -0x7F, 4, -0x7F, -0x7F, 5, ); let shufg = _mm_setr_epi8( -0x7F, 0, -0x7F, -0x7F, 1, -0x7F, -0x7F, 2, -0x7F, -0x7F, 3, -0x7F, -0x7F, 4, -0x7F, -0x7F, ); let shufb = _mm_alignr_epi8(shufg, shufg, 15); let rgb_low = _mm_or_si128( _mm_shuffle_epi8(r, shufr), _mm_or_si128(_mm_shuffle_epi8(g, shufg), _mm_shuffle_epi8(b, shufb)), ); // For the next part of the rgb vectors, we need to select R values from 6 up, G and B from // 5 up. The highest bit of -0x7F + 6 is still set, so the corresponding location will // still be 0. let shufr1 = _mm_add_epi8(shufb, _mm_set1_epi8(6)); let shufg1 = _mm_add_epi8(shufr, _mm_set1_epi8(5)); let shufb1 = _mm_add_epi8(shufg, _mm_set1_epi8(5)); let rgb_hi = _mm_or_si128( _mm_shuffle_epi8(r, shufr1), _mm_or_si128(_mm_shuffle_epi8(g, shufg1), _mm_shuffle_epi8(b, shufb1)), ); let mut data = [0u8; 32]; _mm_storeu_si128(data.as_mut_ptr() as *mut _, rgb_low); _mm_storeu_si128(data.as_mut_ptr().wrapping_add(16) as *mut _, rgb_hi); std::ptr::copy_nonoverlapping::( data.as_ptr(), output.as_mut_ptr().wrapping_add(24 * i), 24, ); } num_vecs * 8 } jpeg-decoder-0.3.0/src/decoder/lossless.rs000064400000000000000000000242040072674642500166170ustar 00000000000000use std::io::Read; use crate::decoder::{Decoder, MAX_COMPONENTS}; use crate::error::{Error, Result}; use crate::huffman::HuffmanDecoder; use crate::marker::Marker; use crate::parser::Predictor; use crate::parser::{Component, FrameInfo, ScanInfo}; impl Decoder { /// decode_scan_lossless pub fn decode_scan_lossless( &mut self, frame: &FrameInfo, scan: &ScanInfo, ) -> Result<(Option, Vec>)> { let ncomp = scan.component_indices.len(); let npixel = frame.image_size.height as usize * frame.image_size.width as usize; assert!(ncomp <= MAX_COMPONENTS); let mut results = vec![vec![0u16; npixel]; ncomp]; let components: Vec = scan .component_indices .iter() .map(|&i| frame.components[i].clone()) .collect(); // Verify that all required huffman tables has been set. if scan .dc_table_indices .iter() .any(|&i| self.dc_huffman_tables[i].is_none()) { return Err(Error::Format( "scan makes use of unset dc huffman table".to_owned(), )); } let mut huffman = HuffmanDecoder::new(); let reader = &mut self.reader; let mut mcus_left_until_restart = self.restart_interval; let mut expected_rst_num = 0; let mut ra = [0u16; MAX_COMPONENTS]; let mut rb = [0u16; MAX_COMPONENTS]; let mut rc = [0u16; MAX_COMPONENTS]; let width = frame.image_size.width as usize; let height = frame.image_size.height as usize; let mut differences = vec![Vec::with_capacity(npixel); ncomp]; for _mcu_y in 0..height { for _mcu_x in 0..width { if self.restart_interval > 0 { if mcus_left_until_restart == 0 { match huffman.take_marker(reader)? { Some(Marker::RST(n)) => { if n != expected_rst_num { return Err(Error::Format(format!( "found RST{} where RST{} was expected", n, expected_rst_num ))); } huffman.reset(); expected_rst_num = (expected_rst_num + 1) % 8; mcus_left_until_restart = self.restart_interval; } Some(marker) => { return Err(Error::Format(format!( "found marker {:?} inside scan where RST{} was expected", marker, expected_rst_num ))) } None => { return Err(Error::Format(format!( "no marker found where RST{} was expected", expected_rst_num ))) } } } mcus_left_until_restart -= 1; } for (i, _component) in components.iter().enumerate() { let dc_table = self.dc_huffman_tables[scan.dc_table_indices[i]] .as_ref() .unwrap(); let value = huffman.decode(reader, dc_table)?; let diff = match value { 0 => 0, 1..=15 => huffman.receive_extend(reader, value)? as i32, 16 => 32768, _ => { // Section F.1.2.1.1 // Table F.1 return Err(Error::Format( "invalid DC difference magnitude category".to_owned(), )); } }; differences[i].push(diff); } } } if scan.predictor_selection == Predictor::Ra { for (i, _component) in components.iter().enumerate() { // calculate the top left pixel let diff = differences[i][0]; let prediction = 1 << (frame.precision - scan.point_transform - 1) as i32; let result = ((prediction + diff) & 0xFFFF) as u16; // modulo 2^16 let result = result << scan.point_transform; results[i][0] = result; // calculate leftmost column, using top pixel as predictor let mut previous = result; for mcu_y in 1..height { let diff = differences[i][mcu_y * width]; let prediction = previous as i32; let result = ((prediction + diff) & 0xFFFF) as u16; // modulo 2^16 let result = result << scan.point_transform; results[i][mcu_y * width] = result; previous = result; } // calculate rows, using left pixel as predictor for mcu_y in 0..height { for mcu_x in 1..width { let diff = differences[i][mcu_y * width + mcu_x]; let prediction = results[i][mcu_y * width + mcu_x - 1] as i32; let result = ((prediction + diff) & 0xFFFF) as u16; // modulo 2^16 let result = result << scan.point_transform; results[i][mcu_y * width + mcu_x] = result; } } } } else { for mcu_y in 0..height { for mcu_x in 0..width { for (i, _component) in components.iter().enumerate() { let diff = differences[i][mcu_y * width + mcu_x]; // The following lines could be further optimized, e.g. moving the checks // and updates of the previous values into the prediction function or // iterating such that diagonals with mcu_x + mcu_y = const are computed at // the same time to exploit independent predictions in this case if mcu_x > 0 { ra[i] = results[i][mcu_y * frame.image_size.width as usize + mcu_x - 1]; } if mcu_y > 0 { rb[i] = results[i][(mcu_y - 1) * frame.image_size.width as usize + mcu_x]; if mcu_x > 0 { rc[i] = results[i] [(mcu_y - 1) * frame.image_size.width as usize + (mcu_x - 1)]; } } let prediction = predict( ra[i] as i32, rb[i] as i32, rc[i] as i32, scan.predictor_selection, scan.point_transform, frame.precision, mcu_x, mcu_y, self.restart_interval > 0 && mcus_left_until_restart == self.restart_interval - 1, ); let result = ((prediction + diff) & 0xFFFF) as u16; // modulo 2^16 results[i][mcu_y * width + mcu_x] = result << scan.point_transform; } } } } let mut marker = huffman.take_marker(&mut self.reader)?; while let Some(Marker::RST(_)) = marker { marker = self.read_marker().ok(); } Ok((marker, results)) } } /// H.1.2.1 fn predict( ra: i32, rb: i32, rc: i32, predictor: Predictor, point_transform: u8, input_precision: u8, ix: usize, iy: usize, restart: bool, ) -> i32 { if (ix == 0 && iy == 0) || restart { // start of first line or restart if input_precision > 1 + point_transform { 1 << (input_precision - point_transform - 1) } else { 0 } } else if iy == 0 { // rest of first line ra } else if ix == 0 { // start of other line rb } else { // use predictor Table H.1 match predictor { Predictor::NoPrediction => 0, Predictor::Ra => ra, Predictor::Rb => rb, Predictor::Rc => rc, Predictor::RaRbRc1 => ra + rb - rc, Predictor::RaRbRc2 => ra + ((rb - rc) >> 1), Predictor::RaRbRc3 => rb + ((ra - rc) >> 1), Predictor::RaRb => (ra + rb) / 2, } } } pub fn compute_image_lossless(frame: &FrameInfo, mut data: Vec>) -> Result> { if data.is_empty() || data.iter().any(Vec::is_empty) { return Err(Error::Format("not all components have data".to_owned())); } let output_size = frame.output_size; let components = &frame.components; let ncomp = components.len(); if ncomp == 1 { let decoded = convert_to_u8(frame, data.remove(0)); Ok(decoded) } else { let mut decoded: Vec = vec![0u16; ncomp * output_size.width as usize * output_size.height as usize]; for (x, chunk) in decoded.chunks_mut(ncomp).enumerate() { for (i, (component_data, _)) in data.iter().zip(components.iter()).enumerate() { chunk[i] = component_data[x]; } } let decoded = convert_to_u8(frame, decoded); Ok(decoded) } } fn convert_to_u8(frame: &FrameInfo, data: Vec) -> Vec { if frame.precision == 8 { data.iter().map(|x| *x as u8).collect() } else { // we output native endian, which is the standard for image-rs let ne_bytes: Vec<_> = data.iter().map(|x| x.to_ne_bytes()).collect(); ne_bytes.concat() } } jpeg-decoder-0.3.0/src/decoder.rs000064400000000000000000001566720072674642500147670ustar 00000000000000use crate::error::{Error, Result, UnsupportedFeature}; use crate::huffman::{fill_default_mjpeg_tables, HuffmanDecoder, HuffmanTable}; use crate::marker::Marker; use crate::parser::{ parse_app, parse_com, parse_dht, parse_dqt, parse_dri, parse_sof, parse_sos, AdobeColorTransform, AppData, CodingProcess, Component, Dimensions, EntropyCoding, FrameInfo, IccChunk, ScanInfo, }; use crate::read_u8; use crate::upsampler::Upsampler; use crate::worker::{compute_image_parallel, PreferWorkerKind, RowData, Worker, WorkerScope}; use alloc::borrow::ToOwned; use alloc::sync::Arc; use alloc::vec::Vec; use alloc::{format, vec}; use core::cmp; use core::mem; use core::ops::Range; use std::convert::TryInto; use std::io::Read; pub const MAX_COMPONENTS: usize = 4; mod lossless; use self::lossless::compute_image_lossless; #[cfg_attr(rustfmt, rustfmt_skip)] static UNZIGZAG: [u8; 64] = [ 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63, ]; /// An enumeration over combinations of color spaces and bit depths a pixel can have. #[derive(Clone, Copy, Debug, PartialEq)] pub enum PixelFormat { /// Luminance (grayscale), 8 bits L8, /// Luminance (grayscale), 16 bits L16, /// RGB, 8 bits per channel RGB24, /// CMYK, 8 bits per channel CMYK32, } impl PixelFormat { /// Determine the size in bytes of each pixel in this format pub fn pixel_bytes(&self) -> usize { match self { PixelFormat::L8 => 1, PixelFormat::L16 => 2, PixelFormat::RGB24 => 3, PixelFormat::CMYK32 => 4, } } } /// Represents metadata of an image. #[derive(Clone, Copy, Debug, PartialEq)] pub struct ImageInfo { /// The width of the image, in pixels. pub width: u16, /// The height of the image, in pixels. pub height: u16, /// The pixel format of the image. pub pixel_format: PixelFormat, /// The coding process of the image. pub coding_process: CodingProcess, } /// Describes the colour transform to apply before binary data is returned #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[non_exhaustive] pub enum ColorTransform { /// No transform should be applied and the data is returned as-is. None, /// Unknown colour transformation Unknown, /// Grayscale transform should be applied (expects 1 channel) Grayscale, /// RGB transform should be applied. RGB, /// YCbCr transform should be applied. YCbCr, /// CMYK transform should be applied. CMYK, /// YCCK transform should be applied. YCCK, /// big gamut Y/Cb/Cr, bg-sYCC JcsBgYcc, /// big gamut red/green/blue, bg-sRGB JcsBgRgb, } /// JPEG decoder pub struct Decoder { reader: R, frame: Option, dc_huffman_tables: Vec>, ac_huffman_tables: Vec>, quantization_tables: [Option>; 4], restart_interval: u16, adobe_color_transform: Option, color_transform: Option, is_jfif: bool, is_mjpeg: bool, icc_markers: Vec, exif_data: Option>, // Used for progressive JPEGs. coefficients: Vec>, // Bitmask of which coefficients has been completely decoded. coefficients_finished: [u64; MAX_COMPONENTS], // Maximum allowed size of decoded image buffer decoding_buffer_size_limit: usize, } impl Decoder { /// Creates a new `Decoder` using the reader `reader`. pub fn new(reader: R) -> Decoder { Decoder { reader, frame: None, dc_huffman_tables: vec![None, None, None, None], ac_huffman_tables: vec![None, None, None, None], quantization_tables: [None, None, None, None], restart_interval: 0, adobe_color_transform: None, color_transform: None, is_jfif: false, is_mjpeg: false, icc_markers: Vec::new(), exif_data: None, coefficients: Vec::new(), coefficients_finished: [0; MAX_COMPONENTS], decoding_buffer_size_limit: usize::MAX, } } /// Colour transform to use when decoding the image. App segments relating to colour transforms /// will be ignored. pub fn set_color_transform(&mut self, transform: ColorTransform) { self.color_transform = Some(transform); } /// Set maximum buffer size allowed for decoded images pub fn set_max_decoding_buffer_size(&mut self, max: usize) { self.decoding_buffer_size_limit = max; } /// Returns metadata about the image. /// /// The returned value will be `None` until a call to either `read_info` or `decode` has /// returned `Ok`. pub fn info(&self) -> Option { match self.frame { Some(ref frame) => { let pixel_format = match frame.components.len() { 1 => match frame.precision { 8 => PixelFormat::L8, 16 => PixelFormat::L16, _ => panic!(), }, 3 => PixelFormat::RGB24, 4 => PixelFormat::CMYK32, _ => panic!(), }; Some(ImageInfo { width: frame.output_size.width, height: frame.output_size.height, pixel_format, coding_process: frame.coding_process, }) } None => None, } } /// Returns raw exif data, starting at the TIFF header, if the image contains any. /// /// The returned value will be `None` until a call to `decode` has returned `Ok`. pub fn exif_data(&self) -> Option<&[u8]> { self.exif_data.as_deref() } /// Returns the embeded icc profile if the image contains one. pub fn icc_profile(&self) -> Option> { let mut marker_present: [Option<&IccChunk>; 256] = [None; 256]; let num_markers = self.icc_markers.len(); if num_markers == 0 || num_markers >= 255 { return None; } // check the validity of the markers for chunk in &self.icc_markers { if usize::from(chunk.num_markers) != num_markers { // all the lengths must match return None; } if chunk.seq_no == 0 { return None; } if marker_present[usize::from(chunk.seq_no)].is_some() { // duplicate seq_no return None; } else { marker_present[usize::from(chunk.seq_no)] = Some(chunk); } } // assemble them together by seq_no failing if any are missing let mut data = Vec::new(); // seq_no's start at 1 for &chunk in marker_present.get(1..=num_markers)? { data.extend_from_slice(&chunk?.data); } Some(data) } /// Heuristic to avoid starting thread, synchronization if we expect a small amount of /// parallelism to be utilized. fn select_worker(frame: &FrameInfo, worker_preference: PreferWorkerKind) -> PreferWorkerKind { const PARALLELISM_THRESHOLD: u64 = 128 * 128; match worker_preference { PreferWorkerKind::Immediate => PreferWorkerKind::Immediate, PreferWorkerKind::Multithreaded => { let width: u64 = frame.output_size.width.into(); let height: u64 = frame.output_size.width.into(); if width * height > PARALLELISM_THRESHOLD { PreferWorkerKind::Multithreaded } else { PreferWorkerKind::Immediate } } } } /// Tries to read metadata from the image without decoding it. /// /// If successful, the metadata can be obtained using the `info` method. pub fn read_info(&mut self) -> Result<()> { WorkerScope::with(|worker| self.decode_internal(true, worker)).map(|_| ()) } /// Configure the decoder to scale the image during decoding. /// /// This efficiently scales the image by the smallest supported scale /// factor that produces an image larger than or equal to the requested /// size in at least one axis. The currently implemented scale factors /// are 1/8, 1/4, 1/2 and 1. /// /// To generate a thumbnail of an exact size, pass the desired size and /// then scale to the final size using a traditional resampling algorithm. pub fn scale(&mut self, requested_width: u16, requested_height: u16) -> Result<(u16, u16)> { self.read_info()?; let frame = self.frame.as_mut().unwrap(); let idct_size = crate::idct::choose_idct_size( frame.image_size, Dimensions { width: requested_width, height: requested_height, }, ); frame.update_idct_size(idct_size)?; Ok((frame.output_size.width, frame.output_size.height)) } /// Decodes the image and returns the decoded pixels if successful. pub fn decode(&mut self) -> Result> { WorkerScope::with(|worker| self.decode_internal(false, worker)) } fn decode_internal( &mut self, stop_after_metadata: bool, worker_scope: &WorkerScope, ) -> Result> { if stop_after_metadata && self.frame.is_some() { // The metadata has already been read. return Ok(Vec::new()); } else if self.frame.is_none() && (read_u8(&mut self.reader)? != 0xFF || Marker::from_u8(read_u8(&mut self.reader)?) != Some(Marker::SOI)) { return Err(Error::Format( "first two bytes are not an SOI marker".to_owned(), )); } let mut previous_marker = Marker::SOI; let mut pending_marker = None; let mut scans_processed = 0; let mut planes = vec![ Vec::::new(); self.frame .as_ref() .map_or(0, |frame| frame.components.len()) ]; let mut planes_u16 = vec![ Vec::::new(); self.frame .as_ref() .map_or(0, |frame| frame.components.len()) ]; loop { let marker = match pending_marker.take() { Some(m) => m, None => self.read_marker()?, }; match marker { // Frame header Marker::SOF(..) => { // Section 4.10 // "An image contains only one frame in the cases of sequential and // progressive coding processes; an image contains multiple frames for the // hierarchical mode." if self.frame.is_some() { return Err(Error::Unsupported(UnsupportedFeature::Hierarchical)); } let frame = parse_sof(&mut self.reader, marker)?; let component_count = frame.components.len(); if frame.is_differential { return Err(Error::Unsupported(UnsupportedFeature::Hierarchical)); } if frame.entropy_coding == EntropyCoding::Arithmetic { return Err(Error::Unsupported( UnsupportedFeature::ArithmeticEntropyCoding, )); } if frame.precision != 8 && frame.coding_process != CodingProcess::Lossless { return Err(Error::Unsupported(UnsupportedFeature::SamplePrecision( frame.precision, ))); } if frame.precision != 8 && frame.precision != 16 { return Err(Error::Unsupported(UnsupportedFeature::SamplePrecision( frame.precision, ))); } if component_count != 1 && component_count != 3 && component_count != 4 { return Err(Error::Unsupported(UnsupportedFeature::ComponentCount( component_count as u8, ))); } // Make sure we support the subsampling ratios used. let _ = Upsampler::new( &frame.components, frame.image_size.width, frame.image_size.height, )?; self.frame = Some(frame); if stop_after_metadata { return Ok(Vec::new()); } planes = vec![Vec::new(); component_count]; planes_u16 = vec![Vec::new(); component_count]; } // Scan header Marker::SOS => { if self.frame.is_none() { return Err(Error::Format("scan encountered before frame".to_owned())); } let frame = self.frame.clone().unwrap(); let scan = parse_sos(&mut self.reader, &frame)?; if frame.coding_process == CodingProcess::DctProgressive && self.coefficients.is_empty() { self.coefficients = frame .components .iter() .map(|c| { let block_count = c.block_size.width as usize * c.block_size.height as usize; vec![0; block_count * 64] }) .collect(); } if frame.coding_process == CodingProcess::Lossless { let (marker, data) = self.decode_scan_lossless(&frame, &scan)?; for (i, plane) in data .into_iter() .enumerate() .filter(|&(_, ref plane)| !plane.is_empty()) { planes_u16[i] = plane; } pending_marker = marker; } else { // This was previously buggy, so let's explain the log here a bit. When a // progressive frame is encoded then the coefficients (DC, AC) of each // component (=color plane) can be split amongst scans. In particular it can // happen or at least occurs in the wild that a scan contains coefficient 0 of // all components. If now one but not all components had all other coefficients // delivered in previous scans then such a scan contains all components but // completes only some of them! (This is technically NOT permitted for all // other coefficients as the standard dictates that scans with coefficients // other than the 0th must only contain ONE component so we would either // complete it or not. We may want to detect and error in case more component // are part of a scan than allowed.) What a weird edge case. // // But this means we track precisely which components get completed here. let mut finished = [false; MAX_COMPONENTS]; if scan.successive_approximation_low == 0 { for (&i, component_finished) in scan.component_indices.iter().zip(&mut finished) { if self.coefficients_finished[i] == !0 { continue; } for j in scan.spectral_selection.clone() { self.coefficients_finished[i] |= 1 << j; } if self.coefficients_finished[i] == !0 { *component_finished = true; } } } let preference = Self::select_worker(&frame, PreferWorkerKind::Multithreaded); let (marker, data) = worker_scope .get_or_init_worker(preference, |worker| { self.decode_scan(&frame, &scan, worker, &finished) })?; if let Some(data) = data { for (i, plane) in data .into_iter() .enumerate() .filter(|&(_, ref plane)| !plane.is_empty()) { if self.coefficients_finished[i] == !0 { planes[i] = plane; } } } pending_marker = marker; } scans_processed += 1; } // Table-specification and miscellaneous markers // Quantization table-specification Marker::DQT => { let tables = parse_dqt(&mut self.reader)?; for (i, &table) in tables.iter().enumerate() { if let Some(table) = table { let mut unzigzagged_table = [0u16; 64]; for j in 0..64 { unzigzagged_table[UNZIGZAG[j] as usize] = table[j]; } self.quantization_tables[i] = Some(Arc::new(unzigzagged_table)); } } } // Huffman table-specification Marker::DHT => { let is_baseline = self.frame.as_ref().map(|frame| frame.is_baseline); let (dc_tables, ac_tables) = parse_dht(&mut self.reader, is_baseline)?; let current_dc_tables = mem::take(&mut self.dc_huffman_tables); self.dc_huffman_tables = dc_tables .into_iter() .zip(current_dc_tables.into_iter()) .map(|(a, b)| a.or(b)) .collect(); let current_ac_tables = mem::take(&mut self.ac_huffman_tables); self.ac_huffman_tables = ac_tables .into_iter() .zip(current_ac_tables.into_iter()) .map(|(a, b)| a.or(b)) .collect(); } // Arithmetic conditioning table-specification Marker::DAC => { return Err(Error::Unsupported( UnsupportedFeature::ArithmeticEntropyCoding, )) } // Restart interval definition Marker::DRI => self.restart_interval = parse_dri(&mut self.reader)?, // Comment Marker::COM => { let _comment = parse_com(&mut self.reader)?; } // Application data Marker::APP(..) => { if let Some(data) = parse_app(&mut self.reader, marker)? { match data { AppData::Adobe(color_transform) => { self.adobe_color_transform = Some(color_transform) } AppData::Jfif => { // From the JFIF spec: // "The APP0 marker is used to identify a JPEG FIF file. // The JPEG FIF APP0 marker is mandatory right after the SOI marker." // Some JPEGs in the wild does not follow this though, so we allow // JFIF headers anywhere APP0 markers are allowed. /* if previous_marker != Marker::SOI { return Err(Error::Format("the JFIF APP0 marker must come right after the SOI marker".to_owned())); } */ self.is_jfif = true; } AppData::Avi1 => self.is_mjpeg = true, AppData::Icc(icc) => self.icc_markers.push(icc), AppData::Exif(data) => self.exif_data = Some(data), } } } // Restart Marker::RST(..) => { // Some encoders emit a final RST marker after entropy-coded data, which // decode_scan does not take care of. So if we encounter one, we ignore it. if previous_marker != Marker::SOS { return Err(Error::Format( "RST found outside of entropy-coded data".to_owned(), )); } } // Define number of lines Marker::DNL => { // Section B.2.1 // "If a DNL segment (see B.2.5) is present, it shall immediately follow the first scan." if previous_marker != Marker::SOS || scans_processed != 1 { return Err(Error::Format( "DNL is only allowed immediately after the first scan".to_owned(), )); } return Err(Error::Unsupported(UnsupportedFeature::DNL)); } // Hierarchical mode markers Marker::DHP | Marker::EXP => { return Err(Error::Unsupported(UnsupportedFeature::Hierarchical)) } // End of image Marker::EOI => break, _ => { return Err(Error::Format(format!( "{:?} marker found where not allowed", marker ))) } } previous_marker = marker; } if self.frame.is_none() { return Err(Error::Format( "end of image encountered before frame".to_owned(), )); } let frame = self.frame.as_ref().unwrap(); let preference = Self::select_worker(&frame, PreferWorkerKind::Multithreaded); worker_scope.get_or_init_worker(preference, |worker| { self.decode_planes(worker, planes, planes_u16) }) } fn decode_planes( &mut self, worker: &mut dyn Worker, mut planes: Vec>, planes_u16: Vec>, ) -> Result> { if self.frame.is_none() { return Err(Error::Format( "end of image encountered before frame".to_owned(), )); } let frame = self.frame.as_ref().unwrap(); if { let required_mem = frame .components .len() .checked_mul(frame.output_size.width.into()) .and_then(|m| m.checked_mul(frame.output_size.height.into())); required_mem.map_or(true, |m| self.decoding_buffer_size_limit < m) } { return Err(Error::Format( "size of decoded image exceeds maximum allowed size".to_owned(), )); } // If we're decoding a progressive jpeg and a component is unfinished, render what we've got if frame.coding_process == CodingProcess::DctProgressive && self.coefficients.len() == frame.components.len() { for (i, component) in frame.components.iter().enumerate() { // Only dealing with unfinished components if self.coefficients_finished[i] == !0 { continue; } let quantization_table = match self.quantization_tables[component.quantization_table_index].clone() { Some(quantization_table) => quantization_table, None => continue, }; // Get the worker prepared let row_data = RowData { index: i, component: component.clone(), quantization_table, }; worker.start(row_data)?; // Send the rows over to the worker and collect the result let coefficients_per_mcu_row = usize::from(component.block_size.width) * usize::from(component.vertical_sampling_factor) * 64; let mut tasks = (0..frame.mcu_size.height).map(|mcu_y| { let offset = usize::from(mcu_y) * coefficients_per_mcu_row; let row_coefficients = self.coefficients[i][offset..offset + coefficients_per_mcu_row].to_vec(); (i, row_coefficients) }); // FIXME: additional potential work stealing opportunities for rayon case if we // also internally can parallelize over components. worker.append_rows(&mut tasks)?; planes[i] = worker.get_result(i)?; } } if frame.coding_process == CodingProcess::Lossless { compute_image_lossless(frame, planes_u16) } else { compute_image( &frame.components, planes, frame.output_size, self.determine_color_transform(), ) } } fn determine_color_transform(&self) -> ColorTransform { if let Some(color_transform) = self.color_transform { return color_transform; } let frame = self.frame.as_ref().unwrap(); if frame.components.len() == 1 { return ColorTransform::Grayscale; } // Using logic for determining colour as described here: https://entropymine.wordpress.com/2018/10/22/how-is-a-jpeg-images-color-type-determined/ if frame.components.len() == 3 { match ( frame.components[0].identifier, frame.components[1].identifier, frame.components[2].identifier, ) { (1, 2, 3) => { return ColorTransform::YCbCr; } (1, 34, 35) => { return ColorTransform::JcsBgYcc; } (82, 71, 66) => { return ColorTransform::RGB; } (114, 103, 98) => { return ColorTransform::JcsBgRgb; } _ => {} } if self.is_jfif { return ColorTransform::YCbCr; } } if let Some(colour_transform) = self.adobe_color_transform { match colour_transform { AdobeColorTransform::Unknown => { if frame.components.len() == 3 { return ColorTransform::RGB; } else if frame.components.len() == 4 { return ColorTransform::CMYK; } } AdobeColorTransform::YCbCr => { return ColorTransform::YCbCr; } AdobeColorTransform::YCCK => { return ColorTransform::YCCK; } } } else if frame.components.len() == 4 { return ColorTransform::CMYK; } if frame.components.len() == 4 { ColorTransform::YCCK } else if frame.components.len() == 3 { ColorTransform::YCbCr } else { ColorTransform::Unknown } } fn read_marker(&mut self) -> Result { loop { // This should be an error as the JPEG spec doesn't allow extraneous data between marker segments. // libjpeg allows this though and there are images in the wild utilising it, so we are // forced to support this behavior. // Sony Ericsson P990i is an example of a device which produce this sort of JPEGs. while read_u8(&mut self.reader)? != 0xFF {} // Section B.1.1.2 // All markers are assigned two-byte codes: an X’FF’ byte followed by a // byte which is not equal to 0 or X’FF’ (see Table B.1). Any marker may // optionally be preceded by any number of fill bytes, which are bytes // assigned code X’FF’. let mut byte = read_u8(&mut self.reader)?; // Section B.1.1.2 // "Any marker may optionally be preceded by any number of fill bytes, which are bytes assigned code X’FF’." while byte == 0xFF { byte = read_u8(&mut self.reader)?; } if byte != 0x00 && byte != 0xFF { return Ok(Marker::from_u8(byte).unwrap()); } } } fn decode_scan( &mut self, frame: &FrameInfo, scan: &ScanInfo, worker: &mut dyn Worker, finished: &[bool; MAX_COMPONENTS], ) -> Result<(Option, Option>>)> { assert!(scan.component_indices.len() <= MAX_COMPONENTS); let components: Vec = scan .component_indices .iter() .map(|&i| frame.components[i].clone()) .collect(); // Verify that all required quantization tables has been set. if components .iter() .any(|component| self.quantization_tables[component.quantization_table_index].is_none()) { return Err(Error::Format("use of unset quantization table".to_owned())); } if self.is_mjpeg { fill_default_mjpeg_tables( scan, &mut self.dc_huffman_tables, &mut self.ac_huffman_tables, ); } // Verify that all required huffman tables has been set. if scan.spectral_selection.start == 0 && scan .dc_table_indices .iter() .any(|&i| self.dc_huffman_tables[i].is_none()) { return Err(Error::Format( "scan makes use of unset dc huffman table".to_owned(), )); } if scan.spectral_selection.end > 1 && scan .ac_table_indices .iter() .any(|&i| self.ac_huffman_tables[i].is_none()) { return Err(Error::Format( "scan makes use of unset ac huffman table".to_owned(), )); } // Prepare the worker thread for the work to come. for (i, component) in components.iter().enumerate() { if finished[i] { let row_data = RowData { index: i, component: component.clone(), quantization_table: self.quantization_tables [component.quantization_table_index] .clone() .unwrap(), }; worker.start(row_data)?; } } let is_progressive = frame.coding_process == CodingProcess::DctProgressive; let is_interleaved = components.len() > 1; let mut dummy_block = [0i16; 64]; let mut huffman = HuffmanDecoder::new(); let mut dc_predictors = [0i16; MAX_COMPONENTS]; let mut mcus_left_until_restart = self.restart_interval; let mut expected_rst_num = 0; let mut eob_run = 0; let mut mcu_row_coefficients = vec![vec![]; components.len()]; if !is_progressive { for (i, component) in components.iter().enumerate().filter(|&(i, _)| finished[i]) { let coefficients_per_mcu_row = component.block_size.width as usize * component.vertical_sampling_factor as usize * 64; mcu_row_coefficients[i] = vec![0i16; coefficients_per_mcu_row]; } } // 4.8.2 // When reading from the stream, if the data is non-interleaved then an MCU consists of // exactly one block (effectively a 1x1 sample). let (mcu_horizontal_samples, mcu_vertical_samples) = if is_interleaved { let horizontal = components .iter() .map(|component| component.horizontal_sampling_factor as u16) .collect::>(); let vertical = components .iter() .map(|component| component.vertical_sampling_factor as u16) .collect::>(); (horizontal, vertical) } else { (vec![1], vec![1]) }; // This also affects how many MCU values we read from stream. If it's a non-interleaved stream, // the MCUs will be exactly the block count. let (max_mcu_x, max_mcu_y) = if is_interleaved { (frame.mcu_size.width, frame.mcu_size.height) } else { ( components[0].block_size.width, components[0].block_size.height, ) }; for mcu_y in 0..max_mcu_y { if mcu_y * 8 >= frame.image_size.height { break; } for mcu_x in 0..max_mcu_x { if mcu_x * 8 >= frame.image_size.width { break; } if self.restart_interval > 0 { if mcus_left_until_restart == 0 { match huffman.take_marker(&mut self.reader)? { Some(Marker::RST(n)) => { if n != expected_rst_num { return Err(Error::Format(format!( "found RST{} where RST{} was expected", n, expected_rst_num ))); } huffman.reset(); // Section F.2.1.3.1 dc_predictors = [0i16; MAX_COMPONENTS]; // Section G.1.2.2 eob_run = 0; expected_rst_num = (expected_rst_num + 1) % 8; mcus_left_until_restart = self.restart_interval; } Some(marker) => { return Err(Error::Format(format!( "found marker {:?} inside scan where RST{} was expected", marker, expected_rst_num ))) } None => { return Err(Error::Format(format!( "no marker found where RST{} was expected", expected_rst_num ))) } } } mcus_left_until_restart -= 1; } for (i, component) in components.iter().enumerate() { for v_pos in 0..mcu_vertical_samples[i] { for h_pos in 0..mcu_horizontal_samples[i] { let coefficients = if is_progressive { let block_y = (mcu_y * mcu_vertical_samples[i] + v_pos) as usize; let block_x = (mcu_x * mcu_horizontal_samples[i] + h_pos) as usize; let block_offset = (block_y * component.block_size.width as usize + block_x) * 64; &mut self.coefficients[scan.component_indices[i]] [block_offset..block_offset + 64] } else if finished[i] { // Because the worker thread operates in batches as if we were always interleaved, we // need to distinguish between a single-shot buffer and one that's currently in process // (for a non-interleaved) stream let mcu_batch_current_row = if is_interleaved { 0 } else { mcu_y % component.vertical_sampling_factor as u16 }; let block_y = (mcu_batch_current_row * mcu_vertical_samples[i] + v_pos) as usize; let block_x = (mcu_x * mcu_horizontal_samples[i] + h_pos) as usize; let block_offset = (block_y * component.block_size.width as usize + block_x) * 64; &mut mcu_row_coefficients[i][block_offset..block_offset + 64] } else { &mut dummy_block[..64] } .try_into() .unwrap(); if scan.successive_approximation_high == 0 { decode_block( &mut self.reader, coefficients, &mut huffman, self.dc_huffman_tables[scan.dc_table_indices[i]].as_ref(), self.ac_huffman_tables[scan.ac_table_indices[i]].as_ref(), scan.spectral_selection.clone(), scan.successive_approximation_low, &mut eob_run, &mut dc_predictors[i], )?; } else { decode_block_successive_approximation( &mut self.reader, coefficients, &mut huffman, self.ac_huffman_tables[scan.ac_table_indices[i]].as_ref(), scan.spectral_selection.clone(), scan.successive_approximation_low, &mut eob_run, )?; } } } } } // Send the coefficients from this MCU row to the worker thread for dequantization and idct. for (i, component) in components.iter().enumerate() { if finished[i] { // In the event of non-interleaved streams, if we're still building the buffer out, // keep going; don't send it yet. We also need to ensure we don't skip over the last // row(s) of the image. if !is_interleaved && (mcu_y + 1) * 8 < frame.image_size.height { if (mcu_y + 1) % component.vertical_sampling_factor as u16 > 0 { continue; } } let coefficients_per_mcu_row = component.block_size.width as usize * component.vertical_sampling_factor as usize * 64; let row_coefficients = if is_progressive { // Because non-interleaved streams will have multiple MCU rows concatenated together, // the row for calculating the offset is different. let worker_mcu_y = if is_interleaved { mcu_y } else { // Explicitly doing floor-division here mcu_y / component.vertical_sampling_factor as u16 }; let offset = worker_mcu_y as usize * coefficients_per_mcu_row; self.coefficients[scan.component_indices[i]] [offset..offset + coefficients_per_mcu_row] .to_vec() } else { mem::replace( &mut mcu_row_coefficients[i], vec![0i16; coefficients_per_mcu_row], ) }; // FIXME: additional potential work stealing opportunities for rayon case if we // also internally can parallelize over components. worker.append_row((i, row_coefficients))?; } } } let mut marker = huffman.take_marker(&mut self.reader)?; while let Some(Marker::RST(_)) = marker { marker = self.read_marker().ok(); } if finished.iter().any(|&c| c) { // Retrieve all the data from the worker thread. let mut data = vec![Vec::new(); frame.components.len()]; for (i, &component_index) in scan.component_indices.iter().enumerate() { if finished[i] { data[component_index] = worker.get_result(i)?; } } Ok((marker, Some(data))) } else { Ok((marker, None)) } } } fn decode_block( reader: &mut R, coefficients: &mut [i16; 64], huffman: &mut HuffmanDecoder, dc_table: Option<&HuffmanTable>, ac_table: Option<&HuffmanTable>, spectral_selection: Range, successive_approximation_low: u8, eob_run: &mut u16, dc_predictor: &mut i16, ) -> Result<()> { debug_assert_eq!(coefficients.len(), 64); if spectral_selection.start == 0 { // Section F.2.2.1 // Figure F.12 let value = huffman.decode(reader, dc_table.unwrap())?; let diff = match value { 0 => 0, 1..=11 => huffman.receive_extend(reader, value)?, _ => { // Section F.1.2.1.1 // Table F.1 return Err(Error::Format( "invalid DC difference magnitude category".to_owned(), )); } }; // Malicious JPEG files can cause this add to overflow, therefore we use wrapping_add. // One example of such a file is tests/crashtest/images/dc-predictor-overflow.jpg *dc_predictor = dc_predictor.wrapping_add(diff); coefficients[0] = *dc_predictor << successive_approximation_low; } let mut index = cmp::max(spectral_selection.start, 1); if index < spectral_selection.end && *eob_run > 0 { *eob_run -= 1; return Ok(()); } // Section F.1.2.2.1 while index < spectral_selection.end { if let Some((value, run)) = huffman.decode_fast_ac(reader, ac_table.unwrap())? { index += run; if index >= spectral_selection.end { break; } coefficients[UNZIGZAG[index as usize] as usize] = value << successive_approximation_low; index += 1; } else { let byte = huffman.decode(reader, ac_table.unwrap())?; let r = byte >> 4; let s = byte & 0x0f; if s == 0 { match r { 15 => index += 16, // Run length of 16 zero coefficients. _ => { *eob_run = (1 << r) - 1; if r > 0 { *eob_run += huffman.get_bits(reader, r)?; } break; } } } else { index += r; if index >= spectral_selection.end { break; } coefficients[UNZIGZAG[index as usize] as usize] = huffman.receive_extend(reader, s)? << successive_approximation_low; index += 1; } } } Ok(()) } fn decode_block_successive_approximation( reader: &mut R, coefficients: &mut [i16; 64], huffman: &mut HuffmanDecoder, ac_table: Option<&HuffmanTable>, spectral_selection: Range, successive_approximation_low: u8, eob_run: &mut u16, ) -> Result<()> { debug_assert_eq!(coefficients.len(), 64); let bit = 1 << successive_approximation_low; if spectral_selection.start == 0 { // Section G.1.2.1 if huffman.get_bits(reader, 1)? == 1 { coefficients[0] |= bit; } } else { // Section G.1.2.3 if *eob_run > 0 { *eob_run -= 1; refine_non_zeroes(reader, coefficients, huffman, spectral_selection, 64, bit)?; return Ok(()); } let mut index = spectral_selection.start; while index < spectral_selection.end { let byte = huffman.decode(reader, ac_table.unwrap())?; let r = byte >> 4; let s = byte & 0x0f; let mut zero_run_length = r; let mut value = 0; match s { 0 => { match r { 15 => { // Run length of 16 zero coefficients. // We don't need to do anything special here, zero_run_length is 15 // and then value (which is zero) gets written, resulting in 16 // zero coefficients. } _ => { *eob_run = (1 << r) - 1; if r > 0 { *eob_run += huffman.get_bits(reader, r)?; } // Force end of block. zero_run_length = 64; } } } 1 => { if huffman.get_bits(reader, 1)? == 1 { value = bit; } else { value = -bit; } } _ => return Err(Error::Format("unexpected huffman code".to_owned())), } let range = Range { start: index, end: spectral_selection.end, }; index = refine_non_zeroes(reader, coefficients, huffman, range, zero_run_length, bit)?; if value != 0 { coefficients[UNZIGZAG[index as usize] as usize] = value; } index += 1; } } Ok(()) } fn refine_non_zeroes( reader: &mut R, coefficients: &mut [i16; 64], huffman: &mut HuffmanDecoder, range: Range, zrl: u8, bit: i16, ) -> Result { debug_assert_eq!(coefficients.len(), 64); let last = range.end - 1; let mut zero_run_length = zrl; for i in range { let index = UNZIGZAG[i as usize] as usize; let coefficient = &mut coefficients[index]; if *coefficient == 0 { if zero_run_length == 0 { return Ok(i); } zero_run_length -= 1; } else if huffman.get_bits(reader, 1)? == 1 && *coefficient & bit == 0 { if *coefficient > 0 { *coefficient = coefficient .checked_add(bit) .ok_or_else(|| Error::Format("Coefficient overflow".to_owned()))?; } else { *coefficient = coefficient .checked_sub(bit) .ok_or_else(|| Error::Format("Coefficient overflow".to_owned()))?; } } } Ok(last) } fn compute_image( components: &[Component], mut data: Vec>, output_size: Dimensions, color_transform: ColorTransform, ) -> Result> { if data.is_empty() || data.iter().any(Vec::is_empty) { return Err(Error::Format("not all components have data".to_owned())); } if components.len() == 1 { let component = &components[0]; let mut decoded: Vec = data.remove(0); let width = component.size.width as usize; let height = component.size.height as usize; let size = width * height; let line_stride = component.block_size.width as usize * component.dct_scale; // if the image width is a multiple of the block size, // then we don't have to move bytes in the decoded data if usize::from(output_size.width) != line_stride { // The first line already starts at index 0, so we need to move only lines 1..height // We move from the top down because all lines are being moved backwards. for y in 1..height { let destination_idx = y * width; let source_idx = y * line_stride; let end = source_idx + width; decoded.copy_within(source_idx..end, destination_idx); } } decoded.resize(size, 0); Ok(decoded) } else { compute_image_parallel(components, data, output_size, color_transform) } } pub(crate) fn choose_color_convert_func( component_count: usize, color_transform: ColorTransform, ) -> Result], &mut [u8])> { match component_count { 3 => match color_transform { ColorTransform::None => Ok(color_no_convert), ColorTransform::Grayscale => Err(Error::Format( "Invalid number of channels (3) for Grayscale data".to_string(), )), ColorTransform::RGB => Ok(color_convert_line_rgb), ColorTransform::YCbCr => Ok(color_convert_line_ycbcr), ColorTransform::CMYK => Err(Error::Format( "Invalid number of channels (3) for CMYK data".to_string(), )), ColorTransform::YCCK => Err(Error::Format( "Invalid number of channels (3) for YCCK data".to_string(), )), ColorTransform::JcsBgYcc => Err(Error::Unsupported( UnsupportedFeature::ColorTransform(ColorTransform::JcsBgYcc), )), ColorTransform::JcsBgRgb => Err(Error::Unsupported( UnsupportedFeature::ColorTransform(ColorTransform::JcsBgRgb), )), ColorTransform::Unknown => Err(Error::Format("Unknown colour transform".to_string())), }, 4 => match color_transform { ColorTransform::None => Ok(color_no_convert), ColorTransform::Grayscale => Err(Error::Format( "Invalid number of channels (4) for Grayscale data".to_string(), )), ColorTransform::RGB => Err(Error::Format( "Invalid number of channels (4) for RGB data".to_string(), )), ColorTransform::YCbCr => Err(Error::Format( "Invalid number of channels (4) for YCbCr data".to_string(), )), ColorTransform::CMYK => Ok(color_convert_line_cmyk), ColorTransform::YCCK => Ok(color_convert_line_ycck), ColorTransform::JcsBgYcc => Err(Error::Unsupported( UnsupportedFeature::ColorTransform(ColorTransform::JcsBgYcc), )), ColorTransform::JcsBgRgb => Err(Error::Unsupported( UnsupportedFeature::ColorTransform(ColorTransform::JcsBgRgb), )), ColorTransform::Unknown => Err(Error::Format("Unknown colour transform".to_string())), }, _ => panic!(), } } fn color_convert_line_rgb(data: &[Vec], output: &mut [u8]) { assert!(data.len() == 3, "wrong number of components for rgb"); let [r, g, b]: &[Vec; 3] = data.try_into().unwrap(); for (((chunk, r), g), b) in output .chunks_exact_mut(3) .zip(r.iter()) .zip(g.iter()) .zip(b.iter()) { chunk[0] = *r; chunk[1] = *g; chunk[2] = *b; } } fn color_convert_line_ycbcr(data: &[Vec], output: &mut [u8]) { assert!(data.len() == 3, "wrong number of components for ycbcr"); let [y, cb, cr]: &[_; 3] = data.try_into().unwrap(); #[cfg(not(feature = "platform_independent"))] let arch_specific_pixels = { if let Some(ycbcr) = crate::arch::get_color_convert_line_ycbcr() { #[allow(unsafe_code)] unsafe { ycbcr(y, cb, cr, output) } } else { 0 } }; #[cfg(feature = "platform_independent")] let arch_specific_pixels = 0; for (((chunk, y), cb), cr) in output .chunks_exact_mut(3) .zip(y.iter()) .zip(cb.iter()) .zip(cr.iter()) .skip(arch_specific_pixels) { let (r, g, b) = ycbcr_to_rgb(*y, *cb, *cr); chunk[0] = r; chunk[1] = g; chunk[2] = b; } } fn color_convert_line_ycck(data: &[Vec], output: &mut [u8]) { assert!(data.len() == 4, "wrong number of components for ycck"); let [c, m, y, k]: &[Vec; 4] = data.try_into().unwrap(); for ((((chunk, c), m), y), k) in output .chunks_exact_mut(4) .zip(c.iter()) .zip(m.iter()) .zip(y.iter()) .zip(k.iter()) { let (r, g, b) = ycbcr_to_rgb(*c, *m, *y); chunk[0] = r; chunk[1] = g; chunk[2] = b; chunk[3] = 255 - *k; } } fn color_convert_line_cmyk(data: &[Vec], output: &mut [u8]) { assert!(data.len() == 4, "wrong number of components for cmyk"); let [c, m, y, k]: &[Vec; 4] = data.try_into().unwrap(); for ((((chunk, c), m), y), k) in output .chunks_exact_mut(4) .zip(c.iter()) .zip(m.iter()) .zip(y.iter()) .zip(k.iter()) { chunk[0] = 255 - c; chunk[1] = 255 - m; chunk[2] = 255 - y; chunk[3] = 255 - k; } } fn color_no_convert(data: &[Vec], output: &mut [u8]) { let mut output_iter = output.iter_mut(); for pixel in data { for d in pixel { *(output_iter.next().unwrap()) = *d; } } } const FIXED_POINT_OFFSET: i32 = 20; const HALF: i32 = (1 << FIXED_POINT_OFFSET) / 2; // ITU-R BT.601 // Based on libjpeg-turbo's jdcolext.c fn ycbcr_to_rgb(y: u8, cb: u8, cr: u8) -> (u8, u8, u8) { let y = y as i32 * (1 << FIXED_POINT_OFFSET) + HALF; let cb = cb as i32 - 128; let cr = cr as i32 - 128; let r = clamp_fixed_point(y + stbi_f2f(1.40200) * cr); let g = clamp_fixed_point(y - stbi_f2f(0.34414) * cb - stbi_f2f(0.71414) * cr); let b = clamp_fixed_point(y + stbi_f2f(1.77200) * cb); (r, g, b) } fn stbi_f2f(x: f32) -> i32 { (x * ((1 << FIXED_POINT_OFFSET) as f32) + 0.5) as i32 } fn clamp_fixed_point(value: i32) -> u8 { (value >> FIXED_POINT_OFFSET).min(255).max(0) as u8 } jpeg-decoder-0.3.0/src/error.rs000064400000000000000000000051170072674642500144760ustar 00000000000000use alloc::boxed::Box; use alloc::fmt; use alloc::string::String; use core::result; use std::error::Error as StdError; use std::io::Error as IoError; use crate::ColorTransform; pub type Result = result::Result; /// An enumeration over JPEG features (currently) unsupported by this library. /// /// Support for features listed here may be included in future versions of this library. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum UnsupportedFeature { /// Hierarchical JPEG. Hierarchical, /// JPEG using arithmetic entropy coding instead of Huffman coding. ArithmeticEntropyCoding, /// Sample precision in bits. 8 bit sample precision is what is currently supported in non-lossless coding process. SamplePrecision(u8), /// Number of components in an image. 1, 3 and 4 components are currently supported. ComponentCount(u8), /// An image can specify a zero height in the frame header and use the DNL (Define Number of /// Lines) marker at the end of the first scan to define the number of lines in the frame. DNL, /// Subsampling ratio. SubsamplingRatio, /// A subsampling ratio not representable as an integer. NonIntegerSubsamplingRatio, /// Colour transform ColorTransform(ColorTransform), } /// Errors that can occur while decoding a JPEG image. #[derive(Debug)] pub enum Error { /// The image is not formatted properly. The string contains detailed information about the /// error. Format(String), /// The image makes use of a JPEG feature not (currently) supported by this library. Unsupported(UnsupportedFeature), /// An I/O error occurred while decoding the image. Io(IoError), /// An internal error occurred while decoding the image. Internal(Box), //TODO: not used, can be removed with the next version bump } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { Error::Format(ref desc) => write!(f, "invalid JPEG format: {}", desc), Error::Unsupported(ref feat) => write!(f, "unsupported JPEG feature: {:?}", feat), Error::Io(ref err) => err.fmt(f), Error::Internal(ref err) => err.fmt(f), } } } impl StdError for Error { fn source(&self) -> Option<&(dyn StdError + 'static)> { match *self { Error::Io(ref err) => Some(err), Error::Internal(ref err) => Some(&**err), _ => None, } } } impl From for Error { fn from(err: IoError) -> Error { Error::Io(err) } } jpeg-decoder-0.3.0/src/huffman.rs000064400000000000000000000311270072674642500147710ustar 00000000000000use alloc::borrow::ToOwned; use alloc::vec; use alloc::vec::Vec; use core::iter; use std::io::Read; use crate::read_u8; use crate::error::{Error, Result}; use crate::marker::Marker; use crate::parser::ScanInfo; const LUT_BITS: u8 = 8; #[derive(Debug)] pub struct HuffmanDecoder { bits: u64, num_bits: u8, marker: Option, } impl HuffmanDecoder { pub fn new() -> HuffmanDecoder { HuffmanDecoder { bits: 0, num_bits: 0, marker: None, } } // Section F.2.2.3 // Figure F.16 pub fn decode(&mut self, reader: &mut R, table: &HuffmanTable) -> Result { if self.num_bits < 16 { self.read_bits(reader)?; } let (value, size) = table.lut[self.peek_bits(LUT_BITS) as usize]; if size > 0 { self.consume_bits(size); Ok(value) } else { let bits = self.peek_bits(16); for i in LUT_BITS .. 16 { let code = (bits >> (15 - i)) as i32; if code <= table.maxcode[i as usize] { self.consume_bits(i + 1); let index = (code + table.delta[i as usize]) as usize; return Ok(table.values[index]); } } Err(Error::Format("failed to decode huffman code".to_owned())) } } pub fn decode_fast_ac(&mut self, reader: &mut R, table: &HuffmanTable) -> Result> { if let Some(ref ac_lut) = table.ac_lut { if self.num_bits < LUT_BITS { self.read_bits(reader)?; } let (value, run_size) = ac_lut[self.peek_bits(LUT_BITS) as usize]; if run_size != 0 { let run = run_size >> 4; let size = run_size & 0x0f; self.consume_bits(size); return Ok(Some((value, run))); } } Ok(None) } #[inline] pub fn get_bits(&mut self, reader: &mut R, count: u8) -> Result { if self.num_bits < count { self.read_bits(reader)?; } let bits = self.peek_bits(count); self.consume_bits(count); Ok(bits) } #[inline] pub fn receive_extend(&mut self, reader: &mut R, count: u8) -> Result { let value = self.get_bits(reader, count)?; Ok(extend(value, count)) } pub fn reset(&mut self) { self.bits = 0; self.num_bits = 0; } pub fn take_marker(&mut self, reader: &mut R) -> Result> { self.read_bits(reader).map(|_| self.marker.take()) } #[inline] fn peek_bits(&mut self, count: u8) -> u16 { debug_assert!(count <= 16); debug_assert!(self.num_bits >= count); ((self.bits >> (64 - count)) & ((1 << count) - 1)) as u16 } #[inline] fn consume_bits(&mut self, count: u8) { debug_assert!(self.num_bits >= count); self.bits <<= count as usize; self.num_bits -= count; } fn read_bits(&mut self, reader: &mut R) -> Result<()> { while self.num_bits <= 56 { // Fill with zero bits if we have reached the end. let byte = match self.marker { Some(_) => 0, None => read_u8(reader)?, }; if byte == 0xFF { let mut next_byte = read_u8(reader)?; // Check for byte stuffing. if next_byte != 0x00 { // We seem to have reached the end of entropy-coded data and encountered a // marker. Since we can't put data back into the reader, we have to continue // reading to identify the marker so we can pass it on. // Section B.1.1.2 // "Any marker may optionally be preceded by any number of fill bytes, which are bytes assigned code X’FF’." while next_byte == 0xFF { next_byte = read_u8(reader)?; } match next_byte { 0x00 => return Err(Error::Format("FF 00 found where marker was expected".to_owned())), _ => self.marker = Some(Marker::from_u8(next_byte).unwrap()), } continue; } } self.bits |= (byte as u64) << (56 - self.num_bits); self.num_bits += 8; } Ok(()) } } // Section F.2.2.1 // Figure F.12 fn extend(value: u16, count: u8) -> i16 { let vt = 1 << (count as u16 - 1); if value < vt { value as i16 + (-1 << count as i16) + 1 } else { value as i16 } } #[derive(Clone, Copy, Debug, PartialEq)] pub enum HuffmanTableClass { DC, AC, } pub struct HuffmanTable { values: Vec, delta: [i32; 16], maxcode: [i32; 16], lut: [(u8, u8); 1 << LUT_BITS], ac_lut: Option<[(i16, u8); 1 << LUT_BITS]>, } impl HuffmanTable { pub fn new(bits: &[u8; 16], values: &[u8], class: HuffmanTableClass) -> Result { let (huffcode, huffsize) = derive_huffman_codes(bits)?; // Section F.2.2.3 // Figure F.15 // delta[i] is set to VALPTR(I) - MINCODE(I) let mut delta = [0i32; 16]; let mut maxcode = [-1i32; 16]; let mut j = 0; for i in 0 .. 16 { if bits[i] != 0 { delta[i] = j as i32 - huffcode[j] as i32; j += bits[i] as usize; maxcode[i] = huffcode[j - 1] as i32; } } // Build a lookup table for faster decoding. let mut lut = [(0u8, 0u8); 1 << LUT_BITS]; for (i, &size) in huffsize.iter().enumerate().filter(|&(_, &size)| size <= LUT_BITS) { let bits_remaining = LUT_BITS - size; let start = (huffcode[i] << bits_remaining) as usize; let val = (values[i], size); for b in &mut lut[start..][..1 << bits_remaining] { *b = val; } } // Build a lookup table for small AC coefficients which both decodes the value and does the // equivalent of receive_extend. let ac_lut = match class { HuffmanTableClass::DC => None, HuffmanTableClass::AC => { let mut table = [(0i16, 0u8); 1 << LUT_BITS]; for (i, &(value, size)) in lut.iter().enumerate() { let run_length = value >> 4; let magnitude_category = value & 0x0f; if magnitude_category > 0 && size + magnitude_category <= LUT_BITS { let unextended_ac_value = (((i << size) & ((1 << LUT_BITS) - 1)) >> (LUT_BITS - magnitude_category)) as u16; let ac_value = extend(unextended_ac_value, magnitude_category); table[i] = (ac_value, (run_length << 4) | (size + magnitude_category)); } } Some(table) }, }; Ok(HuffmanTable { values: values.to_vec(), delta, maxcode, lut, ac_lut, }) } } // Section C.2 fn derive_huffman_codes(bits: &[u8; 16]) -> Result<(Vec, Vec)> { // Figure C.1 let huffsize = bits.iter() .enumerate() .fold(Vec::new(), |mut acc, (i, &value)| { acc.extend(iter::repeat((i + 1) as u8).take(value as usize)); acc }); // Figure C.2 let mut huffcode = vec![0u16; huffsize.len()]; let mut code_size = huffsize[0]; let mut code = 0u32; for (i, &size) in huffsize.iter().enumerate() { while code_size < size { code <<= 1; code_size += 1; } if code >= (1u32 << size) { return Err(Error::Format("bad huffman code length".to_owned())); } huffcode[i] = code as u16; code += 1; } Ok((huffcode, huffsize)) } // https://www.loc.gov/preservation/digital/formats/fdd/fdd000063.shtml // "Avery Lee, writing in the rec.video.desktop newsgroup in 2001, commented that "MJPEG, or at // least the MJPEG in AVIs having the MJPG fourcc, is restricted JPEG with a fixed -- and // *omitted* -- Huffman table. The JPEG must be YCbCr colorspace, it must be 4:2:2, and it must // use basic Huffman encoding, not arithmetic or progressive.... You can indeed extract the // MJPEG frames and decode them with a regular JPEG decoder, but you have to prepend the DHT // segment to them, or else the decoder won't have any idea how to decompress the data. // The exact table necessary is given in the OpenDML spec."" pub fn fill_default_mjpeg_tables(scan: &ScanInfo, dc_huffman_tables: &mut[Option], ac_huffman_tables: &mut[Option]) { // Section K.3.3 if dc_huffman_tables[0].is_none() && scan.dc_table_indices.iter().any(|&i| i == 0) { // Table K.3 dc_huffman_tables[0] = Some(HuffmanTable::new( &[0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], &[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B], HuffmanTableClass::DC).unwrap()); } if dc_huffman_tables[1].is_none() && scan.dc_table_indices.iter().any(|&i| i == 1) { // Table K.4 dc_huffman_tables[1] = Some(HuffmanTable::new( &[0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00], &[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B], HuffmanTableClass::DC).unwrap()); } if ac_huffman_tables[0].is_none() && scan.ac_table_indices.iter().any(|&i| i == 0) { // Table K.5 ac_huffman_tables[0] = Some(HuffmanTable::new( &[0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D], &[0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA ], HuffmanTableClass::AC).unwrap()); } if ac_huffman_tables[1].is_none() && scan.ac_table_indices.iter().any(|&i| i == 1) { // Table K.6 ac_huffman_tables[1] = Some(HuffmanTable::new( &[0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77], &[0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA ], HuffmanTableClass::AC).unwrap()); } } jpeg-decoder-0.3.0/src/idct.rs000064400000000000000000000460460072674642500142760ustar 00000000000000// Malicious JPEG files can cause operations in the idct to overflow. // One example is tests/crashtest/images/imagetestsuite/b0b8914cc5f7a6eff409f16d8cc236c5.jpg // That's why wrapping operators are needed. // Note: we have many values that are straight from a reference. // Do not warn on them or try to automatically change them. #![allow(clippy::excessive_precision)] // Note: consistency for unrolled, scaled offset loops #![allow(clippy::erasing_op)] #![allow(clippy::identity_op)] use crate::parser::Dimensions; use core::{convert::TryFrom, num::Wrapping}; pub(crate) fn choose_idct_size(full_size: Dimensions, requested_size: Dimensions) -> usize { fn scaled(len: u16, scale: usize) -> u16 { ((len as u32 * scale as u32 - 1) / 8 + 1) as u16 } for &scale in &[1, 2, 4] { if scaled(full_size.width, scale) >= requested_size.width || scaled(full_size.height, scale) >= requested_size.height { return scale; } } 8 } #[test] fn test_choose_idct_size() { assert_eq!( choose_idct_size( Dimensions { width: 5472, height: 3648 }, Dimensions { width: 200, height: 200 } ), 1 ); assert_eq!( choose_idct_size( Dimensions { width: 5472, height: 3648 }, Dimensions { width: 500, height: 500 } ), 1 ); assert_eq!( choose_idct_size( Dimensions { width: 5472, height: 3648 }, Dimensions { width: 684, height: 456 } ), 1 ); assert_eq!( choose_idct_size( Dimensions { width: 5472, height: 3648 }, Dimensions { width: 999, height: 456 } ), 1 ); assert_eq!( choose_idct_size( Dimensions { width: 5472, height: 3648 }, Dimensions { width: 684, height: 999 } ), 1 ); assert_eq!( choose_idct_size( Dimensions { width: 500, height: 333 }, Dimensions { width: 63, height: 42 } ), 1 ); assert_eq!( choose_idct_size( Dimensions { width: 5472, height: 3648 }, Dimensions { width: 685, height: 999 } ), 2 ); assert_eq!( choose_idct_size( Dimensions { width: 5472, height: 3648 }, Dimensions { width: 1000, height: 1000 } ), 2 ); assert_eq!( choose_idct_size( Dimensions { width: 5472, height: 3648 }, Dimensions { width: 1400, height: 1400 } ), 4 ); assert_eq!( choose_idct_size( Dimensions { width: 5472, height: 3648 }, Dimensions { width: 5472, height: 3648 } ), 8 ); assert_eq!( choose_idct_size( Dimensions { width: 5472, height: 3648 }, Dimensions { width: 16384, height: 16384 } ), 8 ); assert_eq!( choose_idct_size( Dimensions { width: 1, height: 1 }, Dimensions { width: 65535, height: 65535 } ), 8 ); assert_eq!( choose_idct_size( Dimensions { width: 5472, height: 3648 }, Dimensions { width: 16384, height: 16384 } ), 8 ); } pub(crate) fn dequantize_and_idct_block( scale: usize, coefficients: &[i16; 64], quantization_table: &[u16; 64], output_linestride: usize, output: &mut [u8], ) { match scale { 8 => dequantize_and_idct_block_8x8( coefficients, quantization_table, output_linestride, output, ), 4 => dequantize_and_idct_block_4x4( coefficients, quantization_table, output_linestride, output, ), 2 => dequantize_and_idct_block_2x2( coefficients, quantization_table, output_linestride, output, ), 1 => dequantize_and_idct_block_1x1( coefficients, quantization_table, output_linestride, output, ), _ => panic!("Unsupported IDCT scale {}/8", scale), } } pub fn dequantize_and_idct_block_8x8( coefficients: &[i16; 64], quantization_table: &[u16; 64], output_linestride: usize, output: &mut [u8], ) { #[cfg(not(feature = "platform_independent"))] if let Some(idct) = crate::arch::get_dequantize_and_idct_block_8x8() { #[allow(unsafe_code)] unsafe { return idct(coefficients, quantization_table, output_linestride, output); } } let output = output.chunks_mut(output_linestride); dequantize_and_idct_block_8x8_inner(coefficients, quantization_table, output) } // This is based on stb_image's 'stbi__idct_block'. fn dequantize_and_idct_block_8x8_inner<'a, I>( coefficients: &[i16; 64], quantization_table: &[u16; 64], output: I, ) where I: IntoIterator, I::IntoIter: ExactSizeIterator, { let output = output.into_iter(); debug_assert!( output.len() >= 8, "Output iterator has the wrong length: {}", output.len() ); let mut temp = [Wrapping(0); 64]; // columns for i in 0..8 { if coefficients[i + 8] == 0 && coefficients[i + 16] == 0 && coefficients[i + 24] == 0 && coefficients[i + 32] == 0 && coefficients[i + 40] == 0 && coefficients[i + 48] == 0 && coefficients[i + 56] == 0 { let dcterm = dequantize(coefficients[i], quantization_table[i]) << 2; temp[i] = dcterm; temp[i + 8] = dcterm; temp[i + 16] = dcterm; temp[i + 24] = dcterm; temp[i + 32] = dcterm; temp[i + 40] = dcterm; temp[i + 48] = dcterm; temp[i + 56] = dcterm; } else { let s0 = dequantize(coefficients[i], quantization_table[i]); let s1 = dequantize(coefficients[i + 8], quantization_table[i + 8]); let s2 = dequantize(coefficients[i + 16], quantization_table[i + 16]); let s3 = dequantize(coefficients[i + 24], quantization_table[i + 24]); let s4 = dequantize(coefficients[i + 32], quantization_table[i + 32]); let s5 = dequantize(coefficients[i + 40], quantization_table[i + 40]); let s6 = dequantize(coefficients[i + 48], quantization_table[i + 48]); let s7 = dequantize(coefficients[i + 56], quantization_table[i + 56]); let Kernel { xs: [x0, x1, x2, x3], ts: [t0, t1, t2, t3], } = kernel( [s0, s1, s2, s3, s4, s5, s6, s7], // constants scaled things up by 1<<12; let's bring them back // down, but keep 2 extra bits of precision 512, ); temp[i] = (x0 + t3) >> 10; temp[i + 56] = (x0 - t3) >> 10; temp[i + 8] = (x1 + t2) >> 10; temp[i + 48] = (x1 - t2) >> 10; temp[i + 16] = (x2 + t1) >> 10; temp[i + 40] = (x2 - t1) >> 10; temp[i + 24] = (x3 + t0) >> 10; temp[i + 32] = (x3 - t0) >> 10; } } for (chunk, output_chunk) in temp.chunks_exact(8).zip(output) { let chunk = <&[_; 8]>::try_from(chunk).unwrap(); // constants scaled things up by 1<<12, plus we had 1<<2 from first // loop, plus horizontal and vertical each scale by sqrt(8) so together // we've got an extra 1<<3, so 1<<17 total we need to remove. // so we want to round that, which means adding 0.5 * 1<<17, // aka 65536. Also, we'll end up with -128 to 127 that we want // to encode as 0..255 by adding 128, so we'll add that before the shift const X_SCALE: i32 = 65536 + (128 << 17); // eliminate downstream bounds checks let output_chunk = &mut output_chunk[..8]; // TODO When the minimum rust version supports it // let [s0, rest @ ..] = chunk; let (s0, rest) = chunk.split_first().unwrap(); if *rest == [Wrapping(0); 7] { let dcterm = stbi_clamp((stbi_fsh(*s0) + Wrapping(X_SCALE)) >> 17); output_chunk[0] = dcterm; output_chunk[1] = dcterm; output_chunk[2] = dcterm; output_chunk[3] = dcterm; output_chunk[4] = dcterm; output_chunk[5] = dcterm; output_chunk[6] = dcterm; output_chunk[7] = dcterm; } else { let Kernel { xs: [x0, x1, x2, x3], ts: [t0, t1, t2, t3], } = kernel(*chunk, X_SCALE); output_chunk[0] = stbi_clamp((x0 + t3) >> 17); output_chunk[7] = stbi_clamp((x0 - t3) >> 17); output_chunk[1] = stbi_clamp((x1 + t2) >> 17); output_chunk[6] = stbi_clamp((x1 - t2) >> 17); output_chunk[2] = stbi_clamp((x2 + t1) >> 17); output_chunk[5] = stbi_clamp((x2 - t1) >> 17); output_chunk[3] = stbi_clamp((x3 + t0) >> 17); output_chunk[4] = stbi_clamp((x3 - t0) >> 17); } } } struct Kernel { xs: [Wrapping; 4], ts: [Wrapping; 4], } #[inline] fn kernel_x([s0, s2, s4, s6]: [Wrapping; 4], x_scale: i32) -> [Wrapping; 4] { // Even `chunk` indicies let (t2, t3); { let p2 = s2; let p3 = s6; let p1 = (p2 + p3) * stbi_f2f(0.5411961); t2 = p1 + p3 * stbi_f2f(-1.847759065); t3 = p1 + p2 * stbi_f2f(0.765366865); } let (t0, t1); { let p2 = s0; let p3 = s4; t0 = stbi_fsh(p2 + p3); t1 = stbi_fsh(p2 - p3); } let x0 = t0 + t3; let x3 = t0 - t3; let x1 = t1 + t2; let x2 = t1 - t2; let x_scale = Wrapping(x_scale); [x0 + x_scale, x1 + x_scale, x2 + x_scale, x3 + x_scale] } #[inline] fn kernel_t([s1, s3, s5, s7]: [Wrapping; 4]) -> [Wrapping; 4] { // Odd `chunk` indicies let mut t0 = s7; let mut t1 = s5; let mut t2 = s3; let mut t3 = s1; let p3 = t0 + t2; let p4 = t1 + t3; let p1 = t0 + t3; let p2 = t1 + t2; let p5 = (p3 + p4) * stbi_f2f(1.175875602); t0 *= stbi_f2f(0.298631336); t1 *= stbi_f2f(2.053119869); t2 *= stbi_f2f(3.072711026); t3 *= stbi_f2f(1.501321110); let p1 = p5 + p1 * stbi_f2f(-0.899976223); let p2 = p5 + p2 * stbi_f2f(-2.562915447); let p3 = p3 * stbi_f2f(-1.961570560); let p4 = p4 * stbi_f2f(-0.390180644); t3 += p1 + p4; t2 += p2 + p3; t1 += p2 + p4; t0 += p1 + p3; [t0, t1, t2, t3] } #[inline] fn kernel([s0, s1, s2, s3, s4, s5, s6, s7]: [Wrapping; 8], x_scale: i32) -> Kernel { Kernel { xs: kernel_x([s0, s2, s4, s6], x_scale), ts: kernel_t([s1, s3, s5, s7]), } } #[inline(always)] fn dequantize(c: i16, q: u16) -> Wrapping { Wrapping(i32::from(c) * i32::from(q)) } // 4x4 and 2x2 IDCT based on Rakesh Dugad and Narendra Ahuja: "A Fast Scheme for Image Size Change in the Compressed Domain" (2001). // http://sylvana.net/jpegcrop/jidctred/ fn dequantize_and_idct_block_4x4( coefficients: &[i16; 64], quantization_table: &[u16; 64], output_linestride: usize, output: &mut [u8], ) { debug_assert_eq!(coefficients.len(), 64); let mut temp = [Wrapping(0i32); 4 * 4]; const CONST_BITS: usize = 12; const PASS1_BITS: usize = 2; const FINAL_BITS: usize = CONST_BITS + PASS1_BITS + 3; // columns for i in 0..4 { let s0 = Wrapping(coefficients[i + 8 * 0] as i32 * quantization_table[i + 8 * 0] as i32); let s1 = Wrapping(coefficients[i + 8 * 1] as i32 * quantization_table[i + 8 * 1] as i32); let s2 = Wrapping(coefficients[i + 8 * 2] as i32 * quantization_table[i + 8 * 2] as i32); let s3 = Wrapping(coefficients[i + 8 * 3] as i32 * quantization_table[i + 8 * 3] as i32); let x0 = (s0 + s2) << PASS1_BITS; let x2 = (s0 - s2) << PASS1_BITS; let p1 = (s1 + s3) * stbi_f2f(0.541196100); let t0 = (p1 + s3 * stbi_f2f(-1.847759065) + Wrapping(512)) >> (CONST_BITS - PASS1_BITS); let t2 = (p1 + s1 * stbi_f2f(0.765366865) + Wrapping(512)) >> (CONST_BITS - PASS1_BITS); temp[i + 4 * 0] = x0 + t2; temp[i + 4 * 3] = x0 - t2; temp[i + 4 * 1] = x2 + t0; temp[i + 4 * 2] = x2 - t0; } for i in 0..4 { let s0 = temp[i * 4 + 0]; let s1 = temp[i * 4 + 1]; let s2 = temp[i * 4 + 2]; let s3 = temp[i * 4 + 3]; let x0 = (s0 + s2) << CONST_BITS; let x2 = (s0 - s2) << CONST_BITS; let p1 = (s1 + s3) * stbi_f2f(0.541196100); let t0 = p1 + s3 * stbi_f2f(-1.847759065); let t2 = p1 + s1 * stbi_f2f(0.765366865); // constants scaled things up by 1<<12, plus we had 1<<2 from first // loop, plus horizontal and vertical each scale by sqrt(8) so together // we've got an extra 1<<3, so 1<<17 total we need to remove. // so we want to round that, which means adding 0.5 * 1<<17, // aka 65536. Also, we'll end up with -128 to 127 that we want // to encode as 0..255 by adding 128, so we'll add that before the shift let x0 = x0 + Wrapping(1 << (FINAL_BITS - 1)) + Wrapping(128 << FINAL_BITS); let x2 = x2 + Wrapping(1 << (FINAL_BITS - 1)) + Wrapping(128 << FINAL_BITS); let output = &mut output[i * output_linestride..][..4]; output[0] = stbi_clamp((x0 + t2) >> FINAL_BITS); output[3] = stbi_clamp((x0 - t2) >> FINAL_BITS); output[1] = stbi_clamp((x2 + t0) >> FINAL_BITS); output[2] = stbi_clamp((x2 - t0) >> FINAL_BITS); } } fn dequantize_and_idct_block_2x2( coefficients: &[i16; 64], quantization_table: &[u16; 64], output_linestride: usize, output: &mut [u8], ) { debug_assert_eq!(coefficients.len(), 64); const SCALE_BITS: usize = 3; // Column 0 let s00 = Wrapping(coefficients[8 * 0] as i32 * quantization_table[8 * 0] as i32); let s10 = Wrapping(coefficients[8 * 1] as i32 * quantization_table[8 * 1] as i32); let x0 = s00 + s10; let x2 = s00 - s10; // Column 1 let s01 = Wrapping(coefficients[8 * 0 + 1] as i32 * quantization_table[8 * 0 + 1] as i32); let s11 = Wrapping(coefficients[8 * 1 + 1] as i32 * quantization_table[8 * 1 + 1] as i32); let x1 = s01 + s11; let x3 = s01 - s11; let x0 = x0 + Wrapping(1 << (SCALE_BITS - 1)) + Wrapping(128 << SCALE_BITS); let x2 = x2 + Wrapping(1 << (SCALE_BITS - 1)) + Wrapping(128 << SCALE_BITS); // Row 0 output[0] = stbi_clamp((x0 + x1) >> SCALE_BITS); output[1] = stbi_clamp((x0 - x1) >> SCALE_BITS); // Row 1 output[output_linestride + 0] = stbi_clamp((x2 + x3) >> SCALE_BITS); output[output_linestride + 1] = stbi_clamp((x2 - x3) >> SCALE_BITS); } fn dequantize_and_idct_block_1x1( coefficients: &[i16; 64], quantization_table: &[u16; 64], _output_linestride: usize, output: &mut [u8], ) { debug_assert_eq!(coefficients.len(), 64); let s0 = (Wrapping(coefficients[0] as i32 * quantization_table[0] as i32) + Wrapping(128 * 8)) / Wrapping(8); output[0] = stbi_clamp(s0); } // take a -128..127 value and stbi__clamp it and convert to 0..255 fn stbi_clamp(x: Wrapping) -> u8 { x.0.max(0).min(255) as u8 } fn stbi_f2f(x: f32) -> Wrapping { Wrapping((x * 4096.0 + 0.5) as i32) } fn stbi_fsh(x: Wrapping) -> Wrapping { x << 12 } #[test] fn test_dequantize_and_idct_block_8x8() { #[cfg_attr(rustfmt, rustfmt_skip)] let coefficients: [i16; 8 * 8] = [ -14, -39, 58, -2, 3, 3, 0, 1, 11, 27, 4, -3, 3, 0, 1, 0, -6, -13, -9, -1, -2, -1, 0, 0, -4, 0, -1, -2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, -3, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; #[cfg_attr(rustfmt, rustfmt_skip)] let quantization_table: [u16; 8 * 8] = [ 8, 6, 5, 8, 12, 20, 26, 31, 6, 6, 7, 10, 13, 29, 30, 28, 7, 7, 8, 12, 20, 29, 35, 28, 7, 9, 11, 15, 26, 44, 40, 31, 9, 11, 19, 28, 34, 55, 52, 39, 12, 18, 28, 32, 41, 52, 57, 46, 25, 32, 39, 44, 52, 61, 60, 51, 36, 46, 48, 49, 56, 50, 52, 50 ]; let output_linestride: usize = 8; let mut output = [0u8; 8 * 8]; dequantize_and_idct_block_8x8( &coefficients, &quantization_table, output_linestride, &mut output, ); #[cfg_attr(rustfmt, rustfmt_skip)] let expected_output = [ 118, 92, 110, 83, 77, 93, 144, 198, 172, 116, 114, 87, 78, 93, 146, 191, 194, 107, 91, 76, 71, 93, 160, 198, 196, 100, 80, 74, 67, 92, 174, 209, 182, 104, 88, 81, 68, 89, 178, 206, 105, 64, 59, 59, 63, 94, 183, 201, 35, 27, 28, 37, 72, 121, 203, 204, 37, 45, 41, 47, 98, 154, 223, 208 ]; for i in 0..64 { assert!((output[i] as i16 - expected_output[i] as i16).abs() <= 1); } } #[test] fn test_dequantize_and_idct_block_8x8_all_zero() { let mut output = [0u8; 8 * 8]; dequantize_and_idct_block_8x8(&[0; 8 * 8], &[666; 8 * 8], 8, &mut output); assert_eq!(&output[..], &[128; 8 * 8][..]); } #[test] fn test_dequantize_and_idct_block_8x8_saturated() { // Arch-specific IDCT implementations need not handle i16::MAX values. #[cfg(not(feature = "platform_independent"))] if crate::arch::get_dequantize_and_idct_block_8x8().is_some() { return; } let mut output = [0u8; 8 * 8]; dequantize_and_idct_block_8x8(&[i16::MAX; 8 * 8], &[u16::MAX; 8 * 8], 8, &mut output); #[cfg_attr(rustfmt, rustfmt_skip)] let expected = [ 0, 0, 0, 255, 255, 0, 0, 255, 0, 0, 215, 0, 0, 255, 255, 0, 255, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 0, 255, 0, 255, 255, 0, 0, 255, 255, 0, 255, 0, 0, 255, 255, 0, 255, 255, 255, 170, 0, 0, 255, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 0, 255, 0, 0 ]; assert_eq!(&output[..], &expected[..]); } jpeg-decoder-0.3.0/src/lib.rs000064400000000000000000000032100072674642500141030ustar 00000000000000//! This crate contains a JPEG decoder. //! //! # Examples //! //! ``` //! use jpeg_decoder::Decoder; //! use std::fs::File; //! use std::io::BufReader; //! //! let file = File::open("tests/reftest/images/extraneous-data.jpg").expect("failed to open file"); //! let mut decoder = Decoder::new(BufReader::new(file)); //! let pixels = decoder.decode().expect("failed to decode image"); //! let metadata = decoder.info().unwrap(); //! ``` //! //! Get metadata from a file without decoding it: //! //! ``` //! use jpeg_decoder::Decoder; //! use std::fs::File; //! use std::io::BufReader; //! //! let file = File::open("tests/reftest/images/extraneous-data.jpg").expect("failed to open file"); //! let mut decoder = Decoder::new(BufReader::new(file)); //! decoder.read_info().expect("failed to read metadata"); //! let metadata = decoder.info().unwrap(); //! ``` #![deny(missing_docs)] #![deny(unsafe_code)] #![cfg_attr(feature = "platform_independent", forbid(unsafe_code))] extern crate alloc; extern crate core; #[cfg(feature = "rayon")] extern crate rayon; pub use decoder::{ColorTransform, Decoder, ImageInfo, PixelFormat}; pub use error::{Error, UnsupportedFeature}; pub use parser::CodingProcess; use std::io; #[cfg(not(feature = "platform_independent"))] mod arch; mod decoder; mod error; mod huffman; mod idct; mod marker; mod parser; mod upsampler; mod worker; fn read_u8(reader: &mut R) -> io::Result { let mut buf = [0]; reader.read_exact(&mut buf)?; Ok(buf[0]) } fn read_u16_from_be(reader: &mut R) -> io::Result { let mut buf = [0, 0]; reader.read_exact(&mut buf)?; Ok(u16::from_be_bytes(buf)) } jpeg-decoder-0.3.0/src/marker.rs000064400000000000000000000102620072674642500146230ustar 00000000000000// Table B.1 #[derive(Clone, Copy, Debug, PartialEq)] // Note: Established names. #[allow(clippy::upper_case_acronyms)] pub enum Marker { /// Start Of Frame markers /// /// - SOF(0): Baseline DCT (Huffman coding) /// - SOF(1): Extended sequential DCT (Huffman coding) /// - SOF(2): Progressive DCT (Huffman coding) /// - SOF(3): Lossless (sequential) (Huffman coding) /// - SOF(5): Differential sequential DCT (Huffman coding) /// - SOF(6): Differential progressive DCT (Huffman coding) /// - SOF(7): Differential lossless (sequential) (Huffman coding) /// - SOF(9): Extended sequential DCT (arithmetic coding) /// - SOF(10): Progressive DCT (arithmetic coding) /// - SOF(11): Lossless (sequential) (arithmetic coding) /// - SOF(13): Differential sequential DCT (arithmetic coding) /// - SOF(14): Differential progressive DCT (arithmetic coding) /// - SOF(15): Differential lossless (sequential) (arithmetic coding) SOF(u8), /// Reserved for JPEG extensions JPG, /// Define Huffman table(s) DHT, /// Define arithmetic coding conditioning(s) DAC, /// Restart with modulo 8 count `m` RST(u8), /// Start of image SOI, /// End of image EOI, /// Start of scan SOS, /// Define quantization table(s) DQT, /// Define number of lines DNL, /// Define restart interval DRI, /// Define hierarchical progression DHP, /// Expand reference component(s) EXP, /// Reserved for application segments APP(u8), /// Reserved for JPEG extensions JPGn(u8), /// Comment COM, /// For temporary private use in arithmetic coding TEM, /// Reserved RES, } impl Marker { pub fn has_length(self) -> bool { use self::Marker::*; ! matches!(self, RST(..) | SOI | EOI | TEM) } pub fn from_u8(n: u8) -> Option { use self::Marker::*; match n { 0x00 => None, // Byte stuffing 0x01 => Some(TEM), 0x02 ..= 0xBF => Some(RES), 0xC0 => Some(SOF(0)), 0xC1 => Some(SOF(1)), 0xC2 => Some(SOF(2)), 0xC3 => Some(SOF(3)), 0xC4 => Some(DHT), 0xC5 => Some(SOF(5)), 0xC6 => Some(SOF(6)), 0xC7 => Some(SOF(7)), 0xC8 => Some(JPG), 0xC9 => Some(SOF(9)), 0xCA => Some(SOF(10)), 0xCB => Some(SOF(11)), 0xCC => Some(DAC), 0xCD => Some(SOF(13)), 0xCE => Some(SOF(14)), 0xCF => Some(SOF(15)), 0xD0 => Some(RST(0)), 0xD1 => Some(RST(1)), 0xD2 => Some(RST(2)), 0xD3 => Some(RST(3)), 0xD4 => Some(RST(4)), 0xD5 => Some(RST(5)), 0xD6 => Some(RST(6)), 0xD7 => Some(RST(7)), 0xD8 => Some(SOI), 0xD9 => Some(EOI), 0xDA => Some(SOS), 0xDB => Some(DQT), 0xDC => Some(DNL), 0xDD => Some(DRI), 0xDE => Some(DHP), 0xDF => Some(EXP), 0xE0 => Some(APP(0)), 0xE1 => Some(APP(1)), 0xE2 => Some(APP(2)), 0xE3 => Some(APP(3)), 0xE4 => Some(APP(4)), 0xE5 => Some(APP(5)), 0xE6 => Some(APP(6)), 0xE7 => Some(APP(7)), 0xE8 => Some(APP(8)), 0xE9 => Some(APP(9)), 0xEA => Some(APP(10)), 0xEB => Some(APP(11)), 0xEC => Some(APP(12)), 0xED => Some(APP(13)), 0xEE => Some(APP(14)), 0xEF => Some(APP(15)), 0xF0 => Some(JPGn(0)), 0xF1 => Some(JPGn(1)), 0xF2 => Some(JPGn(2)), 0xF3 => Some(JPGn(3)), 0xF4 => Some(JPGn(4)), 0xF5 => Some(JPGn(5)), 0xF6 => Some(JPGn(6)), 0xF7 => Some(JPGn(7)), 0xF8 => Some(JPGn(8)), 0xF9 => Some(JPGn(9)), 0xFA => Some(JPGn(10)), 0xFB => Some(JPGn(11)), 0xFC => Some(JPGn(12)), 0xFD => Some(JPGn(13)), 0xFE => Some(COM), 0xFF => None, // Fill byte } } } jpeg-decoder-0.3.0/src/parser.rs000064400000000000000000000577570072674642500146620ustar 00000000000000use alloc::borrow::ToOwned; use alloc::{format, vec}; use alloc::vec::Vec; use core::ops::{self, Range}; use std::io::{self, Read}; use crate::{read_u16_from_be, read_u8}; use crate::error::{Error, Result, UnsupportedFeature}; use crate::huffman::{HuffmanTable, HuffmanTableClass}; use crate::marker::Marker; use crate::marker::Marker::*; #[derive(Clone, Copy, Debug, PartialEq)] pub struct Dimensions { pub width: u16, pub height: u16, } #[derive(Clone, Copy, Debug, PartialEq)] pub enum EntropyCoding { Huffman, Arithmetic, } /// Represents the coding process of an image. #[derive(Clone, Copy, Debug, PartialEq)] pub enum CodingProcess { /// Sequential Discrete Cosine Transform DctSequential, /// Progressive Discrete Cosine Transform DctProgressive, /// Lossless Lossless, } // Table H.1 #[derive(Clone, Copy, Debug, PartialEq)] pub enum Predictor { NoPrediction, Ra, Rb, Rc, RaRbRc1, // Ra + Rb - Rc RaRbRc2, // Ra + ((Rb - Rc) >> 1) RaRbRc3, // Rb + ((Ra - Rb) >> 1) RaRb, // (Ra + Rb)/2 } #[derive(Clone)] pub struct FrameInfo { pub is_baseline: bool, pub is_differential: bool, pub coding_process: CodingProcess, pub entropy_coding: EntropyCoding, pub precision: u8, pub image_size: Dimensions, pub output_size: Dimensions, pub mcu_size: Dimensions, pub components: Vec, } #[derive(Debug)] pub struct ScanInfo { pub component_indices: Vec, pub dc_table_indices: Vec, pub ac_table_indices: Vec, pub spectral_selection: Range, pub predictor_selection: Predictor, // for lossless pub successive_approximation_high: u8, pub successive_approximation_low: u8, pub point_transform: u8, // for lossless } #[derive(Clone, Debug)] pub struct Component { pub identifier: u8, pub horizontal_sampling_factor: u8, pub vertical_sampling_factor: u8, pub quantization_table_index: usize, pub dct_scale: usize, pub size: Dimensions, pub block_size: Dimensions, } #[derive(Debug)] pub enum AppData { Adobe(AdobeColorTransform), Jfif, Avi1, Icc(IccChunk), Exif(Vec), } // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/JPEG.html#Adobe #[derive(Clone, Copy, Debug, PartialEq)] pub enum AdobeColorTransform { // RGB or CMYK Unknown, YCbCr, // YCbCrK YCCK, } #[derive(Debug)] pub struct IccChunk { pub num_markers: u8, pub seq_no: u8, pub data: Vec, } impl FrameInfo { pub(crate) fn update_idct_size(&mut self, idct_size: usize) -> Result<()> { for component in &mut self.components { component.dct_scale = idct_size; } update_component_sizes(self.image_size, &mut self.components)?; self.output_size = Dimensions { width: (self.image_size.width as f32 * idct_size as f32 / 8.0).ceil() as u16, height: (self.image_size.height as f32 * idct_size as f32 / 8.0).ceil() as u16 }; Ok(()) } } fn read_length(reader: &mut R, marker: Marker) -> Result { assert!(marker.has_length()); // length is including itself. let length = usize::from(read_u16_from_be(reader)?); if length < 2 { return Err(Error::Format(format!("encountered {:?} with invalid length {}", marker, length))); } Ok(length - 2) } fn skip_bytes(reader: &mut R, length: usize) -> Result<()> { let length = length as u64; let to_skip = &mut reader.by_ref().take(length); let copied = io::copy(to_skip, &mut io::sink())?; if copied < length { Err(Error::Io(io::ErrorKind::UnexpectedEof.into())) } else { Ok(()) } } // Section B.2.2 pub fn parse_sof(reader: &mut R, marker: Marker) -> Result { let length = read_length(reader, marker)?; if length <= 6 { return Err(Error::Format("invalid length in SOF".to_owned())); } let is_baseline = marker == SOF(0); let is_differential = match marker { SOF(0 ..= 3) | SOF(9 ..= 11) => false, SOF(5 ..= 7) | SOF(13 ..= 15) => true, _ => panic!(), }; let coding_process = match marker { SOF(0) | SOF(1) | SOF(5) | SOF(9) | SOF(13) => CodingProcess::DctSequential, SOF(2) | SOF(6) | SOF(10) | SOF(14) => CodingProcess::DctProgressive, SOF(3) | SOF(7) | SOF(11) | SOF(15) => CodingProcess::Lossless, _ => panic!(), }; let entropy_coding = match marker { SOF(0 ..= 3) | SOF(5 ..= 7) => EntropyCoding::Huffman, SOF(9 ..= 11) | SOF(13 ..= 15) => EntropyCoding::Arithmetic, _ => panic!(), }; let precision = read_u8(reader)?; match precision { 8 => {}, 12 => { if is_baseline { return Err(Error::Format("12 bit sample precision is not allowed in baseline".to_owned())); } }, _ => { if coding_process != CodingProcess::Lossless || precision > 16 { return Err(Error::Format(format!("invalid precision {} in frame header", precision))) } }, } let height = read_u16_from_be(reader)?; let width = read_u16_from_be(reader)?; // height: // "Value 0 indicates that the number of lines shall be defined by the DNL marker and // parameters at the end of the first scan (see B.2.5)." if height == 0 { return Err(Error::Unsupported(UnsupportedFeature::DNL)); } if width == 0 { return Err(Error::Format("zero width in frame header".to_owned())); } let component_count = read_u8(reader)?; if component_count == 0 { return Err(Error::Format("zero component count in frame header".to_owned())); } if coding_process == CodingProcess::DctProgressive && component_count > 4 { return Err(Error::Format("progressive frame with more than 4 components".to_owned())); } if length != 6 + 3 * component_count as usize { return Err(Error::Format("invalid length in SOF".to_owned())); } let mut components: Vec = Vec::with_capacity(component_count as usize); for _ in 0 .. component_count { let identifier = read_u8(reader)?; // Each component's identifier must be unique. if components.iter().any(|c| c.identifier == identifier) { return Err(Error::Format(format!("duplicate frame component identifier {}", identifier))); } let byte = read_u8(reader)?; let horizontal_sampling_factor = byte >> 4; let vertical_sampling_factor = byte & 0x0f; if horizontal_sampling_factor == 0 || horizontal_sampling_factor > 4 { return Err(Error::Format(format!("invalid horizontal sampling factor {}", horizontal_sampling_factor))); } if vertical_sampling_factor == 0 || vertical_sampling_factor > 4 { return Err(Error::Format(format!("invalid vertical sampling factor {}", vertical_sampling_factor))); } let quantization_table_index = read_u8(reader)?; if quantization_table_index > 3 || (coding_process == CodingProcess::Lossless && quantization_table_index != 0) { return Err(Error::Format(format!("invalid quantization table index {}", quantization_table_index))); } components.push(Component { identifier, horizontal_sampling_factor, vertical_sampling_factor, quantization_table_index: quantization_table_index as usize, dct_scale: 8, size: Dimensions {width: 0, height: 0}, block_size: Dimensions {width: 0, height: 0}, }); } let mcu_size = update_component_sizes(Dimensions { width, height }, &mut components)?; Ok(FrameInfo { is_baseline, is_differential, coding_process, entropy_coding, precision, image_size: Dimensions { width, height }, output_size: Dimensions { width, height }, mcu_size, components, }) } /// Returns ceil(x/y), requires x>0 fn ceil_div(x: u32, y: u32) -> Result { if x == 0 || y == 0 { // TODO Determine how this error is reached. Can we validate input // earlier and error out then? return Err(Error::Format("invalid dimensions".to_owned())); } Ok((1 + ((x - 1) / y)) as u16) } fn update_component_sizes(size: Dimensions, components: &mut [Component]) -> Result { let h_max = components.iter().map(|c| c.horizontal_sampling_factor).max().unwrap() as u32; let v_max = components.iter().map(|c| c.vertical_sampling_factor).max().unwrap() as u32; let mcu_size = Dimensions { width: ceil_div(size.width as u32, h_max * 8)?, height: ceil_div(size.height as u32, v_max * 8)?, }; for component in components { component.size.width = ceil_div(size.width as u32 * component.horizontal_sampling_factor as u32 * component.dct_scale as u32, h_max * 8)?; component.size.height = ceil_div(size.height as u32 * component.vertical_sampling_factor as u32 * component.dct_scale as u32, v_max * 8)?; component.block_size.width = mcu_size.width * component.horizontal_sampling_factor as u16; component.block_size.height = mcu_size.height * component.vertical_sampling_factor as u16; } Ok(mcu_size) } #[test] fn test_update_component_sizes() { let mut components = [Component { identifier: 1, horizontal_sampling_factor: 2, vertical_sampling_factor: 2, quantization_table_index: 0, dct_scale: 8, size: Dimensions { width: 0, height: 0 }, block_size: Dimensions { width: 0, height: 0 }, }]; let mcu = update_component_sizes( Dimensions { width: 800, height: 280 }, &mut components).unwrap(); assert_eq!(mcu, Dimensions { width: 50, height: 18 }); assert_eq!(components[0].block_size, Dimensions { width: 100, height: 36 }); assert_eq!(components[0].size, Dimensions { width: 800, height: 280 }); } // Section B.2.3 pub fn parse_sos(reader: &mut R, frame: &FrameInfo) -> Result { let length = read_length(reader, SOS)?; if 0 == length { return Err(Error::Format("zero length in SOS".to_owned())); } let component_count = read_u8(reader)?; if component_count == 0 || component_count > 4 { return Err(Error::Format(format!("invalid component count {} in scan header", component_count))); } if length != 4 + 2 * component_count as usize { return Err(Error::Format("invalid length in SOS".to_owned())); } let mut component_indices = Vec::with_capacity(component_count as usize); let mut dc_table_indices = Vec::with_capacity(component_count as usize); let mut ac_table_indices = Vec::with_capacity(component_count as usize); for _ in 0 .. component_count { let identifier = read_u8(reader)?; let component_index = match frame.components.iter().position(|c| c.identifier == identifier) { Some(value) => value, None => return Err(Error::Format(format!("scan component identifier {} does not match any of the component identifiers defined in the frame", identifier))), }; // Each of the scan's components must be unique. if component_indices.contains(&component_index) { return Err(Error::Format(format!("duplicate scan component identifier {}", identifier))); } // "... the ordering in the scan header shall follow the ordering in the frame header." if component_index < *component_indices.iter().max().unwrap_or(&0) { return Err(Error::Format("the scan component order does not follow the order in the frame header".to_owned())); } let byte = read_u8(reader)?; let dc_table_index = byte >> 4; let ac_table_index = byte & 0x0f; if dc_table_index > 3 || (frame.is_baseline && dc_table_index > 1) { return Err(Error::Format(format!("invalid dc table index {}", dc_table_index))); } if ac_table_index > 3 || (frame.is_baseline && ac_table_index > 1) { return Err(Error::Format(format!("invalid ac table index {}", ac_table_index))); } component_indices.push(component_index); dc_table_indices.push(dc_table_index as usize); ac_table_indices.push(ac_table_index as usize); } let blocks_per_mcu = component_indices.iter().map(|&i| { frame.components[i].horizontal_sampling_factor as u32 * frame.components[i].vertical_sampling_factor as u32 }).fold(0, ops::Add::add); if component_count > 1 && blocks_per_mcu > 10 { return Err(Error::Format("scan with more than one component and more than 10 blocks per MCU".to_owned())); } // Also utilized as 'Predictor' in lossless coding, as MEAN in JPEG-LS etc. let spectral_selection_start = read_u8(reader)?; // Also utilized as ILV parameter in JPEG-LS. let mut spectral_selection_end = read_u8(reader)?; let byte = read_u8(reader)?; let successive_approximation_high = byte >> 4; let successive_approximation_low = byte & 0x0f; // The Differential Pulse-Mode prediction used (similar to png). Only utilized in Lossless // coding. Don't confuse with the JPEG-LS parameter coded using the same scan info portion. let predictor_selection; let point_transform = successive_approximation_low; if frame.coding_process == CodingProcess::DctProgressive { predictor_selection = Predictor::NoPrediction; if spectral_selection_end > 63 || spectral_selection_start > spectral_selection_end || (spectral_selection_start == 0 && spectral_selection_end != 0) { return Err(Error::Format(format!("invalid spectral selection parameters: ss={}, se={}", spectral_selection_start, spectral_selection_end))); } if spectral_selection_start != 0 && component_count != 1 { return Err(Error::Format("spectral selection scan with AC coefficients can't have more than one component".to_owned())); } if successive_approximation_high > 13 || successive_approximation_low > 13 { return Err(Error::Format(format!("invalid successive approximation parameters: ah={}, al={}", successive_approximation_high, successive_approximation_low))); } // Section G.1.1.1.2 // "Each scan which follows the first scan for a given band progressively improves // the precision of the coefficients by one bit, until full precision is reached." if successive_approximation_high != 0 && successive_approximation_high != successive_approximation_low + 1 { return Err(Error::Format("successive approximation scan with more than one bit of improvement".to_owned())); } } else if frame.coding_process == CodingProcess::Lossless { if spectral_selection_end != 0 { return Err(Error::Format("spectral selection end shall be zero in lossless scan".to_owned())); } if successive_approximation_high != 0 { return Err(Error::Format("successive approximation high shall be zero in lossless scan".to_owned())); } predictor_selection = match spectral_selection_start { 0 => Predictor::NoPrediction, 1 => Predictor::Ra, 2 => Predictor::Rb, 3 => Predictor::Rc, 4 => Predictor::RaRbRc1, 5 => Predictor::RaRbRc2, 6 => Predictor::RaRbRc3, 7 => Predictor::RaRb, _ => { return Err(Error::Format(format!("invalid predictor selection value: {}", spectral_selection_start))); }, }; } else { predictor_selection = Predictor::NoPrediction; if spectral_selection_end == 0 { spectral_selection_end = 63; } if spectral_selection_start != 0 || spectral_selection_end != 63 { return Err(Error::Format("spectral selection is not allowed in non-progressive scan".to_owned())); } if successive_approximation_high != 0 || successive_approximation_low != 0 { return Err(Error::Format("successive approximation is not allowed in non-progressive scan".to_owned())); } } Ok(ScanInfo { component_indices, dc_table_indices, ac_table_indices, spectral_selection: Range { start: spectral_selection_start, end: spectral_selection_end + 1, }, predictor_selection, successive_approximation_high, successive_approximation_low, point_transform, }) } // Section B.2.4.1 pub fn parse_dqt(reader: &mut R) -> Result<[Option<[u16; 64]>; 4]> { let mut length = read_length(reader, DQT)?; let mut tables = [None; 4]; // Each DQT segment may contain multiple quantization tables. while length > 0 { let byte = read_u8(reader)?; let precision = (byte >> 4) as usize; let index = (byte & 0x0f) as usize; // The combination of 8-bit sample precision and 16-bit quantization tables is explicitly // disallowed by the JPEG spec: // "An 8-bit DCT-based process shall not use a 16-bit precision quantization table." // "Pq: Quantization table element precision – Specifies the precision of the Qk // values. Value 0 indicates 8-bit Qk values; value 1 indicates 16-bit Qk values. Pq // shall be zero for 8 bit sample precision P (see B.2.2)." // libjpeg allows this behavior though, and there are images in the wild using it. So to // match libjpeg's behavior we are deviating from the JPEG spec here. if precision > 1 { return Err(Error::Format(format!("invalid precision {} in DQT", precision))); } if index > 3 { return Err(Error::Format(format!("invalid destination identifier {} in DQT", index))); } if length < 65 + 64 * precision { return Err(Error::Format("invalid length in DQT".to_owned())); } let mut table = [0u16; 64]; for item in table.iter_mut() { *item = match precision { 0 => u16::from(read_u8(reader)?), 1 => read_u16_from_be(reader)?, _ => unreachable!(), }; } if table.iter().any(|&val| val == 0) { return Err(Error::Format("quantization table contains element with a zero value".to_owned())); } tables[index] = Some(table); length -= 65 + 64 * precision; } Ok(tables) } // Section B.2.4.2 pub fn parse_dht(reader: &mut R, is_baseline: Option) -> Result<(Vec>, Vec>)> { let mut length = read_length(reader, DHT)?; let mut dc_tables = vec![None, None, None, None]; let mut ac_tables = vec![None, None, None, None]; // Each DHT segment may contain multiple huffman tables. while length > 17 { let byte = read_u8(reader)?; let class = byte >> 4; let index = (byte & 0x0f) as usize; if class != 0 && class != 1 { return Err(Error::Format(format!("invalid class {} in DHT", class))); } if is_baseline == Some(true) && index > 1 { return Err(Error::Format("a maximum of two huffman tables per class are allowed in baseline".to_owned())); } if index > 3 { return Err(Error::Format(format!("invalid destination identifier {} in DHT", index))); } let mut counts = [0u8; 16]; reader.read_exact(&mut counts)?; let size = counts.iter().map(|&val| val as usize).fold(0, ops::Add::add); if size == 0 { return Err(Error::Format("encountered table with zero length in DHT".to_owned())); } else if size > 256 { return Err(Error::Format("encountered table with excessive length in DHT".to_owned())); } else if size > length - 17 { return Err(Error::Format("invalid length in DHT".to_owned())); } let mut values = vec![0u8; size]; reader.read_exact(&mut values)?; match class { 0 => dc_tables[index] = Some(HuffmanTable::new(&counts, &values, HuffmanTableClass::DC)?), 1 => ac_tables[index] = Some(HuffmanTable::new(&counts, &values, HuffmanTableClass::AC)?), _ => unreachable!(), } length -= 17 + size; } if length != 0 { return Err(Error::Format("invalid length in DHT".to_owned())); } Ok((dc_tables, ac_tables)) } // Section B.2.4.4 pub fn parse_dri(reader: &mut R) -> Result { let length = read_length(reader, DRI)?; if length != 2 { return Err(Error::Format("DRI with invalid length".to_owned())); } Ok(read_u16_from_be(reader)?) } // Section B.2.4.5 pub fn parse_com(reader: &mut R) -> Result> { let length = read_length(reader, COM)?; let mut buffer = vec![0u8; length]; reader.read_exact(&mut buffer)?; Ok(buffer) } // Section B.2.4.6 pub fn parse_app(reader: &mut R, marker: Marker) -> Result> { let length = read_length(reader, marker)?; let mut bytes_read = 0; let mut result = None; match marker { APP(0) => { if length >= 5 { let mut buffer = [0u8; 5]; reader.read_exact(&mut buffer)?; bytes_read = buffer.len(); // http://www.w3.org/Graphics/JPEG/jfif3.pdf if buffer[0..5] == *b"JFIF\0" { result = Some(AppData::Jfif); // https://sno.phy.queensu.ca/~phil/exiftool/TagNames/JPEG.html#AVI1 } else if buffer[0..5] == *b"AVI1\0" { result = Some(AppData::Avi1); } } } // Exif Data APP(1) => { if length >= 6 { let mut buffer = [0u8; 6]; reader.read_exact(&mut buffer)?; bytes_read = buffer.len(); // https://web.archive.org/web/20190624045241if_/http://www.cipa.jp:80/std/documents/e/DC-008-Translation-2019-E.pdf // 4.5.4 Basic Structure of JPEG Compressed Data if buffer == *b"Exif\x00\x00" { let mut data = vec![0; length - bytes_read]; reader.read_exact(&mut data)?; bytes_read += data.len(); result = Some(AppData::Exif(data)); } } } APP(2) => { if length > 14 { let mut buffer = [0u8; 14]; reader.read_exact(&mut buffer)?; bytes_read = buffer.len(); // http://www.color.org/ICC_Minor_Revision_for_Web.pdf // B.4 Embedding ICC profiles in JFIF files if buffer[0..12] == *b"ICC_PROFILE\0" { let mut data = vec![0; length - bytes_read]; reader.read_exact(&mut data)?; bytes_read += data.len(); result = Some(AppData::Icc(IccChunk { seq_no: buffer[12], num_markers: buffer[13], data, })); } } } APP(14) => { if length >= 12 { let mut buffer = [0u8; 12]; reader.read_exact(&mut buffer)?; bytes_read = buffer.len(); // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/JPEG.html#Adobe if buffer[0 .. 6] == *b"Adobe\0" { let color_transform = match buffer[11] { 0 => AdobeColorTransform::Unknown, 1 => AdobeColorTransform::YCbCr, 2 => AdobeColorTransform::YCCK, _ => return Err(Error::Format("invalid color transform in adobe app segment".to_owned())), }; result = Some(AppData::Adobe(color_transform)); } } }, _ => {}, } skip_bytes(reader, length - bytes_read)?; Ok(result) } jpeg-decoder-0.3.0/src/upsampler.rs000064400000000000000000000215760072674642500153640ustar 00000000000000use alloc::boxed::Box; use alloc::vec; use alloc::vec::Vec; use crate::error::{Error, Result, UnsupportedFeature}; use crate::parser::Component; pub struct Upsampler { components: Vec, line_buffer_size: usize } struct UpsamplerComponent { upsampler: Box, width: usize, height: usize, row_stride: usize, } impl Upsampler { pub fn new(components: &[Component], output_width: u16, output_height: u16) -> Result { let h_max = components.iter().map(|c| c.horizontal_sampling_factor).max().unwrap(); let v_max = components.iter().map(|c| c.vertical_sampling_factor).max().unwrap(); let mut upsampler_components = Vec::with_capacity(components.len()); for component in components { let upsampler = choose_upsampler((component.horizontal_sampling_factor, component.vertical_sampling_factor), (h_max, v_max), output_width, output_height)?; upsampler_components.push(UpsamplerComponent { upsampler, width: component.size.width as usize, height: component.size.height as usize, row_stride: component.block_size.width as usize * component.dct_scale, }); } let buffer_size = components.iter().map(|c| c.size.width).max().unwrap() as usize * h_max as usize; Ok(Upsampler { components: upsampler_components, line_buffer_size: buffer_size }) } pub fn upsample_and_interleave_row(&self, component_data: &[Vec], row: usize, output_width: usize, output: &mut [u8], color_convert: fn(&[Vec], &mut [u8])) { let component_count = component_data.len(); let mut line_buffers = vec![vec![0u8; self.line_buffer_size]; component_count]; debug_assert_eq!(component_count, self.components.len()); for (i, component) in self.components.iter().enumerate() { component.upsampler.upsample_row(&component_data[i], component.width, component.height, component.row_stride, row, output_width, &mut line_buffers[i]); } color_convert(&line_buffers, output); } } struct UpsamplerH1V1; struct UpsamplerH2V1; struct UpsamplerH1V2; struct UpsamplerH2V2; struct UpsamplerGeneric { horizontal_scaling_factor: u8, vertical_scaling_factor: u8 } fn choose_upsampler(sampling_factors: (u8, u8), max_sampling_factors: (u8, u8), output_width: u16, output_height: u16) -> Result> { let h1 = sampling_factors.0 == max_sampling_factors.0 || output_width == 1; let v1 = sampling_factors.1 == max_sampling_factors.1 || output_height == 1; let h2 = sampling_factors.0 * 2 == max_sampling_factors.0; let v2 = sampling_factors.1 * 2 == max_sampling_factors.1; if h1 && v1 { Ok(Box::new(UpsamplerH1V1)) } else if h2 && v1 { Ok(Box::new(UpsamplerH2V1)) } else if h1 && v2 { Ok(Box::new(UpsamplerH1V2)) } else if h2 && v2 { Ok(Box::new(UpsamplerH2V2)) } else { if max_sampling_factors.0 % sampling_factors.0 != 0 || max_sampling_factors.1 % sampling_factors.1 != 0 { Err(Error::Unsupported(UnsupportedFeature::NonIntegerSubsamplingRatio)) } else { Ok(Box::new(UpsamplerGeneric { horizontal_scaling_factor: max_sampling_factors.0 / sampling_factors.0, vertical_scaling_factor: max_sampling_factors.1 / sampling_factors.1 })) } } } trait Upsample { fn upsample_row(&self, input: &[u8], input_width: usize, input_height: usize, row_stride: usize, row: usize, output_width: usize, output: &mut [u8]); } impl Upsample for UpsamplerH1V1 { fn upsample_row(&self, input: &[u8], _input_width: usize, _input_height: usize, row_stride: usize, row: usize, output_width: usize, output: &mut [u8]) { let input = &input[row * row_stride ..]; output[..output_width].copy_from_slice(&input[..output_width]); } } impl Upsample for UpsamplerH2V1 { fn upsample_row(&self, input: &[u8], input_width: usize, _input_height: usize, row_stride: usize, row: usize, _output_width: usize, output: &mut [u8]) { let input = &input[row * row_stride ..]; if input_width == 1 { output[0] = input[0]; output[1] = input[0]; return; } output[0] = input[0]; output[1] = ((input[0] as u32 * 3 + input[1] as u32 + 2) >> 2) as u8; for i in 1 .. input_width - 1 { let sample = 3 * input[i] as u32 + 2; output[i * 2] = ((sample + input[i - 1] as u32) >> 2) as u8; output[i * 2 + 1] = ((sample + input[i + 1] as u32) >> 2) as u8; } output[(input_width - 1) * 2] = ((input[input_width - 1] as u32 * 3 + input[input_width - 2] as u32 + 2) >> 2) as u8; output[(input_width - 1) * 2 + 1] = input[input_width - 1]; } } impl Upsample for UpsamplerH1V2 { fn upsample_row(&self, input: &[u8], _input_width: usize, input_height: usize, row_stride: usize, row: usize, output_width: usize, output: &mut [u8]) { let row_near = row as f32 / 2.0; // If row_near's fractional is 0.0 we want row_far to be the previous row and if it's 0.5 we // want it to be the next row. let row_far = (row_near + row_near.fract() * 3.0 - 0.25).min((input_height - 1) as f32); let input_near = &input[row_near as usize * row_stride ..]; let input_far = &input[row_far as usize * row_stride ..]; let output = &mut output[..output_width]; let input_near = &input_near[..output_width]; let input_far = &input_far[..output_width]; for i in 0..output_width { output[i] = ((3 * input_near[i] as u32 + input_far[i] as u32 + 2) >> 2) as u8; } } } impl Upsample for UpsamplerH2V2 { fn upsample_row(&self, input: &[u8], input_width: usize, input_height: usize, row_stride: usize, row: usize, _output_width: usize, output: &mut [u8]) { let row_near = row as f32 / 2.0; // If row_near's fractional is 0.0 we want row_far to be the previous row and if it's 0.5 we // want it to be the next row. let row_far = (row_near + row_near.fract() * 3.0 - 0.25).min((input_height - 1) as f32); let input_near = &input[row_near as usize * row_stride ..]; let input_far = &input[row_far as usize * row_stride ..]; if input_width == 1 { let value = ((3 * input_near[0] as u32 + input_far[0] as u32 + 2) >> 2) as u8; output[0] = value; output[1] = value; return; } let mut t1 = 3 * input_near[0] as u32 + input_far[0] as u32; output[0] = ((t1 + 2) >> 2) as u8; for i in 1 .. input_width { let t0 = t1; t1 = 3 * input_near[i] as u32 + input_far[i] as u32; output[i * 2 - 1] = ((3 * t0 + t1 + 8) >> 4) as u8; output[i * 2] = ((3 * t1 + t0 + 8) >> 4) as u8; } output[input_width * 2 - 1] = ((t1 + 2) >> 2) as u8; } } impl Upsample for UpsamplerGeneric { // Uses nearest neighbor sampling fn upsample_row(&self, input: &[u8], input_width: usize, _input_height: usize, row_stride: usize, row: usize, _output_width: usize, output: &mut [u8]) { let mut index = 0; let start = (row / self.vertical_scaling_factor as usize) * row_stride; let input = &input[start..(start + input_width)]; for val in input { for _ in 0..self.horizontal_scaling_factor { output[index] = *val; index += 1; } } } } jpeg-decoder-0.3.0/src/worker/immediate.rs000064400000000000000000000055730072674642500166220ustar 00000000000000use alloc::vec; use alloc::vec::Vec; use core::mem; use core::convert::TryInto; use crate::decoder::MAX_COMPONENTS; use crate::error::Result; use crate::idct::dequantize_and_idct_block; use crate::alloc::sync::Arc; use crate::parser::Component; use super::{RowData, Worker}; pub struct ImmediateWorker { offsets: [usize; MAX_COMPONENTS], results: Vec>, components: Vec>, quantization_tables: Vec>>, } impl Default for ImmediateWorker { fn default() -> Self { ImmediateWorker { offsets: [0; MAX_COMPONENTS], results: vec![Vec::new(); MAX_COMPONENTS], components: vec![None; MAX_COMPONENTS], quantization_tables: vec![None; MAX_COMPONENTS], } } } impl ImmediateWorker { pub fn start_immediate(&mut self, data: RowData) { assert!(self.results[data.index].is_empty()); self.offsets[data.index] = 0; self.results[data.index].resize(data.component.block_size.width as usize * data.component.block_size.height as usize * data.component.dct_scale * data.component.dct_scale, 0u8); self.components[data.index] = Some(data.component); self.quantization_tables[data.index] = Some(data.quantization_table); } pub fn append_row_immediate(&mut self, (index, data): (usize, Vec)) { // Convert coefficients from a MCU row to samples. let component = self.components[index].as_ref().unwrap(); let quantization_table = self.quantization_tables[index].as_ref().unwrap(); let block_count = component.block_size.width as usize * component.vertical_sampling_factor as usize; let line_stride = component.block_size.width as usize * component.dct_scale; assert_eq!(data.len(), block_count * 64); for i in 0..block_count { let x = (i % component.block_size.width as usize) * component.dct_scale; let y = (i / component.block_size.width as usize) * component.dct_scale; let coefficients = data[i * 64..(i + 1) * 64].try_into().unwrap(); let output = &mut self.results[index][self.offsets[index] + y * line_stride + x..]; dequantize_and_idct_block(component.dct_scale, coefficients, quantization_table, line_stride, output); } self.offsets[index] += block_count * component.dct_scale * component.dct_scale; } pub fn get_result_immediate(&mut self, index: usize) -> Vec { mem::take(&mut self.results[index]) } } impl Worker for ImmediateWorker { fn start(&mut self, data: RowData) -> Result<()> { self.start_immediate(data); Ok(()) } fn append_row(&mut self, row: (usize, Vec)) -> Result<()> { self.append_row_immediate(row); Ok(()) } fn get_result(&mut self, index: usize) -> Result> { Ok(self.get_result_immediate(index)) } } jpeg-decoder-0.3.0/src/worker/mod.rs000064400000000000000000000075570072674642500154470ustar 00000000000000mod immediate; mod multithreaded; #[cfg(all( not(any(target_arch = "asmjs", target_arch = "wasm32")), feature = "rayon" ))] mod rayon; use crate::decoder::{choose_color_convert_func, ColorTransform}; use crate::error::Result; use crate::parser::{Component, Dimensions}; use crate::upsampler::Upsampler; use alloc::sync::Arc; use alloc::vec::Vec; use core::cell::RefCell; pub struct RowData { pub index: usize, pub component: Component, pub quantization_table: Arc<[u16; 64]>, } pub trait Worker { fn start(&mut self, row_data: RowData) -> Result<()>; fn append_row(&mut self, row: (usize, Vec)) -> Result<()>; fn get_result(&mut self, index: usize) -> Result>; /// Default implementation for spawning multiple tasks. fn append_rows(&mut self, row: &mut dyn Iterator)>) -> Result<()> { for item in row { self.append_row(item)?; } Ok(()) } } #[allow(dead_code)] pub enum PreferWorkerKind { Immediate, Multithreaded, } #[derive(Default)] pub struct WorkerScope { inner: core::cell::RefCell>, } enum WorkerScopeInner { #[cfg(all( not(any(target_arch = "asmjs", target_arch = "wasm32")), feature = "rayon" ))] Rayon(rayon::Scoped), #[cfg(not(any(target_arch = "asmjs", target_arch = "wasm32")))] Multithreaded(multithreaded::MpscWorker), Immediate(immediate::ImmediateWorker), } impl WorkerScope { pub fn with(with: impl FnOnce(&Self) -> T) -> T { with(&WorkerScope { inner: RefCell::default(), }) } pub fn get_or_init_worker( &self, prefer: PreferWorkerKind, f: impl FnOnce(&mut dyn Worker) -> T, ) -> T { let mut inner = self.inner.borrow_mut(); let inner = inner.get_or_insert_with(move || match prefer { #[cfg(all( not(any(target_arch = "asmjs", target_arch = "wasm32")), feature = "rayon" ))] PreferWorkerKind::Multithreaded => WorkerScopeInner::Rayon(Default::default()), #[allow(unreachable_patterns)] #[cfg(not(any(target_arch = "asmjs", target_arch = "wasm32")))] PreferWorkerKind::Multithreaded => WorkerScopeInner::Multithreaded(Default::default()), _ => WorkerScopeInner::Immediate(Default::default()), }); f(match &mut *inner { #[cfg(all( not(any(target_arch = "asmjs", target_arch = "wasm32")), feature = "rayon" ))] WorkerScopeInner::Rayon(worker) => worker, #[cfg(not(any(target_arch = "asmjs", target_arch = "wasm32")))] WorkerScopeInner::Multithreaded(worker) => worker, WorkerScopeInner::Immediate(worker) => worker, }) } } pub fn compute_image_parallel( components: &[Component], data: Vec>, output_size: Dimensions, color_transform: ColorTransform, ) -> Result> { #[cfg(all( not(any(target_arch = "asmjs", target_arch = "wasm32")), feature = "rayon" ))] return rayon::compute_image_parallel(components, data, output_size, color_transform); #[allow(unreachable_code)] { let color_convert_func = choose_color_convert_func(components.len(), color_transform)?; let upsampler = Upsampler::new(components, output_size.width, output_size.height)?; let line_size = output_size.width as usize * components.len(); let mut image = vec![0u8; line_size * output_size.height as usize]; for (row, line) in image.chunks_mut(line_size).enumerate() { upsampler.upsample_and_interleave_row( &data, row, output_size.width as usize, line, color_convert_func, ); } Ok(image) } } jpeg-decoder-0.3.0/src/worker/multithreaded.rs000064400000000000000000000100170072674642500175040ustar 00000000000000//! This module implements per-component parallelism. //! It should be possible to implement per-row parallelism as well, //! which should also boost performance of grayscale images //! and allow scaling to more cores. //! However, that would be more complex, so we use this as a starting point. use super::immediate::ImmediateWorker; use super::{RowData, Worker}; use crate::decoder::MAX_COMPONENTS; use crate::error::Result; use std::{ mem, sync::mpsc::{self, Receiver, Sender}, }; enum WorkerMsg { Start(RowData), AppendRow(Vec), GetResult(Sender>), } #[derive(Default)] pub struct MpscWorker { senders: [Option>; MAX_COMPONENTS], } impl MpscWorker { fn start_with( &mut self, row_data: RowData, spawn_worker: impl FnOnce(usize) -> Result>, ) -> Result<()> { // if there is no worker thread for this component yet, start one let component = row_data.index; if let None = self.senders[component] { let sender = spawn_worker(component)?; self.senders[component] = Some(sender); } // we do the "take out value and put it back in once we're done" dance here // and in all other message-passing methods because there's not that many rows // and this should be cheaper than spawning MAX_COMPONENTS many threads up front let sender = self.senders[component].as_mut().unwrap(); sender .send(WorkerMsg::Start(row_data)) .expect("jpeg-decoder worker thread error"); Ok(()) } fn append_row(&mut self, row: (usize, Vec)) -> Result<()> { let component = row.0; let sender = self.senders[component].as_mut().unwrap(); sender .send(WorkerMsg::AppendRow(row.1)) .expect("jpeg-decoder worker thread error"); Ok(()) } fn get_result_with( &mut self, index: usize, collect: impl FnOnce(Receiver>) -> Vec, ) -> Result> { let (tx, rx) = mpsc::channel(); let sender = mem::take(&mut self.senders[index]).unwrap(); sender .send(WorkerMsg::GetResult(tx)) .expect("jpeg-decoder worker thread error"); Ok(collect(rx)) } } impl Worker for MpscWorker { fn start(&mut self, row_data: RowData) -> Result<()> { self.start_with(row_data, spawn_worker_thread) } fn append_row(&mut self, row: (usize, Vec)) -> Result<()> { MpscWorker::append_row(self, row) } fn get_result(&mut self, index: usize) -> Result> { self.get_result_with(index, collect_worker_thread) } } fn create_worker() -> (Sender, impl FnOnce() + 'static) { let (tx, rx) = mpsc::channel(); let closure = move || { let mut worker = ImmediateWorker::default(); while let Ok(message) = rx.recv() { match message { WorkerMsg::Start(mut data) => { // we always set component index to 0 for worker threads // because they only ever handle one per thread and we don't want them // to attempt to access nonexistent components data.index = 0; worker.start_immediate(data); } WorkerMsg::AppendRow(row) => { worker.append_row_immediate((0, row)); } WorkerMsg::GetResult(chan) => { let _ = chan.send(worker.get_result_immediate(0)); break; } } } }; (tx, closure) } fn spawn_worker_thread(component: usize) -> Result> { let (tx, worker) = create_worker(); let thread_builder = std::thread::Builder::new().name(format!("worker thread for component {}", component)); thread_builder.spawn(worker)?; Ok(tx) } fn collect_worker_thread(rx: Receiver>) -> Vec { rx.recv().expect("jpeg-decoder worker thread error") } jpeg-decoder-0.3.0/src/worker/rayon.rs000064400000000000000000000165230072674642500160110ustar 00000000000000use core::convert::TryInto; use rayon::iter::{IndexedParallelIterator, ParallelIterator}; use rayon::slice::ParallelSliceMut; use crate::decoder::{choose_color_convert_func, ColorTransform}; use crate::error::Result; use crate::idct::dequantize_and_idct_block; use crate::parser::Component; use crate::upsampler::Upsampler; use crate::{decoder::MAX_COMPONENTS, parser::Dimensions}; use std::sync::Arc; use super::{RowData, Worker}; /// Technically similar to `immediate::ImmediateWorker` but we copy it since we may prefer /// different style of managing the memory allocation, something that multiple actors can access in /// parallel. #[derive(Default)] struct ImmediateWorker { offsets: [usize; MAX_COMPONENTS], results: [Vec; MAX_COMPONENTS], components: [Option; MAX_COMPONENTS], quantization_tables: [Option>; MAX_COMPONENTS], } #[derive(Clone, Copy)] struct ComponentMetadata { block_width: usize, block_count: usize, line_stride: usize, dct_scale: usize, } #[derive(Default)] pub struct Scoped { inner: ImmediateWorker, } impl ImmediateWorker { pub fn start_immediate(&mut self, data: RowData) { let elements = data.component.block_size.width as usize * data.component.block_size.height as usize * data.component.dct_scale * data.component.dct_scale; self.offsets[data.index] = 0; self.results[data.index].resize(elements, 0u8); self.components[data.index] = Some(data.component); self.quantization_tables[data.index] = Some(data.quantization_table); } pub fn get_result_immediate(&mut self, index: usize) -> Vec { core::mem::take(&mut self.results[index]) } pub fn component_metadata(&self, index: usize) -> Option { let component = self.components[index].as_ref()?; let block_size = component.block_size; let block_width = block_size.width as usize; let block_count = block_size.width as usize * component.vertical_sampling_factor as usize; let line_stride = block_size.width as usize * component.dct_scale; let dct_scale = component.dct_scale; Some(ComponentMetadata { block_width, block_count, line_stride, dct_scale, }) } pub fn append_row_locked( quantization_table: Arc<[u16; 64]>, metadata: ComponentMetadata, data: Vec, result_block: &mut [u8], ) { // Convert coefficients from a MCU row to samples. let ComponentMetadata { block_count, line_stride, block_width, dct_scale, } = metadata; assert_eq!(data.len(), block_count * 64); let mut output_buffer = [0; 64]; for i in 0..block_count { let x = (i % block_width) * dct_scale; let y = (i / block_width) * dct_scale; let coefficients: &[i16; 64] = &data[i * 64..(i + 1) * 64].try_into().unwrap(); // Write to a temporary intermediate buffer, a 8x8 'image'. dequantize_and_idct_block( dct_scale, coefficients, &*quantization_table, 8, &mut output_buffer, ); let write_back = &mut result_block[y * line_stride + x..]; let buffered_lines = output_buffer.chunks_mut(8); let back_lines = write_back.chunks_mut(line_stride); for (buf, back) in buffered_lines.zip(back_lines).take(dct_scale) { back[..dct_scale].copy_from_slice(&buf[..dct_scale]); } } } } impl Worker for Scoped { fn start(&mut self, row_data: RowData) -> Result<()> { self.inner.start_immediate(row_data); Ok(()) } fn append_row(&mut self, row: (usize, Vec)) -> Result<()> { let inner = &mut self.inner; let (index, data) = row; let quantization_table = inner.quantization_tables[index].as_ref().unwrap().clone(); let metadata = inner.component_metadata(index).unwrap(); let result_block = &mut inner.results[index][inner.offsets[index]..]; inner.offsets[index] += metadata.bytes_used(); ImmediateWorker::append_row_locked(quantization_table, metadata, data, result_block); Ok(()) } fn get_result(&mut self, index: usize) -> Result> { let result = self.inner.get_result_immediate(index); Ok(result) } // Magic sauce, these _may_ run in parallel. fn append_rows(&mut self, iter: &mut dyn Iterator)>) -> Result<()> { let inner = &mut self.inner; rayon::in_place_scope(|scope| { let metadatas = [ inner.component_metadata(0), inner.component_metadata(1), inner.component_metadata(2), inner.component_metadata(3), ]; let [res0, res1, res2, res3] = &mut inner.results; // Lazily get the blocks. Note: if we've already collected results from a component // then the result vector has already been deallocated/taken. But no more tasks should // be created for it. let mut result_blocks = [ res0.get_mut(inner.offsets[0]..).unwrap_or(&mut []), res1.get_mut(inner.offsets[1]..).unwrap_or(&mut []), res2.get_mut(inner.offsets[2]..).unwrap_or(&mut []), res3.get_mut(inner.offsets[3]..).unwrap_or(&mut []), ]; // First we schedule everything, making sure their index is right etc. for (index, data) in iter { let metadata = metadatas[index].unwrap(); let quantization_table = inner.quantization_tables[index].as_ref().unwrap().clone(); inner.offsets[index] += metadata.bytes_used(); let (result_block, tail) = core::mem::take(&mut result_blocks[index]).split_at_mut(metadata.bytes_used()); result_blocks[index] = tail; scope.spawn(move |_| { ImmediateWorker::append_row_locked( quantization_table, metadata, data, result_block, ) }); } }); Ok(()) } } impl ComponentMetadata { fn bytes_used(&self) -> usize { self.block_count * self.dct_scale * self.dct_scale } } pub fn compute_image_parallel( components: &[Component], data: Vec>, output_size: Dimensions, color_transform: ColorTransform, ) -> Result> { let color_convert_func = choose_color_convert_func(components.len(), color_transform)?; let upsampler = Upsampler::new(components, output_size.width, output_size.height)?; let line_size = output_size.width as usize * components.len(); let mut image = vec![0u8; line_size * output_size.height as usize]; image .par_chunks_mut(line_size) .with_max_len(1) .enumerate() .for_each(|(row, line)| { upsampler.upsample_and_interleave_row( &data, row, output_size.width as usize, line, color_convert_func, ); }); Ok(image) } jpeg-decoder-0.3.0/tests/lib.rs000064400000000000000000000103420072674642500144620ustar 00000000000000extern crate jpeg_decoder as jpeg; extern crate png; extern crate walkdir; use std::path::Path; use std::fs::File; mod common; mod crashtest; mod reftest; #[test] #[wasm_bindgen_test::wasm_bindgen_test] fn included_file() { const FILE: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/reftest/images/mozilla/jpg-progressive.jpg")); let mut data = FILE; let mut decoder = jpeg::Decoder::new(&mut data); let ref_data = decoder.decode().unwrap(); let ref_info = decoder.info().unwrap(); let mut data = FILE; decoder = jpeg::Decoder::new(&mut data); decoder.read_info().unwrap(); let info = decoder.info().unwrap(); let data = decoder.decode().unwrap(); assert_eq!(info, decoder.info().unwrap()); assert_eq!(info, ref_info); assert_eq!(data, ref_data); } #[test] fn read_info() { let path = Path::new("tests").join("reftest").join("images").join("mozilla").join("jpg-progressive.jpg"); let mut decoder = jpeg::Decoder::new(File::open(&path).unwrap()); let ref_data = decoder.decode().unwrap(); let ref_info = decoder.info().unwrap(); decoder = jpeg::Decoder::new(File::open(&path).unwrap()); decoder.read_info().unwrap(); let info = decoder.info().unwrap(); let data = decoder.decode().unwrap(); assert_eq!(info, decoder.info().unwrap()); assert_eq!(info, ref_info); assert_eq!(data, ref_data); } #[test] fn read_icc_profile() { let path = Path::new("tests") .join("reftest") .join("images") .join("mozilla") .join("jpg-srgb-icc.jpg"); let mut decoder = jpeg::Decoder::new(File::open(&path).unwrap()); decoder.decode().unwrap(); let profile = decoder.icc_profile().unwrap(); // "acsp" is a mandatory string in ICC profile headers. assert_eq!(&profile[36..40], b"acsp"); } // Test if chunks are concatenated in the correct order #[test] fn read_icc_profile_random_order() { let path = Path::new("tests") .join("icc") .join("icc_chunk_order.jpeg"); let mut decoder = jpeg::Decoder::new(File::open(&path).unwrap()); decoder.decode().unwrap(); let profile = decoder.icc_profile().unwrap(); assert_eq!(profile.len(), 254); for i in 1..=254 { assert_eq!(profile[i - 1], i as u8); } } // Check if ICC profiles with invalid chunk number 0 are discarded #[test] fn read_icc_profile_seq_no_0() { let path = Path::new("tests") .join("icc") .join("icc_chunk_seq_no_0.jpeg"); let mut decoder = jpeg::Decoder::new(File::open(&path).unwrap()); decoder.decode().unwrap(); let profile = decoder.icc_profile(); assert!(profile.is_none()); } // Check if ICC profiles with multiple chunks with the same number are discarded #[test] fn read_icc_profile_double_seq_no() { let path = Path::new("tests") .join("icc") .join("icc_chunk_double_seq_no.jpeg"); let mut decoder = jpeg::Decoder::new(File::open(&path).unwrap()); decoder.decode().unwrap(); let profile = decoder.icc_profile(); assert!(profile.is_none()); } // Check if ICC profiles with mismatching number of chunks and total chunk count are discarded #[test] fn read_icc_profile_chunk_count_mismatch() { let path = Path::new("tests") .join("icc") .join("icc_chunk_count_mismatch.jpeg"); let mut decoder = jpeg::Decoder::new(File::open(&path).unwrap()); decoder.decode().unwrap(); let profile = decoder.icc_profile(); assert!(profile.is_none()); } // Check if ICC profiles with missing chunk are discarded #[test] fn read_icc_profile_missing_chunk() { let path = Path::new("tests") .join("icc") .join("icc_missing_chunk.jpeg"); let mut decoder = jpeg::Decoder::new(File::open(&path).unwrap()); decoder.decode().unwrap(); let profile = decoder.icc_profile(); assert!(profile.is_none()); } #[test] fn read_exif_data() { let path = Path::new("tests") .join("reftest") .join("images") .join("ycck.jpg"); let mut decoder = jpeg::Decoder::new(File::open(&path).unwrap()); decoder.decode().unwrap(); let exif_data = decoder.exif_data().unwrap(); // exif data start as a TIFF header assert_eq!(&exif_data[0..8], b"\x49\x49\x2A\x00\x08\x00\x00\x00"); } jpeg-decoder-0.3.0/tests/rayon-0.rs000064400000000000000000000007550072674642500152100ustar 00000000000000//! Must be a separate test because it modifies the _global_ rayon pool. use std::{fs::File, path::Path}; use jpeg_decoder::Decoder; #[test] fn decoding_in_global_pool() { let path = Path::new("tests").join("reftest").join("images").join("mozilla").join("jpg-progressive.jpg"); rayon::ThreadPoolBuilder::new() .num_threads(1) .build_global() .unwrap(); let mut decoder = Decoder::new(File::open(&path).unwrap()); let _ = decoder.decode().unwrap(); } jpeg-decoder-0.3.0/tests/rayon-1.rs000064400000000000000000000010330072674642500151770ustar 00000000000000//! Must be a separate test because it modifies the _global_ rayon pool. use std::{fs::File, path::Path}; use jpeg_decoder::Decoder; #[test] fn decoding_in_fetched_global_pool() { let path = Path::new("tests").join("reftest").join("images").join("mozilla").join("jpg-progressive.jpg"); rayon::ThreadPoolBuilder::new() .num_threads(1) .build_global() .unwrap(); rayon::scope(|_| { let mut decoder = Decoder::new(File::open(&path).unwrap()); let _ = decoder.decode().unwrap(); }) } jpeg-decoder-0.3.0/tests/rayon-2.rs000064400000000000000000000012000072674642500151740ustar 00000000000000//! Must be a separate test because it modifies the _global_ rayon pool. use std::{fs::File, path::Path}; use jpeg_decoder::Decoder; #[test] fn decoding_in_global_pool() { let path = Path::new("tests/reftest/images/progressive3.jpg"); rayon::ThreadPoolBuilder::new() .num_threads(2) .build_global() .unwrap(); let _: Vec<_> = (0..1024) .map(|_| { let path = path.clone(); std::thread::spawn(move || { let mut decoder = Decoder::new(File::open(&path).unwrap()); let _ = decoder.decode().unwrap(); }); }).collect(); } jpeg-decoder-0.3.0/tests/rayon.rs000064400000000000000000000007460072674642500150530ustar 00000000000000use std::{fs::File, path::Path}; use jpeg_decoder::Decoder; #[test] fn decoding_in_limited_threadpool_does_not_deadlock() { let path = Path::new("tests").join("reftest").join("images").join("mozilla").join("jpg-progressive.jpg"); let pool = rayon::ThreadPoolBuilder::new() .num_threads(1) .build() .unwrap(); pool.install(|| { let mut decoder = Decoder::new(File::open(&path).unwrap()); let _ = decoder.decode().unwrap(); }); }