pax_global_header00006660000000000000000000000064152136075650014524gustar00rootroot0000000000000052 comment=501148829d9467fe9ee5449e3050b5a5a2117855 Miriway-Miriway-854d43d/000077500000000000000000000000001521360756500151255ustar00rootroot00000000000000Miriway-Miriway-854d43d/.github/000077500000000000000000000000001521360756500164655ustar00rootroot00000000000000Miriway-Miriway-854d43d/.github/workflows/000077500000000000000000000000001521360756500205225ustar00rootroot00000000000000Miriway-Miriway-854d43d/.github/workflows/close-snap.yml000066400000000000000000000005641521360756500233160ustar00rootroot00000000000000name: Close Snaps on: pull_request: types: [closed] jobs: close: runs-on: ubuntu-latest timeout-minutes: 5 steps: - name: Close obsolete channels uses: canonical/actions/close-snap@release continue-on-error: true with: channel: edge/pr${{ github.event.number }} snapcraft-token: ${{ secrets.SNAPCRAFT_TOKEN }} Miriway-Miriway-854d43d/.github/workflows/cmake.yml000066400000000000000000000031231521360756500223240ustar00rootroot00000000000000name: CMake on: push: branches: [ "main" ] pull_request: branches: [ "main" ] env: # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) BUILD_TYPE: Release jobs: build: # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. # You can convert this to a matrix build if you need cross-platform coverage. # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - name: Add PPA run: sudo apt-add-repository ppa:mir-team/release - name: Install dependencies run: sudo apt-get install libmiral-dev libmirwayland-dev libboost-exception-dev libxkbcommon-dev - name: Configure CMake # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} - name: Build # Build your program with the given configuration run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} - name: Test working-directory: ${{github.workspace}}/build # Execute tests defined by the CMake configuration. # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail run: ctest -C ${{env.BUILD_TYPE}} Miriway-Miriway-854d43d/.github/workflows/refresh-downstreams.yml000066400000000000000000000013331521360756500252470ustar00rootroot00000000000000name: Refresh downstreams on: push: branches: - main jobs: Refresh: runs-on: ubuntu-latest timeout-minutes: 5 strategy: fail-fast: false matrix: ref: - mir-libs-build steps: - name: Check out code uses: actions/checkout@v4 with: # so that we know what to cherry-pick from fetch-depth: 2 - name: Update `${{ matrix.ref }}` env: GIT_COMMITTER_NAME: "Mir CI Bot" GIT_COMMITTER_EMAIL: "mir-ci-bot@canonical.com" run: | # bring mir-libs changes in git fetch origin ${{ matrix.ref }} git cherry-pick HEAD..origin/${{ matrix.ref }} git push --force origin HEAD:${{ matrix.ref }} Miriway-Miriway-854d43d/.github/workflows/snap.yml000066400000000000000000000022571521360756500222140ustar00rootroot00000000000000name: Snap on: merge_group: types: [checks_requested] pull_request: types: [opened, synchronize, reopened, ready_for_review] jobs: Snap: runs-on: ubuntu-latest timeout-minutes: 45 strategy: matrix: platform: - amd64 - armhf - arm64 fail-fast: false steps: - name: Check out code uses: actions/checkout@v4 with: fetch-depth: 0 # needed for version determination - name: Patch PPA and version run: | sed -i 's@mir-team/release@mir-team/dev@' snap/snapcraft.yaml sed -i 's@rev-list --count@rev-parse --short@' snap/snapcraft.yaml - name: Build and publish the snap uses: canonical/actions/build-snap@release with: architecture: ${{ matrix.platform }} review-opts: --allow-classic snapcraft-token: ${{ secrets.SNAPCRAFT_TOKEN }} launchpad-credentials: ${{ secrets.LAUNCHPAD_CREDENTIALS }} launchpad-accept-public-upload: true publish: ${{ github.event_name == 'pull_request' && github.repository == github.event.pull_request.head.repo.full_name }} publish-channel: edge/pr${{ github.event.number }} Miriway-Miriway-854d43d/.gitignore000066400000000000000000000004161521360756500171160ustar00rootroot00000000000000# Prerequisites *.d # Compiled Object files *.slo *.lo *.o *.obj # Precompiled Headers *.gch *.pch # Compiled Dynamic libraries *.so *.dylib *.dll # Fortran module files *.mod *.smod # Compiled Static libraries *.lai *.la *.a *.lib # Executables *.exe *.out *.app Miriway-Miriway-854d43d/CMakeLists.txt000066400000000000000000000072071521360756500176730ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.10) cmake_policy(SET CMP0015 NEW) cmake_policy(SET CMP0022 NEW) project(miriway) set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -g -Werror -Wall -pedantic -Wextra -fPIC -Wnon-virtual-dtor") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,defs") include(GNUInstallDirs) include(FindPkgConfig) include(CheckIncludeFileCXX) option(SDDM "Install configuration for SDDM?" OFF) pkg_check_modules(MIRAL miral>=5.5 REQUIRED IMPORTED_TARGET) pkg_check_modules(MIRWAYLAND mirwayland REQUIRED IMPORTED_TARGET) pkg_check_modules(XKBCOMMON xkbcommon REQUIRED IMPORTED_TARGET) add_compile_definitions(MIR_LOG_COMPONENT="miriway") add_subdirectory(wayland-generated) add_library(miriwaycommon STATIC miriway_app_switcher.cpp miriway_app_switcher.h miriway_child_control.cpp miriway_child_control.h miriway_commands.cpp miriway_commands.h miriway_workspace_manager.cpp miriway_workspace_manager.h miriway_workspace_hooks.h wayland-generated/ext-workspace-v1_wrapper.cpp wayland-generated/ext-workspace-v1_wrapper.h miriway_ext_workspace_v1.cpp miriway_ext_workspace_v1.h miriway_documenting_store.cpp miriway_documenting_store.h miriway_magnifier.cpp miriway_magnifier.h ) target_link_libraries(miriwaycommon PUBLIC PkgConfig::MIRAL PkgConfig::XKBCOMMON PRIVATE PkgConfig::MIRWAYLAND ) add_executable(miriway-shell miriway.cpp miriway_policy.cpp miriway_policy.h) target_link_libraries(miriway-shell miriwaycommon) add_executable(miriway-run-shell miriway-run-shell.cpp) target_link_libraries(miriway-run-shell PkgConfig::MIRAL PkgConfig::XKBCOMMON) add_custom_target(miriway ALL cp ${CMAKE_CURRENT_SOURCE_DIR}/miriway ${CMAKE_BINARY_DIR} ) add_custom_target(miriway-run ALL cp ${CMAKE_CURRENT_SOURCE_DIR}/miriway-run ${CMAKE_BINARY_DIR} ) add_custom_target(miriway-terminal ALL cp ${CMAKE_CURRENT_SOURCE_DIR}/miriway-terminal ${CMAKE_BINARY_DIR} ) add_custom_target(miriway-unsnap ALL cp ${CMAKE_CURRENT_SOURCE_DIR}/miriway-unsnap ${CMAKE_BINARY_DIR} ) add_custom_target(miriway-background ALL cp ${CMAKE_CURRENT_SOURCE_DIR}/miriway-background ${CMAKE_BINARY_DIR} ) install(PROGRAMS ${CMAKE_BINARY_DIR}/miriway ${CMAKE_BINARY_DIR}/miriway-run ${CMAKE_BINARY_DIR}/miriway-run-shell ${CMAKE_BINARY_DIR}/miriway-shell ${CMAKE_BINARY_DIR}/miriway-session ${CMAKE_BINARY_DIR}/miriway-terminal ${CMAKE_BINARY_DIR}/miriway-unsnap ${CMAKE_BINARY_DIR}/miriway-background DESTINATION ${CMAKE_INSTALL_BINDIR} ) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/miriway-session.in miriway-session @ONLY) install(FILES ${CMAKE_SOURCE_DIR}/miriway.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/wayland-sessions/ ) install(FILES ${CMAKE_SOURCE_DIR}/backgrounds/miriway.png DESTINATION ${CMAKE_INSTALL_DATADIR}/backgrounds/ ) install(FILES ${CMAKE_SOURCE_DIR}/miriway-shell.config DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/xdg/xdg-miriway ) install(PROGRAMS ${CMAKE_SOURCE_DIR}/systemd/usr/libexec/miriway-session-startup ${CMAKE_SOURCE_DIR}/systemd/usr/libexec/miriway-session-shutdown DESTINATION ${CMAKE_INSTALL_LIBEXECDIR} ) install(FILES ${CMAKE_SOURCE_DIR}/systemd/usr/lib/systemd/user/miriway-session.target DESTINATION /usr/lib/systemd/user/ ) if(SDDM) configure_file(${CMAKE_SOURCE_DIR}/sddm/miriway.conf.in ${CMAKE_BINARY_DIR}/sddm/miriway.conf @ONLY) install(FILES ${CMAKE_BINARY_DIR}/sddm/miriway.conf DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/sddm.conf.d/ ) endif() Miriway-Miriway-854d43d/CONFIGURING_MIRIWAY.md000066400000000000000000000112731521360756500204260ustar00rootroot00000000000000# Configuring Miriway The Miriway shell is intentionally provided with a minimal configuration that can be built upon. The most obvious lack is the absence of "wallpaper", "docks" and "panels". These are covered under "Shell Components". Another lack is a way to launch applications. There's a very basic solution in `Ctrl-Alt-T` which launches a terminal emulator from which other apps can be started. But it is possible to integrate specialised app launchers (and other applications) into the shell. See "Shell Apps" (below). ## Basic configuration In addition to these Miriway specific configuration options, all the standard Mir Server configuration options are supported. These include such things as display layout. ### Supplying Configuration Options There are three sources of configuration for Miriway: 1. A `mirway-shell.settings` file, typically, in `~/.config` that is automatically created by Miriway on startup and contains settings such as key bindings and shell components to use. This file is reloaded when it changes, and these settings are applied. 2. A `mirway-shell.config` file, typically, in `~/.config` that contains options that apply whilst the compositor is running. (These options can also be supplied on the command line or as environment variables. This file in not reloaded until the compositor restarts. These options are standard for Mir based compositors and are documented at https://canonical.com/mir/docs/stable/configuring/reference/options/ 3. Optionally, a `mirway-shell.display` file (specified by a `display-config=static`) option in `mirway-shell.config`. This file is generated by Miriway and is reloaded when it changes, and these settings are applied. ### Shell Components These are applications that are configured to be given access to privileged Wayland extension protocols (for example, `layer-shell` which allows placement of wallpaper, panels, etc). There are two types of shell component: Shell components that should be launched when the shell starts and restarted if they fail are specified with `command_shell_component` in `mirway-shell.config`. For example, command_shell_component=swaybg --mode fill --output '*' --image /usr/share/lubuntu/wallpapers/lubuntu-default-wallpaper.jpg Shell components that are launched by the user are specified by either `command_shell_meta` or `command_shell_ctrl_alt` in `mirway-shell.settings`. For example: command_shell_meta=a:wofi --show drun --location top_left ### Wayland Protocols Extension The Wayland ecosystem is built of a collection of Wayland protocol extensions that allow apps and compositors to negotiate how things are to be displayed. Many of these extension protocols are generally useful and can be made available to all applications. However, some of these extension protocols, while useful for trusted applications, may have security concerns. Miriway restricts the use of these protocols to apps explicitly configured as "Shell Components". Additional Wayland extensions can be made available to all applications with: add-wayland-extensions=zwp_idle_inhibit_manager_v1 Additional Wayland extensions can be made available to shell components only with: shell-add-wayland-extension=zwp_virtual_keyboard_manager_v1 shell-add-wayland-extension=zwlr_virtual_pointer_manager_v1 (Note: These extension options remain in `miriway-shell.config`.) ### Working with the Miriway snap If you are using the Miriway snap, or might be, then there can be problems launching applications installed on the host system. This happens because snaps run in a slightly modified environment. These can be avoided by prefixing these commands with `miriway-unsnap` which removes these modifications. It is safe to use with unsnapped Miriway as it does nothing when not using the snap. For example (in `miriway-shell.settings`): command_ctrl_alt=t:miriway-unsnap mate-terminal ## Advanced configuration of `miriway-shell` For simple use of Miriway the defaults provided by the `miriway` and `miriway-session` scripts. But to enable bespoke customization for different systems and destop environments there are the following environment variables. * `MIRIWAY_SESSION_STARTUP` a script run when `miriway-shell` starts * `MIRIWAY_SESSION_SHUTDOWN` a script run when `miriway-shell` shuts down * `MIRIWAY_CONFIG_DIR` a config subdirectory used to find bespoke `miriway-shell.config` and `miriway-shell.settings` files The `MIRIWAY_SESSION_STARTUP` and `MIRIWAY_SESSION_SHUTDOWN` variables are used by `miriway-session` for `systemd` integration. The `MIRIWAY_CONFIG_DIR` variable is used by desktop environments. For example, `MIRIWAY_CONFIG_DIR=lxqt` will cause `miriway-shell` to look for `lxqt/miriway-shell.config` and `lxqt/miriway-shell.settings`.Miriway-Miriway-854d43d/LICENSE000066400000000000000000001045151521360756500161400ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . Miriway-Miriway-854d43d/README.md000066400000000000000000000075031521360756500164110ustar00rootroot00000000000000# Miriway ## Introducing Miriway Miriway is a generic compositor using Mir that can be customised to serve the needs of a range of desktop environments. Miriway has been tested with shell components from several desktop environments and comes with some scripts to help set up a variety of example configurations. (See the `example-configs` directory.) ### Keyboard shortcuts using `Meta` and `Ctrl-Alt` can be added or amended These shortcuts are the defaults provided: Modifiers|Key|Function|Action --|-|--|-- Ctrl-Alt|t|miriway-terminal|Terminal emulator meta|a|synapse|App launcher meta|Left|@dock-left|Dock app left ("Shift" to move output left) meta|Right|@dock-right|Dock app right ("Shift" to move output right) meta|Space|@toggle-maximized|Toggle app maximized meta|Home|@workspace-begin|First workspace ("Shift" to bring app) meta|End|@workspace-end|Last workspace ("Shift" to bring app) meta|Page_Up|@workspace-up|Previous workspace ("Shift" to bring app) meta|Page_Down|@workspace-down|Next workspace ("Shift" to bring app) ctrl-alt|BackSpace|@exit|Exit ("Shift" to force if apps are open) These (and other) defaults are specified in `/usr/local/etc/xdg/xdg-miriway/miriway-shell.config` and are copied for an individual user into `~/.config/miriway-shell.settings`. For more details see [Configuring Miriway](CONFIGURING_MIRIWAY.md). The "@" commands are internal to miriway-shell, others are commands that could be executed from a terminal. ## Miriway internals At the core of Miriway is `miriway-shell`, a Mir based Wayland compositor that provides: * A "floating windows" window managament policy; * Support for Wayland (and via `Xwayland`) X11 applications; * Dynamic workspaces; * Additional Wayland support for "shell components" such as panels and docs; and, * Configurable shortcuts for launching standard apps such as launcher and terminal emulator. In addition to `miriway-shell`, Miriway has: * A "terminal emulator finder" script `miriway-terminal`, that works with most terminal emulators; * A launch script `miriway` to simplify starting Miriway; * A default configuration file `miriway-shell.config`; and, * A greeter configuration `miriway.desktop` so Miriway can be selected at login ## Pre-packaged Miriway Miriway is available as a Snap, which provides a basic default configuration and also includes the example configuration scripts to help set up a variety of options. [![miriway](https://snapcraft.io/miriway/badge.svg)](https://snapcraft.io/miriway) It is also available in a variety of distributions, notably Fedora. [![Packaging status](https://repology.org/badge/vertical-allrepos/miriway.svg)](https://repology.org/project/miriway/versions) ## Building Miriway from source Miriway can be built and installed from source (without packaging as a Snap). The source is available from GitHub: ```plain git clone https://github.com/Miriway/Miriway.git && cd Miriway ``` ### Dependencies Miriway uses the latest version of Mir available from the mir-team "release" PPA: ```plain sudo apt-add-repository ppa:mir-team/release ``` Build dependencies: ```plain sudo apt install libmiral-dev ``` Additional runtime dependencies: ```plain sudo apt install mir-graphics-drivers-desktop ``` The default install is minimal and provides a basic shell and a default `Ctrl-Alt-T` command that tries to find a terminal emulator (by using `miriway-terminal`). If you don't already have a terminal emulator installed, then `sudo apt install xfce4-terminal` is a simple option. ### Building and Installing ```plain mkdir build cd build cmake .. cmake --build . ``` Installing ```plain sudo cmake --build . -- install ``` Now you can run with `miriway`, or select "Miriway" from the login screen. ## Community * [GitHub Discussions](https://github.com/Miriway/Miriway/discussions) * [Matrix chat room](https://matrix.to/#/#miriway:matrix.org) Miriway-Miriway-854d43d/backgrounds/000077500000000000000000000000001521360756500174275ustar00rootroot00000000000000Miriway-Miriway-854d43d/backgrounds/miriway.png000066400000000000000000017304141521360756500216300ustar00rootroot00000000000000PNG  IHDR?P,IDATx^sGo$${׶r-簻rT%YsAO7)RFշPC)z!KR[!vNjtv:#\Km]J[ځ+${l·vxw!t凶tuwWyq<:ή\X_"%/V{G w۬w'ں]!3!Ō8L匷T5^ &~ uZZ{RJ$jc弰:z/ޝjJ3k/Ib亝TW^goݓbMsuYMqLOo/g-חlݞVNӋK/%4/!sN[S)͑r<ۖb</Y# #G(t0g2Lb!g}6Ш444tx+W1k5DM@AhxF%zƪ z&zƨn5Iv .N9/\]+3gH!\s%@y@S:=K EnJ \MtmF:-AW .ȼ^rB Ftu}SH3nQGζDk hWЊ-D77]#jbLSM@73zeZYQ Y۴ 9:o:HNBN .hΖ n}zc5ZfKhKD:tko[=@ V(i+Z5XWa\_Q@鯯hŚ.:Yt44f=rY zэeK h-t9V f4@S4ӋjW7ë:|Ql3zҹ7hjhSw~ ̀͠M4msML/ˀRW(qڵ.H3"%=_5:fDNw礻:вg"2h;۝9vT z&FC@ @cРFM [u6t <޳/3MFOn %HsC*r{gXt̥+Xn툶tDY ]7E㊙dX ? n#e,4/Vj{֯/ O\LwnE-%ge1iЎ hɖw󎾬ݖY^4n`k$Գϙ:茇 JA3)٪٬@3e1\6\1t Fo"'Ӟ054й@%O<å躀^!3Xp+-43m݀UKۼ}W+%ݰB:VHg^ÛsvqR4 VSjdS=_=Ou@C=_IEgTto^}f;ۃE.% KVlw%Z+U"3A̸N"Ve3~mL4` &^ @W{ Aޚ hv &n$(gܸZЗ&Ug@z^% k.4ݒޜ[G8C զCnkEV6S7nF-l,>4%ukh}K &~e-n"@C:3qq r”vqRC:OSjA2^VVt9 ]~I$׍Fy ,y@z~ =XvԈ5t 蛳}7gmtF-k3i0rn)0t٪#D.4r-{M@5-k &~-zz+}jB3;=iD .h.M/+Si J`G>]:9H=,I7\7$zfMv\=hPrx{[@̵DCTtpCQC{ CIO@h&EfE-@:W nhZfPvBGih8=Sύ#/L/L zF@T(s:TϿ*fqRbSD @^1 t&hf+Ad(i.bb[G`t CpZ ۉdǛț GC;`vECc؞xloz>ςⳌ˜˼7Oͻ7$y0 xzݐAGAw[8ܿxȣVR k2z}rCr1Ԙ|j\>=WNg'i9yGuYy}Oپ=@뙀6}7;:X=?iu=ի hذ㣚h3=CgT62dC xy ݏk  u]/n"q2cٳU'gS3=KOЏvT]FLи|p`M}ԋż%VX/r^HBs4aM=7x1GQlwNY; Jй 40Kao$)SM?Y-γ>欙;KM[ Q=\]:@?].K/9-.:j`}oIqn9;Vlz6kZhc3n5f=/h_a@1o"ZqݺGo(V&&L˾d@:fk>@˯ -zn뺉Eo" ,@J@UQ#Ԩrj <&g׹ HΌJA5ؚPtsjܜn$/\+9oPҹd7KPϮg4g2Yfl^# G˖,YL\;])n h\Cdgץ皀6lP@OWq݀n!3x.u-\6fnbVLa7RWtvye1[^[G]1B7QN"[j¶1tEwrkZn4cx$$~Eݮj.r!\mfX|'lKloO)+Z3Wy!fzm[h{/ٌt@:I.GFq!Q\,E@sӳ>eȸb czr'F8݈'世U=d'z$ $)^гXL3hx)zhz7!D SC G 4h3xpW<@7q9%BDC 9-ull͢^6C~C^:Τ82Nˈ>5,s9)nlB9?0]KZV34| 6Fo6č7gyD^ t,}-9b/:jlto%d`fc.6bnlN.ѹܜ<]w<3ƍm0%=$z_~&]Vg5X4ogwT.Mk+t#5]&o-xU{Ow5ڞl >_/ $ OJG3cB;;2g hSH|oLãt}ucu εYRw^$dvo`przu2cZ=#g4r-VS*K4=DЬC&ukfΩuZ3ď]߶R26hd]ډכ5MohՑ)71 KΛhי 3-sh1ccq嬜sc t~\53'8yi [) 2N*WӊgL;s93=O.l=\=^=esPne~.ͨj 5m.c ; 6^ϋN2[E@*ZY~>+zq1Ϩ碶U/(f Ts@B67pkh44F=wtn4kX ẀnJF -v; [Sk h}v貞й2e@Sz~6O"J@ nڢ4s@va h4[BHH@7 V@J}:1=KqZ8]/3Yբq Dz:;,9}/ٟ.:S]/ ڀƃsX=[ڢgE'Цˀ.4=l%'gi@"Q@)}4!5hǍ$ ֩vF @*Fp`>򈵒䳵?Y`{@3M'r[h14֎ lvU3FNҮVkG=n)oWEIH((OMɶd+z]IoAq^'}pFUC}P]{w1SlƏW#GV{ix^}S1%M躸VfDƔT,ޗMc><;37P\nl_ ^fA,V\S|}l286k}HjTLnJ4NHS8\$)HH8❒ّGp .BWt&Նϑֳt̺9h +z&;)4úiI)N# k%Љ~4"N j qw|L'x{$lTbi>Ж=ވih3Љpl9C!L;77P_8)vEh\]Q04ٿ7%D`N?N}??S=gx 9H%eozJ46Ó@~lvtÐa#q34gtn<[##cqqf\a, ͍rQ2%]W |eZxaukݼDɶ#t!z*\?#\CkD1 ^{2"]H'XqP!ԍqZД,wD JHL{_֌#Y'ѝA%5v/%A@ÅO96-%I14Nлkhh344v<4-zS7f=~6@JJ3-a#E3JFY5Uc9-Sy) +IS=3#iqތb&.xFоy!gYV 4ghC53W0V( RLwB hW8;]`tD/ :!c9l-x8ӏN{O}AU4 @-Ϛ/TѦ>7\hޣZ N Q$:,6ZB:s6Pc8yR2])ӡ<$B]m#n!N )нy޼BFXQqfܘAV=.GfhUC<6hv\ߞC.1\Z.:nB%ƜrQ)zQe3_8nؘV咼RVfK15Z CH|A;;]3:=Ry@{@[ ]e3hjMtY=D@ b~ @54Yծz&wL>?3/zV9@g-w4:zIf1%Aܹ,@[,,W/? y?=#g_Gt=qS=:+ΧǕ3fܪG hgr|\+Nݞ{Z+ SSrݝ{2tA(?X="Gj?{=@_NvJ]{Ƶg:kzmΡT@gԳ۹&‮Fg]pKD`JABuQw.ߗ1zSТ7|[}@-8@2nUb`⟡俠p-ko;ĮQ,+E^ @ nD@8ati3<QܳqrD;5NB*N#ni\I풞z $nT3L\ހ{7K͒| 7tF7,W34)nn^rAMCs??1}h%g3:uz}(_-*lHWgq.?739왫@43op^:[M=e/Nɛr3--] 8DhK[n+a{~@Wxb.DqtÀ.btЯ hpt,;Ō:ch/39y>n0vt5>3/杂ڱQĨ4ЙtfTQURGeg\v"]|J:q,f4ٙعu[dg&:I1JdrZhWJjУZr̝n0=g|Hg˔@3Ʈ@oЛ?#MBoǒē;خd|w*'P=W@cWPʋ2#iH }Nnl>C?,O"ţUؾ$'{7A?Og^g7lzNOOOCͣ1ܘ9ݙ̧Rvg\r6Tvtznp:Bg2΅ { GKU\HgQ&6K NjaP p1qBĴ{d3h|:탴Y "hs8vi3q[8nj/ } иZ,:߅L[%.B ~~eM ];É7HH(к9@'ģby17_-@6 Шg:S43g2Y4)ʔz*צ=Ug٘L'\P%R9 ehcz'lQf%hT8 Y,wwQƋvwA w@+5 諛L3@dZ@)Db-scWس!n{mDS' MXڒZ/;#QOWmh =#]Ӿ ބ-M@FChhgڿ @]ЩDtFt Aʇo\@6,U±~@~!6pAQ$q3=kg18V|iMLFPgA&l3 \u=ZIt.݁ؼd`I.3OɎrOEA%׸chV=4"xAZc(Cּk GÈ;o9oΫ\T\jQ4#[88@_(s3D@fSSIsnڌ4 "`K4%W]@sڬmm_S@dtYM@oz&enzs@'o'b$R 0dL@ #~w&gr@71ω1ܹqv\;MƵڥ }ʔyuRWq3Yx ,YYRoqtNK2yY~z3Ďfv82~z&zj@F"[mzU3q1^ۜv@)ltdzn}Ҍl4hAʙRЧS*B7nѻ<rCM@oz"^Bn]S&Vrok7E oJ_՗f~M~-9&7ІВ#r4d @&d@Vta$ż@FoGTAϣS FŸǸ.?izI}X5$yAr@sLO. aV/fxƚ(f޾Q6 ,+Yїr;FlFC@çpG9-Crٓ.{B'dGR) ?&yh.,BkvL@3=ܛ~3 :oQ)ZKbƧ$$,.2- 'xg&'rѬ:s =N )Ĩߝ"M5ϐӼihhhБY:vڼ ġsBѼPfqQwc;ф$)V?~2u{|čw g΍3:IгZp_:OfߠY:yV9*kPI[+;sfޢvo^?Gfk,HKғev=b۝f!I,K/]1/afv6rX7z;F \;IBAGmpt~@NHA([/JwЮ]<377\極9^ VIYr lv W!}ҳJ"6jQ\R"v(]B@z #8@څePlntƱ |WUS|?TOk:-Ņ1klT^vIw- Qk'-&z^6ܹ*`.kWY6& yZAn-Ʊ06VmH[Wyt7zIbx+щuںԝjͰeǖtf]^ͱ7Ek^ة[Þ$ :nKqBxko(֛5mPA4hq}S@Q&;t{֍"Jnl,(Lᢟb_SPl3&ܥ љ>[-6#}hsHj{'*o8*<ڒih3%!33d^T$Niȼ2tXJA!W.QtFK阜q%W2蔒`KI#5i)99WRy>/T]@k1h$ذFYN hBKBd^OyҴ'U@FSIǧi_`4/Z"`Qc 84z9 ǍFpd{8F$F$Fixf4f4X z+7N2+ڝJK$cԁDO'Б}zȁT`2z09'Cx0> NEMGKMGR#I Kxga ww|uQq.}B! >Bp,ڼ`?_ y~3f09;:?`4C>aþþ#S#ӣؙ11}ۆ1q 4IG;ㆍ37:+7fd:AntVΩK 9yǓE׳e@ve&5,$(aټټ)n諙tY!D{{)utD0{G.֌LCHF@\r>XƢY?Ū+%mڕ9墺RT.e9TR rT^\iܴ ^v-N}gӓ A' [=hB@Yfhufϔ&oBM ^=u*3zFtnOhO hFCM=c/ м@5h7,~j]f M?:K 1h4 t4Ct=kczW*7ߗ',ޗHM&&RDto"=R1 hШg3p*n:^:B< ҉f$qw(Cn =oBс(6::a.?ɪ3ҙ̨(Йb Lhɪ,N#7Z6T.iݏXcբgR]@$C9@?^ѓ%e:UZђLNћX:vJ>n͙nXcs`cv]Ћhmrt6 h/s5@4tA 4M<|tKw|y,ow Cu%y&h%{j5Y# MVmnvzk⿅K,H&nt|O:'ߛJIehxNI'{14t2?h\xnB63s&q6Q zPCA+ǝPǡþdφ؈Ĉ(vz{nnF:O@څI)R1gNTϸa 6nHۺn~_VT4@o7VE٢";45zip犀kLը 4Q2EϳYvB¬|aV8t3D[h:Xìâ \vK/Ⱦ-4Fj!v:40ΐlur\u-&*SiU=lims5j-xv · *5+ L|w&tړcjO6' N$ch\Жt @f6cL@3zhwg(Dq(t~:<;zw_@I7rHmu, tmܭA茇o,=\Rm@OvxpS7C4ϖ$'2Zdž blZ7nWЫn?6S3 s5=#lgڪ<׼@^@-}$E(W tnUL|W6+ߕIJgݙlfw6;ܝ@w%=ľTb?1ڬ6?>rA|عj8p!C3tw< 8il2t>6;1E:!}&N2+fhz@dJ-Y@wA o8i8.<{~'t&z^ &ՕvG;k3YjQZTx` ܙ کBϠ7wמZ47ٲ ,=C/ rZG\R}@ӑbeO/w6bt Ǎ9h1&TY.V,-.9L(ϜPNOg&OC [(%g5@WiKDH@8@ut4@7m.H5 hxMY nj'PB؍7?* Ϳ@t*&5N[/P㺉oes7_:xÀ5mo\ Z0t\:in5@3re@;htA-=7T^JB' Q=C+ڝ)O 1Wtй.dymY[[wӻS{3r0 /ܛv0tj}t |f&Y4ר!A|@?`8y}ls<==礜Ξ \xP.M*drD#tSnEVI^Aw{:qz,=.=!@ءӹg{c=ʋٽ%\YR=@ nf֞7 8ErHggԳnː "V^UA̯ ^ Y@wt%:I&0;s.kWinYjڄ ӕb||_Qm-xb]< 6ܼ)j@&N*G@/ni@htLt±'ޛO@@ܾLf_6CPt[8~H.}}= =z8}7D=~ 8i1߯c^gq ӹ'pgeʽ2%CxBl9rKg"݌ڳtDO&?v|;pFm@{6D@"H~]aHd{K.&cVܜ+UN`37=<>1Yi t2 MסY@-hhqM_dYZz@cm+-jxDxooenhM@[M'C1wRwR]خTp/@9ڗOe|@.{9 и)f7oFߏ  8y4qwl{Nzs8\`Ղr _QuEFI1gN T~9K(PwxR&GV=.D:zn"Zu>>CY?zڱID@}}Em-"nHڛlK [@u+`t=VK 躷 ֽpM1}\7\eI?C \@׭ 4{71tJtFK=D@CD ]LwЩn={@ͥfshs|Lz_&?b誵㵟uW[;3P*/i\#D^kzE^s3 yӹhhQ\к:nAi+cWa,?Ŋ>x۽m&N@w/ap\)s_:4CgyLd{ZgjEvVtQ~g::M :!Dh3:UILN͉#8@)̃!Vt)DXЦ~X r!7](;ߝL!{xlj.F@gq`ŁFCt`*z(~7}7@NLLz/υ#yZ!]П(fhWp1j }=}7a4y<tuG?9=5>3= d3ѳgu{e}mZgtvkN浵yz{Q(_pyxu:˿Ҳ ?w Ve()y%g@3ӝ%mfh snƭV Ћ[2tD/knK790tO..9LtZc3NƮUrܠ%^2 h~LxLГu:k)r _'+?]mmʶ6Vȋy-XW.?fg&XJWȲ\HKWd[wx[w<x݂w83>69Fxi¸4{ƸSLgn[_ uA|V[;)<跖o-ړe`s8lI#zފy8 _4iOw:Rl™vGFn]Dn N3wƓŬo@;}9<vy@vG͙smƀd4 Gyv+G ٞSedgR\)Օ֌(=K%$g3123#ȑlUĠsP\b(R?@/ɜ/A_փ8#~=v(PaOc@q/^<=1;5?3;77_,x.Mc+iYz}kV[m.*Kʝ9roA(?\_qSc;%qU @`ncׇNp'^O>&&C г3t]pφޒ@1s%@gLvo6"{1@l̦eSCt0D:֎Lz?x?' t hfˁh#_AB  Q=tuɆ_Accs|{;3;;FqhWfп7nYNQSݝ eBg.yd'sY ~EYX`|sI(@@k5eڼzmvuA4&]-+VHfUgW3SЬqI45H/~64c7~Р6#OmU߮p[3 {{mAU⺵;t8f`A4Wm@gm__=Ȳu8^@s nz]r'ٚ^dܞq>~:>|oWCѯ_G|;n nF:2e,xlmw84I$ee7иO2j05y$h#aHLV @33S\u:Oy/|}+3ߕxv_ǴE,3 nϩ E!yIy>ٮgo(@T?T JZE $;՛K* Z :"^mmѳ h]Yυ"*܌?v;W+V'Yf֎O*Ej5h<={DsY4ƾ& hf3n h$˰jۙ_N]~D='YεP?hbhȵ 1[hq.{wx1 _"@byKm^&OМ_m `&r07v34ӱ%YɑtC;S4GJA: =S@ЩuZ?.3<(ђе=^ pAM\Ёi`%@ts5@S4Ӌ:@ @=>@?}""B_ 79:9 t 0a$h s||"tb"x Ssg]䌫 K}o}A{0>\ЀΏqN74#\{+GXtj.@6L-F1@/Etk46sthIjIR^-yP[)zVfiK E4yl>OBD"w K fݰ{6*AF̜hN@3Sa42[ZL79;ty1W f.nƃ"k$rYL뙫8NLLמE%ר@g\xЎ$5:A8C¤>R!@C9EUt4'E Т9@!%Ehd/ Mx)3iOd 3z6-q83pbg(3IQ468we3o0jh]=2rxxAf沇r̻3Qat.q.&I>i| 94{#{q3qc/{ű5|y+ $ir9(GHDtNrƀMv>U==UcKo~{.2 {6CgyFїgu\@/ - Alc seY\ZkOM|ڕj[`z]n^-OK-K:a/ ڭhҘ%QiI.Zhwh<VՔ$2YK7$S ԆXb}4!6D" st~|v~v|q~uٿm)~r1ʁ z( rɂW4\ n.:WArn>~?aLp\xRx~jZL<^zh}͡Cekz_ WHg+O XpYx5Q|-@F)vTA44r"gikwt;s#,G0Ԕ3hy(fi2; 2sbD:Qi818x@3c!DJOJFb~ &AϪxvyРgMG8(gh,[+8"bDz]" ?7`Drc9>8?vŜ_{$ɬ@sR{_l;])~bbxb\1^u:n n6lF:?фNd/^|G8x:ϞGX#@Ӈ[89wӮ=ˆA=QZV#13#PW6);5(Ϟkz;S64 hG ZbG (fJga&iCrA~N/ۗje+t{\퐶@ )L4蹳' aE͢\熀f`ǦzbRNݪSdŊiǠBť#jo=o [hQ>߯} WICK\iB!Fcbqtf}"!Me7sTzc:5nxE$׶.{vA>`: $ޕ|p;'C)pƆtY}Ag<{.ZOm_,q۲BrbT1_TkF43ww#:lTpLh\OAu? @W 5*R=쁖ƀV/JPppefY{6B&4 };aC,4.N/hŇ.%iP΀3Y04> 8@#Ig,fj @33.O\lvgiI^ED@wv{;;t4?H)Rve'):%mY]!34uZ|?wzM'tx3M`熀/lpyp4PYD@S=CmzY@ {Uhಷ!cZ4}0j&.#|i@\#oi2B a)3kzc:?-lҙMԆX|}$: n$߶h79vm\{a{!a1Iko¹< ؉-#y˱YT7(Xd9[i J|3]M7¬a=yp#FuѾGc'v^1^ϯ K5ww@ӱ#!HCg^>d"}jΛY@_/T(l %1sIG2gJM&4LrFhzyO":fjSN-Y|hy>^3.ЇNsk;BEaV8R[qp!InrIjrb'yrut'rB-NV;vF^jYl]j[n_i_hvv]n9&}iTֲx{O$v(+-c,%2nГIv_5YveC֩RC*v$aa1fZ |;eVdD)|h;|G񒞘.tTaBB6 Zr7I:x%7WU4 ?kz֫Z9J^@^Ƞ> tVpIw/)~ԡ :w{ހ/?]V5A2AO]x hW-%<l"iHdr4Wُ7p$HVϐa6 kX3a[ܘp,Ǝm冖A^h׷נ~L@rfCah{}/RYĒ!tBѵRٍD|S<) o7G|["ޭ϶{GԽ3Cg{ػ=vF;1Θgg^~aqY³+"ړrK9C9Ht4o>7ϛNMK3%%~~~\1\jUíAhHf1 q 1kҐ}OF#{/ւG27 GD=IGMZd@8h0շ7tڠ:&wƉAeҥ%l]0\ߒY*7\I;_MbgK/K:ig@d)I'NO @LeA| &}>V G y#H'䈰uar}YI9# Nr@SC3n0>~I@ yEc]s::ݒ AϘ;KPRWRXBu"cږ}B*^,6eJ3 ͡K\o`rC3+@d39lʴ;IeZty@KO@׽KKfʋxs@&4&ϯ!eE54YM H<YO gM>߫ &hZ0441|={~I54 ^h&bf}OK&o А TPUhya;ZA=r,Fz@}#9bǭ|g$yLkg_W坫褝xЗzg:Yr=s'zn] 4y-9ۗ5J۟3O5ru۱ڭ(w?mTK}$Xv4V!qfSZUϩ;fbq77KpV<#3W]C=/Y hT b& h-z4 gxbf3tz6M7ƣļ#ꁶ G#໱лqqq1ѳٽ;ړqE=;PyǑX|h:^4,NAe Uu|;AzwV1}?Èz8 =G+?}^ EѵIk_"=Эݮn7O%i_k퉋愼d+N9kSP"&EX7(ĉi1@H@3M=2C/ÉoJ(4>uB/ Y0t0[ Φ7ShhS$8 nmqx`{,# }|p}pJ4u0>C=h?Q7't7X)/ Z. n n wF wG3øz6>>{>}>|z:lh}|t PwFu$m[g&43$3}Oa |33|j8;`e Lpܳ-v(T& Nj:V]$R'0ލ?@fY^L{z.ÞQhufy.pq@C%޶~t@Dz`PDzp'nވ#M8∳VUZ^]mut*h;2=@g8.qbf:ށǬPD@M/ Zo-+4]1?M( M ý ~)%BuP@Kkt(̊yQU"\m|I@C'6א5:/]hjh_Ҁ6 ܆<5tr6lFb-Ȗxhk<- z|~|t}tN9q|8<t[Nj6llM+*o Kg!˕!3&4l3t;7z~lx8a|2t!ljk~6tƗ{ if#!͊{cI3ohԳjghgA<~0r 7S@)S@\+r}A//ꝩBz,z4vNj: ,K܊Rڄ7LA@:@I*o&ntk:M}L?F7 c:މ5r?0Zjnv[B܌u ua|M3S"բHkUfԮ up]Yl{2 )˚AR'H09q؎-7;k4h2 z1OyѺwP:,l @LOz[`Y4Z*bnhY}0D5n=^‡JAmR>+2Z$(f^Q7- K7ILVn]o'dr-lNbF7]3awM:\Zd4䮯rP:/3ĚX14ؔ-nʗsk uBv۔nJ6'ͱhl.Cxxg<~,a,IyEƻ'ޗq:Gт8zd=o=CƝ&sxڻ 2]2"tG:OhԳ~,39֐z<iyHNy@׶mԫ3snk!r9{5h5h9 T`e`f1. PmBC 3Te,ԂfOhcfTx6hm>V:+cڟ1K)#'i3~6I]&M'h\/hw@,4@`"sg(3ZTY7mtX., Xw>i{ E/tO`H@[ h^ϯkեRa}0[‰ܦLvs wEo'7'sDd["3}7!J{dol>W,%3Bytst3nDoLz~@=?ГO'&t&gԙ4{(913ޛI;D7u7t7tu7t|αn R=@[ZX.U|~"|*ˊtiE~3Ӊx4㱒,vX!cx7s9Px0cX.e΢ hs^ 3t y<@˸'}P!pO h;玥R}j[j(-X"qKbIkUeʜXBٓD#DZ#0tHͦK'11u+r(+o #drC_h|`eY}H* 4x*kz&W,~f.[KZg:_)֔KKK\qs9Kf璉-dt{23{/ 8,{9hv`?Yę +=#-}A"":!!#֨Έ<L?.nݓII噐db~: 'UO8@&ƋtwZi`j_n[nf; (rOmUiCe^]!уuB !k_oP0e#\8;UIY|@xFf@4zG|h=V;]lCE} t~w(k:C=7jݒhhIh1=0tx3ve'lf1! > ([[:IDND@INg NWuc'}&͌pBsxڏsciCL<[ Ϟw#-L*+Kk&MoS) )g`2 BT:n;vܦ@)PT15IF' Y̌dAg:?Y.)Dnn;*X3"33w R#\-4gX4ٿA>\:{X/q POn+s^OX"RU !вQ&""M  S;:TВ`V)zҧ#i*A7HjiQu ZITCZuIC^4_7iaOHGK(y@ ޓ0xF_JBKi'md 7 6ht)G-К@hm0 Eֆ#k#uX|m4.\OO6$ҳtvS:9!\aCq]\P.VʛVRSTzG&^&~*i.;ڏz/N'gγ㫪 ! Yo [nXn3ܟ0~?iappp@dd??4<]y2x4x u=>:AEDh1=²1-}wzIfRctw}C:i7 ׇqCI@w+"fi"7/ds}<$>3Bl9U1O-1y6C_q԰IXD>Z4 ?ڳ`:sؑF. C t``<76fnYgڞJb{)tKڝ6JY>OYwlBͼV;fżY ǐ%kkwB@nsnKmZAR}ij[o-vnnf %i4x 1nX@K7ŗ:.UV:]r]7$;MJIDAToUCvME::zpS13-qك -u'OOfp,t= ?MZ_+=or@jhMA2)B4N2ƤFCQ@rRC qK陴ON헆gT &hք̽!4e. ż}~&O6c=OBްMc>3'n_zF_F7f^04hfo*/S6`\Mn"[sqFYҨ9иM8Ф;C=^v-w;Wx\J[ $M=`dM(*6EhKSЦdfs*ܖL~.X,ΖKЦr?ms U+sʶRek%ۖIK~^)G˾ɊT}>7z͠". Y YGGwLߍ:O! O'g H kSIݓ)|Pth=AS[DL4:["HlhHto3@ÃmЭa|YPR Hm̭`=FXAk_@+A_6rbmީd([e+~Y'Jh"(YIt6KC1c;{tļ/z4e>K>i;V}Ь_hAYX qW]cYj7:JZV? hhCIΤ&Pf;ղŝ@/TjS%Z&N;0z^  mp2Dϯ ц8jYY& @̇7:at'S:=<k 躞-лl\Rrwtp9p;9;3=Su9>7jͰ°҈ʰڨc㖻{¸3Yxd=6>|8+q І>ye#wq #gz5-u5Ϝ)/WjpgxϕMsNWd 4@8@˸̷@b:/ԋ-_@zuO\ܶ4(y^n[ә\CV;Ϫ$Y74|ҩKcbfy1a@ ~wy=Q@+3rCUn4] ͣY^L<@h&Z G8.GX|66%S8@[2ٹlvS T*l/nʥriKZ-C;>+f?*&vcS3޳CsCޯ=ߎx..:ڮYoYn[nAc;LLO6<\nxBh1{2:k74t”Mܑ^ h{@ά倦FCK􌀖YX|mtn#ktWYW[5Ȑ0:ۙMdrd"J[uka@ h6șe eٗXfUt))ˮ|^LOtkWg})n_!E{b( (ժfg'P@,B0Y4UNeIt2ީ R.p{_ h2*KUH)VŴZ 5Aȹ7(ͨ ~`#@GбE:T@ϕHg3z@ygJGO]##S#3޳ÞCHQ1ϕ1׵qǍ ۭ ˝ Iw{ӆˍ4>^exRx '+ Ϧ r@kqz>G[=?%2F1J n l hAߍ u0[C}777 Í#tpH&4/+q 517deex?zEKG* >9v3{5r\m z>$0|(|(q&n24bfj06ҹ҆+nd fļX@5vx#e4к,غ յDzbF[OZ@V aTCm V k1y]P;4NAZ(Ѯu3f˵D3OE{deH3iȭB"q!X9O?f)DLKdm3|$sfiЃV';yFO:}Д N}n/hJgi W|~hu00 Bk!hm$ F(!Mġ92-\>3WHo)fJqg@{ ?./.\?1;=:;j¸ʸ))ì+g33'>=Y}\l4V~6nF=~<}<4{0k8!p@ P&OU:Q#zD4:Rgtnn.FIKA+$mٳЀfi '4Wrbnh~xwd?R5PvYփ s޼}xl݁i_κ7g'k;cH[!~[NghS0jݓ: hjЫˇoGf`I|j[!QLO[μWɼ_}P}8XhP®+gV\>ʹr厫ӎۓ;Sl[Xa~djӳW~?\c$І3'3kؚlr?9DL<=/hLwGFnF $t3yȈ3Æk䆔C$tejsuLG2f<`ڠ3E9r!R @gg:Q!َmvrf=h,I}Y˞Mn/vW8V>}puܼ~1@/ ,C:S=*@ve]"EEkUC+GU-y2Y/GU.ӿDgb]SkS+uhd3m CR%Bo-~7ż0u_h &5мQ74UXC@h41LϹ4z{YJ۟z~p `'OGƋ{ ̟\ru7+Wz/r_[弱y{uwr׽+lWX>]ey/j$>t&'OW鞭=G@kH 6 ڄ4ѤvA@kDCr hz-]2`˃ +,k]θL3DI +33~sb}hd#nvҎт]ڑ} c)}6Z3U:txeĪՙ3offg|f<7f\Wp[ṿJ+mWٟ؞X~Zce׵V~_mm/k?߲<_c~t=_m+u?Chh@O륆`>@Tf}{D{sTG5@7Fذ:Lk=/ez= - X6/z]w@[陌8؏WDžPyeɒCx&hgp΋sZkh4^R=@[pB)z4a@3z^, օׅ-@aw 6c]-ͻax@U$dt[ x). K&:bn.; Vk``wX2ъ0UMiS-J(תōqznUpX[P ;^p G/OP>t -~=6M6!<;4څzl:k'IɊY(U 74vMSR@nj }ߍuE=wr8VOhKw*$0?li=.@sNR!ԹX@ߑO+9/-[Y)LQ+(Qؔq N6ZPJ?!%5D&٫o7i$MSUoh!MІS|h55> ho_c@xwjB:o-xԪZ}ҫ+8 ^tBi} #eMG#zYʙ97oBE!o\-lJ#W|h@А ghAc<{GÏ?h\w qx!wǷ]ծ&Wy G8hpp]$>\@7Cdxc29Ķd[m6~Nl+%v'-ޯ?>|uf" iĴ&텂b/(MGΤd*A&dӄ';&zCKi|~m / B@@"@QPL kac:,B F?0⤄ ~M^X9?o* J4twZ=Ѐ+6h :|C7lB#6psGiϸ67C] w`_1DOOAϠj*Yyo?kAZo:cx`c")ڜ ϥ#ll[.-VHl)Ʒbʉ{+OR_ gONNNgNH]zN|&L5K}Wg}7zoo}woZ뜏9/덿^u[gZ^cmjï Zjdi ]ss^IOGhIiiI|0=20e~VքD$-zLTwo݈3351XtuX3tu>1O /Cd`Brbjj%,֐tp\:5+*Nyrn;`h އ;X`Xq)BHEr-P& Kv}E`[νy$מs=D9v yy뮜elLg2])  -0}}%&d}tȳ3{9ez6chrnrt@/=ۖ[E[[zQ$LNk+x4@횪WOg +%ļ_s1i@^:ޥNAd2 YNztk ;jccEh҄M[@z@E:TR3#q5!,uZtZ{u_O6-Wh<[0 n h7e?vb81_ dyЌC~гh3tL%ޞOl/$ >JIʟΞY:"u~Uķkb߮ ]\ufߝ{6~>iˬYӯ7-1}Z45Uki9@Zg)khCІhhY&tTwGp?=o!M7Pς))z2^=/˂֨) ڥo@z]Y3F-\%H7:\#tF=l5@ t>Rӂ h 2@zιvC}sbyy[S=[ve1qOg9@O>M:ٙO8¡{Q@Cm81o4 hv}ݞn/;܆zM-=u=R-4\mf[U%@F B9߼5>~Ҏ3WjEcћ2F8U40[@FCKk14I)x_H:K*TџP @@%N cCQ!'"i5CM: t l7'BsTdK:5ݖmw; 8'/{҇&Ǧsg@_L}:LŵW7oޞ |7|)æM'}O7y~y_7Z~5w [oFoLkIka^j?B31S::!#y ~ƹQrvg3ư:ru|e|y]&s&Aoy=WQLR= 9cMA_4ȨNk 쇋pM܇KE!ǝ rlۓOf9%I 9лrhzlbf@}g2 z!P>NX^ v?e7?Y]ݮ%\oG=GVg2]z"nM,4lE~n< y< fΤt_SӍ@v D(FI!1C뷀~Y&!*J MBO%4i:T|2+Mjw h&+|zC1o‰97E C/h?4sз&[@gc~3:ڒ oIG3؎\bg>.A{h `|P|HxtĊ왕+_='/_^>tuCƦ୹ݭ[Cm ?|5VOs7;dmM7Z7kCC]o;Hz鷵_֘tϫ z49p L&''y'oӍaaaUEإA%H&7ȸ3t$zvGr@۾,tC3SmC3|Bo$Ag"x8\@϶CE;&t}Ё>KrmsY'/DɒDI>K2>X$2}Ot 3,qdQ-@u[[E6znn D=#UEyj,m2qY}y^Z *a ujW%6e\Z7{=-L@+U1I˄ tVfU,i*'G )@?I* L{=&9vZ? C@8<x/~q@3ѳZS"9K[3m(=ۑ,$-BJʑ*Ob{FcG&ǧVςWƿ]&vymȵ[BwB~=d[ЏC?m7;~l&F@3Z"lfi܆3v}tu@l@ӳg:MuM_ sdsT.>qTDǗD2 &GitNq$qH<,! |({I znh"Q9K>!4f!gi;3n!^H?J0akF/ N:?i2 _g;eHc,زhN,2?nwK=Z[3깵'٪D@:ӳgzIتSŗ4qK#?-ﳑ yp 4M:Y^i&Jfqaײ8DTV$;bH-4]Uf1|/ 2&Mt3Og! >f~CL: x2PL t& eQg,nj/ҧƴ5@ij?$ :Kx7HMYl!2F.~1 C4NE1_T&4h!6Ilŭvdt:k8@evnj~+b~I?_BBg>|P!wq!1'Z]e'-h*w7:׆}y}Է!M7- d`k*=ڑFvccKKO+]1ȡȱ/W$Zveª5k#օŏom 7z@xGџvy-_\ϡNOK;>oode5O3d]4g Ϧ OOt~!A)a)Q)q)y9g08rh4|tz^?ygm_Лorwwhw37z@SCLп;O \<y.pkюw?=0t_~}МwM\kw$Kd3,ww!=!JB/ɹGь\ ;k}HNY'\{GGއ{=in5}o\[ޖZ_6\Z[k Еk!lFF#C gzΚO㡀>ե׳ݜn,3#Ug (f:+9kܚTnOo?΋?-ʿ.e`Mr&cc>fhf{;mR˖;[ +NndC3x{xr;pYu>izb 'l|n rx=􎾶]m;fm( z f2S+gMu\F@߮n&#z @flM''Ӊq?dft#h[kRӖz z=S@_"8iЍdu*SD'V4=~ h#P[QlnᠳN5w\@3ZLt0C: @gsC.$A0C=*ucs$q$f!tRDltWd `fD8]n;~~ts\=!84ܙI,w{y4h}2 td/&ۈnx; 1bhֺ٪4vk#}sVt!8H ^ÁڋeP=yDϸ3Чu> y~zSx7dOWsϙ3a|kOtbw2;BvлwAfF뭶PfYhY[8 .gk64}0ǒAC!h3:p$88 jlc7$lO&&4'Lʾ |Cü 㜌ch_C4?EC#]h!~Spg=l:t]w>?=s6_oancog.d寏7IiY9|!`1pQy(?\qg3,$dǂHLf9}A~ :ww;w:; (FeP"1o@ (gG2r" mTC7AܜzbHgu9!~GS3s$[P2t%t :8<ZRD?1<+,$?|L 60hhjL@ Рg}e13Wΰ YJ"O\h=KPAI] ~A2V 'YډhC/˕3b5z>-49 hgZgBgDktdz+x3jm:!i ШxYYlJ]WRn+ftU"N\-N<#>#:@̇dVYR-/ h-חgM'4V4ű쭒|U:h|U*.H]#@yM3ZK[6D׈ h:ڡ7~^6$@ZP&@v&@3@,429v A[yQ 3$MS eIlV&t4&Φ4M8!o?闾X/N 7:9ase'uoƄ<z -2-ݝs@?Xs =C?xltdh/,{Ά;VttíM9y9@7@t{@E3n{nwn{O~5=5m<ԋb3Eg Y_1Ut`;ҙ:wtoC ڸڨ7ڸ<ulX*t 7ӼR9eܜ v=PFg}G]IPw=d _E eܜ9۪/41ІlUڜʐb+3zAEv@SܽY=Ç/TWfydth茞 ڳșxơ0%Z1dA*mȄ:R 29pṩ L&@kz^А &E n.T〦W[.չrV^.u?xx:i:-Τ4_뒎wwH H_nN 3o2ߍ0v0wWvvw7Fw ShWb{ zA:gܣi4S0X1ocgcާ'{q4n(lumu?C#F@49hԳ߁1܋þFކ=_x0nN;AN>B@܉39^#@O:<Zf=MO)_K!lez>2.6'ù\F173z\Kkq? m M\6bOߟhbK:aL. :saY%:Gϯ }uFO4KU(S%?M@my ~6c1~qd:q8AÙfZNҊdY67RmE:P^᭾N+ZIDTRJJ)a6-Nnn~ҩ aF6vN}mw}'{s7kvgiByRe >@~(>ZW4<54xz۸qo'YCƛV~@C=:@7K;O=ۋ}LQw6?BBOG8q+p3^@ F]\xΊ:jq}T>2MG@'C.B9ex)XU1_t٣j2lWړQCmi Gsxhww4 ^vj58z>xm @ ^ o1>δ/{nC"j{;͠'Bym dvvϛ{Wjl1so 7ZۄLk塣iGGR, x}9-ܑ$w4c-#`Y]nf d;&ܾ&f_Ye$u>@3xP\,rdM.fl)i.3:\6g֠;U_8hŢ Z}9OZ \6:b6T`+K,pr.Xa)3thgz]YЅ.u }m FO'rdM wp92i㐴if$fad#`v`lRI~HZmug Mݬ3Fv;plɼ)~+ h \\,hG"f#K#F>o.+uFK"vgbd^ Rwn[sLCxGfh2W4;*M";^^,紪\<ڜh #O+V ])z*Eo%4``г Bgx;w}=ًc_4~ҙY=ϧ##13=6 <^y{' ;PsNoEP.5@ŜiiLgI^߁f-}ޗ`!8YF$!o^cVT@[r^=Cl3Vh z tg>ߗ^gL3N<3:DAG|mx3깓}G5wwȒ3Ix.R@knB@6Yha9uAf@nCyp(w$w0)9L m3X^j/h_CAx¾ HbҠo fY0tY{.$kϸk=CV,@~ŀ)rwXˬ@j@ ]R^%3>^tf4pΘt&ԾH,+ZlJ*Sh֛D"t@8?pC ;;g# vCw<&T@7 K-g~@!FfV{u;N?)=㽷  Q@CC62и=@:@ zAW=~ک^^>iMTGCu0:xA*x͘Kojio Zo Kڥmrii`<;":'RAAD~aڟAif)fY +@sEy*WY/֑gAМ("-cf_roVW ~ ԥeiZUژᒔ\=c#@A l+о }Dg{@39% zS4YV."f>`>d`Nt݁!s{&HVV z-gi^뭂g z.@5sڗo1r0 + &~JpM-!Th1Zg84i6gk3Pll&#P`*@OGM?*Ёkʭ dY.Kɡu8b& O3Iț+OwzUPXU?y6.?,nL{@r2\ ƜUJMPdH۫rz@@Yj[EҖR4zpܮ5@ ުYJgy3~ e8Y)Qy:Edd_J>⏵qv Aob@ϗ00Wзs}Q|;4.B/O'ʣCÃ҃%1z6d&dҧ3Yhп!q9h;x}&K }}诵nnTݍ`s.; yp9DjjoDiHPҹz6\qZ? ziC)fB14lR iKL֒&!oD=s1Ta8(c>'fFB ?m& Pi&Hp* ^C/h%zE@7>eLѬ=hY h,?=B:v5]hk4.tB FC W⪞3qjMݜ}./-Vw ty2g] 3Yb?xt34 9 g9gs,R; nƣ3k*Z\|P#HS@h{eґ]Nt&Uk4s@KZf@7}q,Cb*<@jz@cxZ+Qz@ *k^)tndkkd+Lw4YX# 0P=a3+nfe&ۄLB2Bz!^C'#X HIbstzf0wC7 YEF8rW;d1g8iNޜ|wV;xzp!> =O =ލ3кAЍ67܄t~7p~=׫C+E)3/Ɠtn'=Ot21twa nkg13DpsЄjқg (-W8p,-mGҒaB ~J<tEW U ftIP|)k8Cu*x%a[jt+_)[7%o|n(P.X,1X!*%i}+[%@ \uyƐ IK\+5R#AZ)R+GjA"\բ6Gyo hCMP(68ZvZ=|õB^݇eN;A4s1j,0724gxfq.H8K\m:pT#4zƁ C뛊W4mzbbkM1-m49m#wۘ84|GZ %!Ѕ6\hѬ|#RDNP 5=ښ4VPbh VWWu]i]UBoym6&_(S7Vq@BTQY*vjt~@AdTj&@%xsFF @9fǵJϽlsI,wPFvC ^ K7(k.s\6WeGYUGie{iEM ޖQ@[4j s1#"8fM*:--s zvG*#.R@z s[̀t.Sj4=N]!OF˕ huh3l:*ɀ[-rYHek%Nk1@@ˑ: ER~@/gUk%unipi/n P)E}>)'?Y2:hi!sNYą7| ?wD]yOT艸2L&Mfh2p-Iwd?{f={aҐ6lfo#ީZn/U'_&V "@( O@ߏ!x,go3ox>Ӊq1ϓݍvyt@{oo꿱wm&UƆ+塆480_ g_ߞń{E44Zi @ߝeͳ%./>9C?=ʮC?}p./;}?om o@ 54zzF@\Xn}63_C<<Lo >й+tƞNtwk3i}⛭ ͊#iYߡ@=r| עfiDN qAf2VB-37PnÜmÛ&!pZGDyD(r|ݣDpx&"Es(z%qw;Ϟd/.A РgZsv;[{{G;O<=-::ܝep*ے<,,c''ccG^P@ iǑ@0k+}}~ 6@|3B@N CdY]{ Q= TʿƳ5h6Al tAdhKZ#m9lTxK2^[`夼,o O `r0R87}L̝s4(DpHf4M ŦzК _ k^1гŪBD@EvS-v4@=m~@ ò6 id-֪ᄆN/he3UCWuVtu@[\y]9ZemA-,VBM ZA ڰl۰FKKZQ:hPleQV u M : KI4Nbkک@45sn"\ВYku@9 z~1@S4 hp3Ms.[ F:gV ДY@ BdEe&G)S핣JtZ*B8?x#|}]]\\ ] P@ 4] }mm Zq*Z[" av*_ ͇(z@k!}l{2Џ' GU@w#[ 7ym]:컲y0Nx_"?ސ WS}ЗgC@=wt1w3'x{{{86v--rs:L)208+s ]PH}y_ RsKERa"R?_HTO>A߅"6Z5V6G;<;r4ZCߝqd+!`1 gd hV}HAҳ}³E^x x34=j~:w otϭdflP9|uU9w ۏƖRRКcjb -`\sD|B~&Lfل27PĤhN3Q*AЬ>3< [% >^\@"Kp Yme!4Wd1XT")+@ZA/Ц:g+a5peF8VV42לaYF Q? &}fl.u%KIx-HY҈RgIuWIu7ViЮrrsJ9tnLV@sMG8n\*j$F6a`f)Eoc;티o{/zs7gr=cyCsWF-\DN.n`4Z3;q@=@#S> v@]s3R"9-/(L1tY]rŃ[zև>n#ɳJd[e0qNz='P1Qk2&=9mX@@s㹍EXI4h٫푃^)8.M(/hM >I{ʀ|"n--AWC.)d:@lx^ELa1[dK$C:"҈-rD ’HUD@n2ZG3S@W/tE [_9]9+YeѢdʕ!~ݚJ7xk+z f9Pϯ},ȳ#3~<"G hy8z8|8z0'xoOзG͡!hpХt<1Fjh}f}j} /4q7=n4v7U=AutW)񺓃Ҳi9dBb[H)-8lty'S5z9=6@O͙&"pqxh3zaDeĬ=zF@Ky#䐾q\&WjdDj-Jz{&GIdma%$if#VKHA\] ㇖.iy !++qx YC˅lu%~(IŖ`aq_ELlqK#$OAid]i_HAY,\Yi.pe:p= 7p.c X\y+GlFCBslZ5 +yvՁɝ> nud *$c^N5G04xJ+Z}de}#xe\&ќ+li2*ꛊJӹM*4!ODىX3w"8M(‘ai8$ :)1%5 < ĬjDhrsWRqcfBP]5M;W*nhQ Bd #=6-_!ފBw ~8vϿx+!W`!-TXW_`PRtsAYd]Y9EޮsF.9+ g:W|5#]*΁UMAd]˽XMOqmS8 8^ f@LԵ_*.*D@FH hn'z:URŕBwȝ, &1es>@=dudRlh*q7] < UlgZ&(Rlv \@M\:ۥeR<Qڑ(-m*u4#QB9ZH:0n-!gL6쵝k}Rg 1s'diԴZi@Wt`]v79:khh;]NS @4jq:]&ps+QY#E*] CFڨr~R:k8õN&V0iu傾 j!OT!P:y|0Pߎ{-XʓC%O fG1(w/ϻw?lnp7׷n ],܅Maaz!,k诲fOȟKIII3qs. |C>ޡ@vEh)ڥfd ɇڔʁVekx)_J' ;2[Ib!դo.7Ϥb3htlVL*>{&cxd*_04UcxSDX"o< 1nX1q͢yCoBa& C{n]{"\@aZhZo4,$Ofz^ lO߃$G]g KHQYW.:N6g0s 3Mh[y>[.<M#zƚ'n'.Z MLqBVnCvJ꺭 [mU%v^t:D+^UHe7G_ І д; ˡ=x4Kt7#C=(lx4Ȅ׳ \" ǰZ B?/Er9't;3GOIpa8o8.n.miК5Fg -^%\-E?M)s`hh\@!>0a~lA@?A@KQ^H$Vk@K&F ,S,Y@Jg h Τۨg4sXr]>.7[Q>sknZL -qCXbI\2o%15LVm9Ϡa0Yz@s B:r2ِcQ~,fDhHk4ʒ%?i(IDATV̌q9\Jhҵ; A. kk}w%ƽےv{L BZR =$H; !kId <ۆq΋+sU"@S=opg3o:B.ƒzJ%ifb"*sIO4E>[\݄b+{gCsE'_D@7V~:"|yC`z ≡Y 04z6 ө> 6>&&؛;!ǂGFWGЗG. .@@ܩ,zp BRH CPPHH!.m=+Ov.3-TV;/^(u`CXУ};cPݱ{{7o>"ohd+C}}hC`h41=w{ A!'04HEC/q?wqmfzj77ܙ >tTM6>܄bh7W2<4 _b Й~|ͽhhz>A&7W0'zG@LHx3?+S@{cƞ(f<Ckż^;Mco7 Y؁v ӊ.6mVT0UCyYK-RxY.BWRz[{iY{mv;OgzwwЕb*bOp9h{䔺?Еl@u6@o(4Dw,]< ]&%'l<Z.n85Zpƪrcݜ xmgk?$6B lS]z:~?n?,=s?mOKaQ41FCW *N"S.%$)-{$uWƂ ge C}pP zFг p0g$p"ޫ/3|2|){%{m@K.X\ċ9 5| 3~w"|s{ofE~76@3Mh Y t>04nE(=,zPi?sw wo{+%zk*7= h~ ]@p~c<48>?ĝ Y,Zl?'WR4s|0!KxJLSھ7s5Dg!2BpWxZ/6ôݴmiߊl[ -oURsWane.48@Klo9't5^ ~mC@ =X;zc]UV\{9hG.IWvT<78A}Pv3U'Ud3!x=VclE݌k]Em"2.@̍rRйsdYu P&ur@W$a;6認)s4 r\AO= wsM@WژڀuT t^Ў5(b~@W <x浃_nlDR1PAƮwsvN+'|]eH[~ O@\uqBDum1l Z=mCa1jr BghƕmI)lN8P .ᐸ!Fs㍆.VSW*r@{xhk ΏXg݄CZ=d,.. !C堆@|DQ4J> >x^ax3w;o}rBw;۳fB9@!Axcy{,xͱz4|m:/0C!PYD'zȮrR|9I7c=wc HgH# b m l;Q:fh]n+:svDcCW.r@\#o-~2koKq2$˽'ׯ-%o]rT678*JWVyJ/'mW+<@$; ?Ҫj {ze@@WTQ@;I'6gn9'TQۆ@1va):`@kK3_R1[und?ͥƃlh.3h%wruNH閠h ź%܇dU}Ee-˨PR`P C!CF7VmGmѧD}~S|-JSK+鮋΋ٮKݗ{.. ׆X>طFw! I`f?>@mB4'r,p/񷗅/ wVDZ`ܩvće /G=.rT~x_7a||N ]W[8j@!?}9T;cahX:_cˣ0s-%>9z@ϯf4 ݐQIL%sL:\19؀gq6CY+~sIX&2[HaaoinՍb+m"YՄ4{[ H]/] Rl= K{[dD̥ /Er1&@?e=ot Mp*\J7z+k D4܇&^#U]Y>>xemnw:Qݐn k@~wS*`.yZW}+<_hRG9IC@y=M&78ѐr6ΖAgې}N9qtTWu\uFCg9.x_wNйGM9 5 r@"йWZyfNk0Al׳CEzbY]%ًtѳUb=r[='z$ԫԒ\%6DAFègxẌ *PO3)|}9s)u1q!y=sb2\dјkÀi9ʿ5 oc78`7tdz輡YX?_扡Er| T;nI?(=< z9&rL~pH}{v}zs̭S1|o1΀D@3z2]f gr^_=c+i|2фt4._=@guLb:'f"z6H]D̝kG0$Qފil1-jZԡeC뷜j˪RE-Bs 4y݄e"R9D2o@C$@ Wp A{F@gtOL_(X*ktC19)WKj/x{<.^9^ +Z_A@(xk_1e~s= ~=6\~x%Br3:B_t&pm67cΎQgjCTz/6gir_h&#s?(Z^]h'Es R3)<5 h-?\rGMl׳#-E{nѠxC SKJ )6z7M-{(OF}1{)s1 zet}yAyC99*Ѐ! FCO4ACCdv—;Xov <{/sࠀhsG^0>?أ}Kv6-eFO &Yr488G@/ #a{fH<=(=@Ȋ/g()XD|$_8mgгN/f<5F*i;ɨTx{^C/Lt빜ȋNKZ %E.HJ)d޲,$ (iI*N.űZAn޹|\ـv%v9Hl?+|OK=S@\Msttw:j\$@}j@2x@o =-M+ h7o40xb!lwyGIMjF|%+^H3> tP\9Sĕex줿 y7]h[T.H:0znY1wk9c@Ww4c} f[hp5w8SΆs#Zw5 wx7,s.".r.,o]qx7ZnBٺ@ ƀP1 _BcX+КBCosPSm '\c[HtG􌀦^=]p"wz3x7w#k`2%B,@6ÍLeY ofwzshh4rrX'b"NZ9WmځiP/Iwy]-"I2{h-[] QIZ tTPOlP@ [5hCJ—(k18OpfFZgyS~).ΤgS龳,<9=w b̅~i4@Qmsj`՞F@{IGj&_w^jtuT9Z.@Wct@@Jgh#/rd:t3Yz4ǖ?`M4{%憀UTj娱TTAÁcMmy4"hqօE<эIGC =hLTrиg#i]ͩ攣7=-ݘ4  s GcPh(G#q-T:\7eƪkG4g^y?YYU58H6 S-"21Da;*)ۥ'ѵ܁Bm}($ߌ{(oE]jÍgtqu1ocIܺ\¹uQIٷ;aA;=MO3k̀_)4rw:&Jz4W6نg5@^c-5ze-1D\CN[C@K`;znci}d$z]̅f\3 : 8Ahc9 erhOhֺ$>k[ֻqAFݲVH E{5{^hs ldת?ddAV~~g1!>ƚ㌱6%!fMjǢil:x6{&w:>Ϟgdg1޹,{; p5tNuԳΨxcL1.oNMH'eMʇ7Io?O[gsyEe勭ʝv˝Wo@{S_~=QףʯG__>`qn߻䯷K_m&[m-w; 9Y44(_|opcBxg\6^`L0؋Q¸x~T:7"NK7ׇ׆WYz>VipJxt0)H מi8n<:Fݹ]hHȶ O`De[Kkd,Y:h c0 kѰHKfdɌ.e<01ꂢxt9댟ڢ,$nNbf%f4y!u#{s9E7̋E \ =E6Th > Ѕ z ? Fw [M6As p7^_5M :K* hYc|/Rr3 b^Nh 2CF5 XɐCƚef`~r,脘c92E<çS!TϙtL,{;C~0@_Mh*zs4o1ƸL9ޛTи-MIgOg[sʭ9ּ }B_lUl#ީ|n=*z~Ox&@#W 9п~=bA~s{wة|]*] "93!!{xsR|wB>^䮌sًc=#2:I RF9Uf#)p_L С|B:cxP]ay%t.i%bsEˀLyEE/Q̶46VzZ9K2"Ss?KM @3#e8mې ϰ=,@=i\h2\Hll%&3nBC3nUx 5hgaM-UoL8dY GS "$,\Ps^04s ޜhg\̏tu18h4ht~C͟Xuʝ 6͸ݍî1wkE@;&{V8FW۰2n"'= o}SFP[ߧȹ b@7&1(i?W^ko [T-Vc]e^700m*q qͥzf(4(IlvA@kn%eX׊ލF ݪխEzhV8 ZO}8렑$CZY094s,0acO[%zw{?}K]bzY,$^?[Pn+)ϪL+mol$^N'~=zpzH!VO`v@*PZ:P-DxVݞ(,=hrsz&J D@#cV"ѭfd5+l09&p\_q#z=[39+7^?u^o4Kyy!繢Y[<,o-j+wfs>Y077mqhspA4_5R%ZP#'&4 4ļD 2:n{aќ5'!=7>'Mh ۺ?ݐ4 մ{;6y:=igTuduτ{=gצ&]bh'.^C] D:אB@7k&ͰkϷ{m>EG@͗lP~,fa%i ܥF=w5 ݫg@ uH7 u"dBfp$D3L,$LgRCh(:4f#V#k4{6˜wItaɞө>.1,r K!ʰ|uX6\VF1;ڻ:tcR#S4phdNt^?_֩nWоzWX_PqL!i3X#?^~^}""B-D~2~=Y>8A yZ׭nwQ@UVATW\N!NE_hXz VUcAttsnÃ+kD0^܍Y\RijelWv v#r@7as%ʁw>ry1g}o":0gn3'<5 CH~u!t.NN —A;K<5雂Αlfn?9"irq7T٧ b.Ti0zpj!I"=pnOwKz7muL3Ygߌ#8U-xy1'nB:[F\-#!O P@ rGp4F{c5gB@o|tO-5't]PքX#drϴXǵ> ~ԙ#muU肛 GK 5=cJg5lp]IlSΰ`fb[B\!Ql`A$ː!IESeD5IIWIzatfdZdu鳢}f xf%BV2H*Eh:Ki&a2Y&Ϥ0 ["=#&9Ϥ)Zߙtt:|*;^/ho1_87 / K!zmR iizkTw52сCm6#?Vf 9yւ٢q{~gE]Cr3{oC 5OG!_2xףχM0ӿݣ},.YlUX>_?[o-*.(ϫi̪M+7ҵIʸxy\8*^ӹT^P_q4m_LRH=)Ƴ1uƍX#DQg mƷE+([Xe3htQ~j@{ ̓޶9OϜwNW6;݇\P礣}Z\-ao q<th 5jhCG49!_h-u!+ tꢳ/.h^Q 604_$pM",Ït TR"v%u\ܥTϥi=hDŽLԳzБ ZXȊ"qs8 zNIy@L8 dR#Llj yZFjZ &c#e%&N+ Ihh/$Vt ǟFbPݓq-~ҹBꩅx[Bw-Y^x\_h/(^+Q$i h$7@gC:5tH6S {L } F`$t-+bZdC: Gi_XT8f`816' Hi'itt>O§RF;Hk덬p*+ΊgY\|_4^Ҡ+Р &t}DsԀ3!jh:qcRI{o {Z`Zxxt޼/_l{{;{Ϙ_>k}~+?QU:=5(rF=Yhi0'5 X@dFE@O@OAI$(UmNQY[<'@C= s?s<=96~O g8Cg8.4M_"m.=i+#k=NbbG^0\UWc\U O26=@y@G)stnHuBkqUtt tyh.t&t;?څCSJAu*eh~:@WX{ hZ ߭nqp=sGh:EP4ƃX"t%q(A%s"N'ÙT8Nc#!uSH.+퍔zy=|=z-~-ͼf_Kq`WSk)z_M:NdY\ \P/ j!H6_1oB[cc;hh ƤycҸYjhix֠П-[Ѹ}gqgyw}4CL7{/w+wno?[n-ɷ牞ԛ 2\S.ճڙ!Z99@CZL I/a=@:=G|Ǡgbɍ-nS4o&#ؒXrrL@FVd䴑13FfFLi-^ =@ Lµ- ]Ԭjws)}cwYyQ[(n^Pm) bsͲ8R1?-K8rw^o[Uy2?-o<oTV&4b]n#W֨5jeRY#g h"}k?%\.HMQ R@7J7鋃ޚ*v@\_hOxFوw-@oޘ6}Mi7zZt*vyw7yhӐ{ks3cCZ4<&"@7$ +Wx} En "kAßs73}a(X1!ۇyrszhICs);hUcBz} FM ]TNwH$=@lt<$Rd"J Spb0 +s/jO$)x=j*j*t"ŞH'R‰x"%HXR"B~= Y4dYBVد]@C_ԯ@Ctuؼ6YGq ƤUfh`p ɜ^bqgbg̻/_?~{@X>>8tLGFCG"><C?`~Oj.veֲ|k~s3zqL=? iSAA(t:r0e2'- 3܈='wy=Aۢn9c%E-#SqrJ@!1PzZ^ճōgeMQIm̀mHjQ:'=30#bYg~0 uafY<},0Px: jpsAЮy ҋ]mUO]VrVAώpE5~V;sxjTQT<429| 5Xj[!O} nF&kB |6@+jA~gTj83^F N@6^UT Pꓶ\GĜG3.8ER ]y4F oc5EQfZm:Vה'k1osӔĭJr)ܘv֧i40Gt`IG}欏;7 gG4 "PrǽDh8t(ZFk4W@wڶ v8X\dezIUrDK^D@y @{К'{btw&@zP)omvy:'=]SYwoZ"w0s0xS(8O+Cм;8uθ]]ns}u2 C{V%Ӗ1oXUmyjM_~5'#I6!e4%nb//4bS@lx>~f:LW-]"káp 3L=Kbh$X=u|Oܫu%.1tgrFXs(~}@p4`FRm=,p@R>m6kW6ElŤ6Un M#kгtr&'E]F4P | z: ŢX,(c `I$d$Bt( M0%S+qdTTD~%Ž^NK+4!a hH"_*'itF9QevqP4_&]ChQ:݄]4~;i6 Y`Ƈ3s' 構`h-vN.oҿQQ1Q /_^><HCտܭݮ^Qo-+.+f50ƴfMIʄzi\0ύgSC:ѳz>1`_/ecȑtp*r(9@ϑ}Ixdo"G: zF@Ƕ Xb%܂N,aEl6/4m; cRjB>n&t&3t?4 B9 Rf,[d/! hmC%$޴ajڜhO44Yh3z454`(i޲X[-pwsPîܭUj7.n,r`v.Z=6lૄ50tpW:O[SUJ7Wȸs΅TӪ|zUV`a҇D@%+OW hIMCRWJ^QC>ƪAVtm^ArcqQ ホW4㎲ȵ (c90ƙ h!hHbBuPS@Sdr5ȝ!iHy66]uq'9]+3j66i΍r՛$dtKo" ΀"DUq. uO-O+Hm,՜ ws^zaqG.tOH&yjI^<;Oc+u2ަo밷}UޞOϒw\vݡ0+4Pxs0wx^^amqoD鞫unv{FC~OSӘ5p5PsӜ&S)CnOz7&1o][K΄^)5>ËTkhc`hxOc|\o 6&r`n;k]`_}1l=r!—f9 ͒ݵXW-nfr֕^W4ҹ6atoKr -5Em1^- Wk rQfIOX&۬0-2Ķ(VoS6oՄUhV]j[Mn T: -Agu z%-P xI'r My5Q_ϪodՓYTV;M:;`. h~sNB}Ȼw&`ad9ٸ9e7m?c~8g}4o}`~h}db}úyo}_0;h?dxxp@?8Gu>n|,H/w[wv蟯hOOќᬁp77konҮOjW&څ1¸qn<=b_='WYX:@/"^HsxtO<'şb#]خxDbg<=Ocr4s4Z$y2 y q? ea:_ Ы*s!gV"֪5˫r!UYOEȍ:ܢ Ѩ1Z&[::n,!RTU\TɴoP Ƅ>fnpFaQl7\h[j+SO舳=/ȮF+]^El&?P4}]πϵ]xo~'tɟjnEn)u~OpM۸cյ5.z{}[}`<ó.2pY?+ME"s܍ sVV(A%[mY{qwwߺ<Pڪou5%喝>>~u`I#\SUM.zX;VGաwEY֏.gS8+Ι;2hQN tvg!(G ',D 2F :mbtʬ2sjLgfM~ُ,~aԳkm-דB8΁X`>hR=(XY_q:'^Yw)ؓ tXiH:L^n.5LΨB:s 1!fx@ g,78NRn B*%\J. ƮdW eKȥWnӷ XR8 |WI TO!Cqho^t| .R?S?m"4C@9mX;~{1ӟ.3/032q+[SGԃj~;oSJuSy=îIg|,r);Cyw?X #p̋8gE$;dK B[ =hމy:TLgDD[#- 38):wK& 4Ӫ]9  yȬlhm]Թzgz?(#![άN^+O-t^@یh63tNSY_8xv%oZ|f/=ۼ>7h΁ FP#<~{g'dAz~3лZ^"Gצ`s_=J 3RlzGy nF8f!'>JZK?:*}0U&sB"/6@ogeCGHLl;o-q9I_ɦ7^ͦoꌾ[L/p1ȁ֗ǡ2OԻ{3s ZfG 0Cx9ϫ`h ]_Ӻ*3ܷ'_L}dQ64 z6Liͩ&ҝ=_)QۅVn" zS4;p^:̋:[`yZ(a, 䲲is~*J@&c޵yz2LFk.uIOEʦP E悑N@硟:-8/i4}f6@Hm_3Oz-zhzxڏp:ܥ: vC~ɜn]FZ~A/}8X]~@7_7uV5)hhۘf9;kȈ8Xv=bn9emV[R9:wD޻^R^e˒t5$12Yx5~wa, ^K .cuhY^DbtCMyYϞ0T) wZϟ3u@qm.t@Xytsڡ)@MSkwĨ,ew^Ӟ\=2VsJhygcrd;H0Fɛ~o==A( ǝ!HqB@0oTG muz<±׈΄ϕR- ~ @KzN@tnYpBRe,Oz(U-ř|bl ˂.eHRxKb6r&y I:$5Mw}@/RKeQFCq_dw*ƽ33 ߝߛaޟe>cK %`hFCO{s?R߯ɋ`ϛgo[ϗք ߝ9Eh%4&g?|:K?ߚOQORkn3e/f "*rhQN:I8 δ,ЙyĜQ;lʷ`嶦H>Df2.L&xeq9֘ZEg5"pY᫭\& eӡt0JóyZhi٦co@O\@O{G[Zg@k_3=C /hcxn-7qgn&&_"SrHdS=v=]>מT2.mjQϬJ+3٠g5bof3 v3@- ACp%+JQZ߀6D&p>*{N*k{u)ȴjtG+jww˿_"+~,|@>G1}RÞ g5ke:el  U`~Y %gs' >вw8b@S%w-zN˅z$to*җnMZロ 1ÀfnG@y #fޝaߛeߟޟ=`<"21ˣ^fC[|"w#C3c[ӺH 2`8 %zswwf7G U FcֳZ[":KtRN 3&xra.s2d9`KL9;Og (ߓwTNr['-M ~jQkV(Sj"BOFHTjytzEݪN@|ʦ|)G SMϻZ2 xVWs2Q>Mp&ԥDLG8CuK2Y6v8顨X.3m.3h}:71(+e*6[1VڐѴA)*fG ;3@/YְhA{;4T{ eͩN@wTt5E$}sZ$ȵN(?N"‖wj46=Z%Nm]tSn\gAoWtwK݁yU`A_A!H;Mդٓ>{V:6)}CYǶuKQ`4 ~2#Ȑ-2hآ;G8VD~0nrGl^5>!5?:~fgL@s+u%n &tMKѡtj+"7@+ 2PlfBa$4*HQ<"]OoAYdP+"\9_Q$_ %o .g%~U%!%qgugpsI 1)&7ԖmdLz[uEJf"D_ϰynSC ܃"?,J4H2<coVjSܓii ,t}:?J}=,׸? mqcӺ_8ٟ5swg g&5=Fߨer.2[v#^ʁ DD%$œpRxs0+,Й9 -1E&@4@4O -%d~"%r/YNH q" $^-.`1H3_Uchq(Bc}#DסO+#VXz>sg~w2S'w)j_h m@7?itOg]蟴B*}tbg}t-uzuB2zfA*e^2ᒳr`]@:г h4FŢJYFlőnꤔb&qDgtֱ ]Rup3]Wm[ %țq&AJkP~VzuY>y&ͪc&kϠ0هzm8uvM;}S2 5;^\FCΰׁö(8&n?g!G͇{}M V6A3hgH~n4s]gt+hh(ɀnN{(`7C2/fY[de_+(e/_GcLjUׄE>)жxV2e=z$Mڔ S mIԖHm6ylhLdI+w=7s|D}~>d8f7'̽*{{~~B]@"U6z_ѳ(ӢrF:IB愐9gqtd 3s~/0y0GEh*̤ i@sT0.)% ʪP"gdf2 ju+iEj ǣ.<v4f~-A*=h/h󳛂z۟pp]_ؾN}Ƅ2i2/_@I"V2q|5ԍQ b 86[eSV;ms06^D"9y<ҭɯ *{uE7Vno;ﵷ.z6F~y~"9G@U81YP.=j~Y_"3ЋgM6tP9lď H/o2N>=t?tq{WGrԮ욞;NßZC+CSځw\SvY|US Ω3uJz2STe1RnH7L!Sh z `H8)rx!u1n4ړtzNo:!g( Gl![tS~Ȱ-3xoޏ:P8NC $[lt  6>n eQP,͂9Ȱ/с160&*P =L5,D9sr\B[:%YOGWlCL\$QІlHFI{DoI̶\+r{UI+FF|5+̉r❜p7/܃ GV1 Ϳ^AP =!95ɿ5ſ=ͣgsܻD aܗ'_9+M&hhM `~|F}w4IgُWh)}g+er=oKy~=/fNHгzΜ$(=.\9zr+lnΓVcͳta*A3"4*@4Osq5skU$z"eCK%Vc0ݥcv,hf۪EdC?pƳg=ۚ{oP;ҤMϝGQT!2=ҥN@wBUThyl$ޡNв[?n5%PIFeCvdʼnD=z>tʶ' 7%iManht}΀3n]1p 2VQ,je n`7VN.óH}wEMvP.u=i5#a-)xJ+,ܬ9w/=Bƹ慛{S.~ة]7 c悖=NUGj+:ߒndV38jz=4u&wZs|4ò=;z{0ܤy16@ ]-%=~ ?X>X`3YI]enQ, :˟g!I:#J%L愔9. 9Q.w~SXd Li):24MӥtJTq2UJmUPQxgZ ]Kdqic"4v `cXDY,ƍ)9iG`sWZֳogubϿwmWtߝ#zF@4]Zt6# gX3٢UѳmMdA H2)+ݖՙRfv;KCT5[[|}po@2Ժt{B@dC+s^JO@sV =3ixДlcY֏ǃTF5ErxʜڷzFkbG4]#zF8m(\0G;/u7νj]c]\׻0uSg?ꙹe.nr>}B=d{CӚ~\)ӹ+}E57&et.Qd@̯tG;v(6zqEпAN4zti2ٛiu@{йyӁ ,P2ĆJ_x?`IEneRBGbb i!. u!~QHR@5.EYpcihlC6DvKh]+tM̼"eg270Ռt3#HY"=,Ul\zTո7 $a4dVxgN$ Ow>>>?uJswS^Me x)AvKui%U۳O ;.|~x?@3OXeߜޘ&;U8}}Z%~(yBV8eR:-/?#DϸL)]ZfKLq)A LY4]2ӐɄFy=C@גj"3$h WT*c1QDeеPb"ߣohAV{=5N6@Ox}5&/ .RS/hNӨy3M z47 wj7=Th&k <=Gqy[@w.]%m蟵/H!o"X>LeHSwRS*cZMwihNeKltlqd{8Z R@V(6i6՗xWGH@.\v;k4`e j~l2$DA04e1>,U~(Kzmv LY3C2,sr>j2BfUɩM1GlK7| Dޣu!&&ք) ])hM^h^nCj$rB3~[/ U }]B@_H -fnZ!+Aƒ~CУ*ƿ1?F@ oM oψOfw's΂.Z`?A/O_9Gn2en<[QK{f~Kd\3S3z=I=tcĹ8^_u&Vnܷխur:bZyHи⎿VAϔ@)WƩʝw+q@M?P4֎4ӍBzϜ; ,CуQS!}5f/vOwc+.<߰L_\Nn[Zۦof︗NkҖ5O >|H_TNGk-z΅zTmtAwESgz:gNo,̔H1Yvs2f3й͈ p@[6sfM$6{~cd0MxcVdlA~z}Lrh|_0ĸ#;D0/Xƅ ~ϺhM9`=CCAk4`CGFu2B(:d -LA&;,@yi|nzך_0r^V.K  iK~Yp.E@E*?6Љ\ n.4K/QBڟy:Pbe1PE/3O &%ץ5!&IL 1R $J]F } ͯº(m`hn ˢpEhhW\FA^-7 ҭt[+0xzJeMdMfޘOgHoIo.Ho-IOŏ8$g? C#LyyiaqU I 8A d~ĿĽȾ?_Owзj̫Uq8wmKEbA@efsgS)1RUc|P8s,%3[c su=ŠCT*ͪi1.3+="l$ 9Vr4WWTIu7.F  ƪ 7 K@ӵpR281Nsdl l& f~M|5\H&pyڣU661Ѻ U_ZMOKm+пZh=: ~lZ%y[Vt 6.7+NigJ@M&d lqgj=HI -z&w@ȯt[bo@@wڄ'@K_9]`AZ6DcGLI#w֐Y3c?xoՏwiB[IDAT gڧ. }m}~l˩uxoUgq@EGLz/^ڡ26VԳ+{!CϘhWU oF))e4%/1bD90]D1o #i]g sRiGugXt2 $RO@>ٞgO×,K3/PbA[gN@Zb֖ hetVd=V=n3tM@8A%cRlN:+@'N!Aϥ\:Pe_GrGAZb(F abhp\bx>Ej@s"r,tQe@K%QMQˢx3+8ˑeFAzY.w{r =}@ }}}} h2Ɣƴx6x>B̓;+e>=XNI?ҟ//1?mdS<-%x݅Ί_>;x'f:?M w&9\qW+c<$ռt>=˝_Рs\9gV.nt4JsMdEY%YU*N@e@EyS @;>$iZC3t-HWCT5jXRPzmMÓ@ktVZ6t eCT+*4\q^UGUFTt7@:tSQ9)]ֳL纞&г#aF;1 J;\)6wKh4+fq%8dq FN=?V!).w\@Ьk'[t%cd)vؘ8fL@UqӉ5 ھp fjy>{>w6׶꽟ް.31s5r\{'}CO )A:1co2tXm.YM4&S084ݦd1gL "aGOtwP fzCp?\`? >7X7ᕀ3a7v!.<;EꀎQ4UНb~@++GN.jI:)a!_/'WO8_?<c#|[BpH Za):"EaFLth6ٵ\|4-$ʥV4x?|m-_{R6Cҿ u@t=*YVqY Wtdfyɻm~AiJ84cŞÙ d-;-ᴴMq6ƥDŽqYk$@g9ֶs5Ꞝz^X4WLdØa:&gyqM dhG|Q<:ϧs;g8Y'5nV뱫<]b[h1)ftY]W5 *\W܍|fpXKwK廥ҽJ:`=bk9"bzLl\ wOxҧG< &y045/O_!MMM駍?]LSOIwZxmNx0+qcRQU^.2<t(?&"C|_>Uptywth2EWP$S5jY5=Rb(CN^.X\^Y}eRD";3Dwj NԂ퀞 D[M`[|*phB+TpOn>K_ -zeCnA#zV+ _%D@)-p<_ϝV^Y h ,:m5лZ6-4.0Gd:Զ|\Ϛ6WpzT#mŭݑNͤg'5ahg;2;3[W6=7 #l4=]?yo^d%:AдH Ψ+]};),YNeS1~ĘQ8Ĝسf5,p=_? */5!&By$7H[ba[,\ Wt%S sW[|PS.Uƀja-ipLқ'w?8PP#Oe8ToJxB* @i狅o>d#, o/o.7G ù Wj⵪.d@rq hpD, yt2[Y$@Еiflktm"NI)xrl \UFL^.Q9^,ХF\hD>")ȿ34OilGg#M9ChpʪqapZ7,tNYZ2GMɣf?c۶TG>{_W-wn;8W<_q-k= {?j2 Ynf'poLNVUc =<-;p`s~)!lч)drs͉^KϜI90Ǣpsg6 ޕHP"|0^C)\Y W}h4ssYWq BʭPL1Wj4gg'wfe(+wk&!86ќKJCWA{Ӛ eQ/@l=@||5#@|#}>)VzJ1/T*P/7h<%UWFb_NgOٳ<ʦ.u.zy\of4N,C|ktS " x/ʝU!.yL,Ep)--.Rrp9[-]˖^ɖn++c `r[)݃K5DdTttu04bһ+?8XHcO<π?"DC7q|g_z<ё̻'[?^Xx}=&nK匼}./Of'2tp ]<$ e47Ž-c;e@Wfif|G=S4AktG7:ud=ag+(7WE֡F3e"R,CBk\)–" T0p3+j,k \ީCzff稬qO3\n\n7{f6^t?Cu@kC"F+];lZE#5e%!P,pjOZmq-fo D]N(0掶Uu9L4jh5 @w\w?ʵgҬ76-KW_ֲ fWj닾z/?왿皿Z\q~g;Xt}t =g悕:iI1LgF?24Nj\?*dqռzƴΑ1_hsݠgs$F %bh܁|2ʇq艄ds4>r$;Gf)Pe$Xdz;9+hW1nzW%7wmp'Bp?,?Lget]m$(0#f\ؓߵZ1-G!_%FZ<㔿FdQn&!/y_N\d*9/zN!|<@3DUgЙpNܵtVt0.y*@ biE$/ )Vm)mgʗ3+lznF~|Vɻ'L`Rs9w۷vs03A"c@$H`&Zے~z}9v7:  Eiuշnn J=s{>YPʨJJݪgo7wGDzoS'oOaCR-P.g?Zb- B7nǿ=L> d'ǫćKwRoO'ޘ)^I$B=CғQ4j<ǀ7Bt=TP9Os,P/|h_1+u!Sn04I{.ug;<S2U κ"YWb k:o | Ȑd}Zb \0V &swƞMg9534wDQ}] z6ͱplx>q2\fKs;=( 24}WAB_"YBzb 0pN%!Av!{ ux>ċ~>$|A@{~;?S8GN5ssQCf Ɵ0wtwu17xqkzyuVtC?͟s|4s)gԓwetxۺ?,ΙBͷcb}EealZgyIeehU4&Yi.me36=a7sgӔ=̴Tk.$\X%6o;ŝ:O'ctyFd@[h9kO9Gc[8_V Jmdhd BbԩxngډwcqL>*K^NΧS+)B~-U)]ΔdJ2kDYF9/хBaHC7K u=[SٷdS,QPf&>L}9&=l7/S8~s.sΑߝ~K}ul2Blͩ8Hp<Ыib)E,&3Ib!A'H,t0 hn P.UC%"s\K_3Y .Q0t1.dO#=ٞY.\dE3s(G'֝=4chh :g V?mBhulz&[ɭ̎Y,KW`5Z0Y: Fl:iCm(c=;{^"hKɼD423a=M@wmhz?Ne7qn:Хg h0Н/AW(,rDrig.̩3ٙ OOi1$A"UB ڇ~v??>Ŷ9C;Gv?ыzG}M53-#)yx>|~}8PVOULޑOݖޒ.H4;6rf87DS{Żo|m(}[&@@~@JjDNH,h )™؋zۘ6뵯' I׃qۍO[UBgSa6i- ΖUJ;ڄ!.h9d @M1]FG'v?=7< =zn>c= FHc0^zNA:7 |ܕYN2k& 6m0tڢ@VΦ=g!D~˜ef\X 2úlʘK1b񝌸Oa並dԹoE[QVԽ4{[f$ 6 pHhrMJ[̉(q"=NƘrNrQ04 ]8CN/+«tR|9]\Ux-[FCE{P/gqNA<ϼ9I<"ߞ!ߝ[ȁ?C6ҟo&8z;n3_,Y4Y';_}Ab5":h:Aϙ1 l S@Ӡ@ۀf,=4@f3xm9{;kL4 A^H(D8[,pIm@tfjhwgZ*g^=7 4c6tY{рL@].hvN@CM@Z€eE*qEn BTh=4ځE-*\\bpz[1=LUB3wwdK+ӏESk‰z0~]DȪ7dzOM hDgOU:(=eƠ@'9W\4n|3~(@F&v{dܙT9r:[bqWQ՜|g;3:Vǟ|c:rƳL;-V[l-l9P2kL !(@'uxNxA6"q]V3@#@}vs:nXh~<Z#=˚z 6T8̗VM h `%΅ hgLMMa@:b]t[Kkm)ug.FtL)Pv1_ NDaɰDnތ:6ͨ{3ٌ1(X9iզsSk%Hj= N"I\ nE.+좊g3 _I/$ӕKL r,A`T14f4 хzݫfk$v=JKK1ys:px4}@H}xzԯN$N>I}{:ùg9??fd'hj1.@_sS r6Ns1 Xz.Ф@hWEƛxrP2lE]<@SY hҖ8Ф+J"C݀ ]:˶/x3^<~nޮ hh"@w43卽 }30NUTYShLg&)ܛ =Y2.[ex,Dg#v%'QG=B ixp|Ѐ.Cп(m+|w7[n+l'*Ydt>Q>,*_H_MW^C"F+h ]F4}΃o7J W͂oɃ =Jܛ LeᏋoRwrrPX|l+ovߝ6įϥ~s._}{z;O7/e]H?ߛߝߙHOK47ɽJrI4ːk, @l}groC̮1A>7#?(Vkc^<kxWTHƯǯk&7S{=z#;[}qb캤vų?μ'*Ki62:bh7ШFjY]=hA ,KA8%9m(r8>.eGB[!ǃvBSsɸ. @.3zBR/U1}lZڶ[?-䃊N^sjLn`9{6_qkIj4Z6TmHD7a!ͅůKtJv"r.mytBVѠ Rq' A8?T |l^-iaV4(UtNHAӪ di`I& ̬!LڌInge,zj QHfde>O>GCsvcnfRvYi谕V+[u[ns9l.f-ĸ[@ oFfķFԏE 4esT7"W#0lZɴ \vXvAe8˭GFފbxm'j3ʙD\z.Qyat ^T/2YBP9p-O_CеbZ)wQUs5A^ݟν18{{!be5dO7_|u*d'L[4lR=G,imW'O.%nOoO&nMnJZ9B!rfm@wxf|􂠀HB_$ @bO" 1lsrO܆Sp) ~ȤntQF{-=wnB?44gh6424=4pـj@tN̳UN m477Ѕ_*fd몙}|fcɷ‰=Ij|O>zݾp}".'Orl ub РoKÚ␶0+z-IsE)08(r\ل\"[ h-:x pZ.yJOQ0bxp3G{%ardx1o6yⵌeͣYpmPR*3hjl@Glځm6)E!aEO2tЪIM@f$ޞUGA6=ݐ`>Ho` #0 ؕ hf@~טZZJQ ]"8Xɞw#áH`=["@40cx#ɧ+jexF˭J'uGr(ʹ+m+fvxtv&Y= ]}9Q9^HW_E]$ʥlrt*^Ay*GaC_/7^ޯS[G wщ`h W'3_: N}{ ߝLSg'Vҏo'LoR}>:O\is 6G 3~}-=c@Lkyp3qn@\c@ugI'r2h8"tʙN;Pڊ,l٢9;":h ,޲ōkNnfKXVKjgނ͖B? 9ַ'4%T{ (ˇ+4!mZo\7 А3W:_/ K(Й~'ybTƹbi@g2W>$Bn1#X݀PaؽbGL̩ef^Zc淖s`]o6pb~P1Y5?jMoO7Vޭqm&ژV[J>:&%-*`RTIC,:SI߫eaE{UA1Hg6+٣~@w鹏-@3:ɢz6 =3nS/hഖZ;UsD4B_L8IDc!j@kZ$Eh­L+H-ͩ2ab%BZʶC(֢@<+*F׶(QEѵ3+څLUDV/BEt*\ї< M_-׊46taJ߬w&軓il1;KVV_R8A|r7nΤ~}:3N<فJd5eBA7Zz]I^ @ZLB^ɀR h|s @Wq Q=&˾2R":.$~3piGtϊpi چL٢s$g=i-XO44>y;[beh[}zmrOC6@#5)x h7b(G+F5ԃ/i^GFG>-hlbtZB@X\?8$ .v;gG?$+ '{eb:)N ʡNpb)v܁J[I=IP{- -x0`hȋ h 9=~/sys)@3.C m\^baO+o=}7=)zjO1wKPjy-a=WJo*Dz+Lx/蹂]NyHϭ5趞Qv* C8memlp ht sG6{P6qrL `S4C=vo/ہw j1 9o6g{|Ānb4lͱ.Syh#XQ2W.\͚zv@J謒!ܡ;5CR)l*]%wV4-h4  /OᢞvІ񑁏9>@h734:.U4߬@wh@^"dmEG8@w,h r4|޺_B>{tL{[s{o|=h-Vݐ5inW^'#45y gZ-CKyGn톄Suv &0m+6G&Bi*cFC6ޛLsiNQWݥuoT+4wNlk~ۼ0 :6a@11QgtH91G:B; H ZK3zfB=kzt@443t 6SKR3ZqS8 ~K>l62ǣ9.«z4<Áph9n/"2`i9\"RG^d0.)\Z WCj( WX ӫZ+3ZnUYVWcXc-؈n[ѓSQdtjLj\z\z|fLѸ@6.dj*U|-/]KW kRzW+׋[;;MCޜ-5O?ZȽD}9>Y'?~E|~*v7;vR$Afz7N/ר2璯w@Եjj5t!}>+t\~.49XsД* zu+ffX56t]z.*eςG жT֚QgkjyŏhН0ts^@OQ V\=R=-@ ʟ6`'v\yh[D, Gjޠ=b%%c C Hn@ԠCM!PSzu`Ćꝁ=nas>s52bn:w=wK&P6. N?g0 .ssm@*@gg5:@{V9)拓ZMtDNlƆE#ߞ&9C}szԝdDXfC_W*J q&G,z#CgtoBxa.^@Ox24P\R)*`5悕\ 0)_꤯Fgՠ4O57W>T[Iz si ڊ35F;s)ڄ,vviW&Dx`A :3z΃-%@[G[P-<%.f.ăvN!Crf4:O 4w?g[t lO4KQsԬcU xI3xL7x08`gCuO@gOOxU@Elo< 6H³86Ǧ:,|SIlQP[JzI;oWoW(oʼnVA+WɩoS껴N qd 1d4S: \hHR[t1;̢&BN}E $֟ZWYo# ^Zy)yF-ٙAwd@͢7!!Y!cކa״DM,ZMl2dT $]u[^k1d-9OGrB,.G#Z(pt1[ @|!`r ͙`z=eB\g[p0.,b*.ˡJ.0:rT_Ԗ"rtt%2_F'bkVrdrTjb;5MMIMIM͌F+TF^.檗BJzrZ٫WnV귰N͔ߜ+5_|gx)2::f'_J}w o0=M}+Ի 7fwSqbokd3 /33t|@WG#U 4ՒZ T Z>\Gzb77kd Dg/<t=1a7w]R*4]9j= h(Cg;K;63m@3m@]gܜ`lыEdfjK AQ9S36: Fm3j'oΤΜ3?/l5 kXʡ㊁ǏioqW۪&I_/gP%!7$o hmrFfZ+o-RVJ BpT쐈PИ"dh) BG?0mh3~YtWY=,lzDAge Gxr5AE 1˥voT}⧲dpr?s_#x }r~ᅨokU`lzsѵ|O=4K4h~`·t_"< Т@B_-:EHΡPCPib-K\\TQU\m1\5"Krdr):\M&W$4y25JM!Ffc//gy~F/"v\VݨcꝉsG w. >f t(GۓN=xr:n◛_/oeΤoMoNf'1 Z @ ElR1@3~NH3K|@<]S8,JoQ|G}p`w` pm=MvEZ*o(mUfAhF9/h h1+|%|gWqmZu:: {^cͲ]y&p)?x.ߠ{zRʩ@ߥ _][vG;RWH\-u"@K\1QՋ|VtsWhoF[}{t>mCc m5- ]:`TMNDr3|8 /9 <[ Vbɟ\ Ns :9O28bGBs~rO3:1 , 根 =,Bpi>\^#•TBHϋRxl)<\NCrlj->ZGJNHN$vȌ!ΒйlJ x-7zTh\*/jWZ}QnjCOVTޘ-5Wx4{BW|X#?]j3VI0oSOv2_wrߜ*UZ%P'^ ?c ~MZ,^^p x$&vA2Bym2p`@PspE*O@tZ(A 4-8[9gWsm:u8n: GAc5f- ѿ0}dAjr/:Ts9͆ח~wmf7h915@/a/s{N.qY 6u4g44@hn-@4ZҠ{;ҹ&eS&3fc/ڂLdT jl52t S\Ĝӱ,:# -BKR( =}Ez+9ze|ٗem\l6 POPa6XĕfPq&\f#Hy6ZV3\ AչPi>Ԙ7£ |dr>:=^S+*:>JLJNo'wRSh#=͌&FO3d,YF_G/bRVk\7nk{՛cxLE}twUg/6O`''ON%Nަ;U~r:r,qg:ss؟$&{Q }F`@Jstl>}6TK42t]/gzkZm9: 蘻Y]~.\Iupd@#=wڂM!=sf_9gLnpssl W?覞uVT<|Mtat)X @,swBDE)r>G.B ![.d+ډU|+}`h-xlt||7ؠ?ӦCaAs빉vh}9a5^"t p\8ӆxaw)u |Š/pBBS$tn1z$B7J8^TttV jҊZ 72Af7)#{:I!NJ]ZS#vNUD);LBВ"~SV7(¦QsZbsQh=/PNØo\{+'qs Н44솘u!DdswǢkݟɇ"7,?p,^ŋ%d)Rle*Alu H٥aTmIkU~fKD ~\wGka&o{hm?T_owߋO#x ]#ܗ֮*%eDӼ:/qlsmpt%@t`=) i XluMp'%_cQD oBsYjSsv;:bg\ O!o6l-d5>46\1[K݆-u5|Bdd#LDp|):/#b(L,Ƴ?H#.2|Y13P7S<ǝ1f`ua:XpPe*\ pyTf"Hm**T ՙfqsѹ|d|.21bS Kj|f->9>:NMn'v;(tD~9; k\7^G_+_+/+Ƶ:~Qݚݝݛܛ.<ߜ˿{P 6:f̓''3O3Po9YJ̭I71>J^Wk2*H&' jV3r]FbXi6VåH#ZR W+T KAg:7P53e4ty:6ҭoo4kĽÌEnt%*\ŤcČ G$;P;rq'DŘJɔ=24O%iNdќ)7FΛ]IPc fp'mPNm!@gM(ʀ0&Y328:#u6RgO[IrGM:c=Lz#70( )t75̜^'z>aֳYg3)B!@w%(:bR@ m9cOqlh!3rscC!=8bzF4s=(4}D,tzx<>5:̺ Rי@s\zf ֈ\CNZ;|r"38,\{.8CGױPC#V !n=(Iˈai`Y[Q(K2zxW[!}iXZǹig_dA|jW1zyί kʫe u-W>>wz;o7&d%Y劤vſ{H:#o+\<12h,=D,;F.0@g [( WFdi4ɗy_d -"/z[W Gse8]"GI)-5IqL$;sK Fhg 5Gw&qgYp'LƚVZ2K\jЍ*M@ͭ-@BRG@I`he@Xj:sr[N=3@%4$@Ar5b+A:RYWB*tT2O =43`!s S39b~xZtNGLɘ)C7GhW㤄.%uW2Ȗ1X3K`'3Abx MprkJkJZиNڜT[j+F&T`hIR&GZjcZ 4w3izcfzo=CBT8/$ sb֌h͛z>$ǔLӀaֿh9>sf54b{ >*@Kl܊@gUccil;:.,<)?ȕ/ե%~r&z}isí'>g?QxU\*םG~ߣ'?DO/,wh6Z"idPGɮ9G]t-4{<7\x3ѲC-9\vaX^gcbSFnAaQLcϛ ፴FBu#)n[h=:P#uaڐT2S"hЖa@㷼B:Ksx%ϻ7! M@@ YR)7SpV1X)h3D_Oyo@zXu2jۄY3ZCIk, eLM[ UWZTȘ;R Vf:ʓ1W:jhZmhwn 6c }`}0&Sѭ#HXFv"^;$>EUOgs|brXLW}jvrQ~Фr'kg뙷6?̼ |? Ghׇ?;18‘ű7_O}xo-N;W߬'nԓ7jصR2X@'fә>߈';v@ofz\7X\ ?@c.yо @1X_P!'=ڔU35 ML17H t(&>@|g32 ƚX&BCc \S3n(Xnލyk:FFC=A @G6SEl^@ϊgУϣg c֢[{Ap: R0"]s̸n?_Zl,[z2Ȭ晀hFzY/6%K{5yz9h$ZC@ͳx<>>zA~YhfCzش_vhfwoٳF@x>67j@K lЊ>Y&7-9ƂZ ,@˫W?i[ѷu^z_Pz|nvwItUTf?8(y 4߁%R244: @ C\A`]{y|$|&[&ʷ:RSVa,k nӪ:R~qG '7FR~#)Io&e_zs~1fC׳mQK b܄FFf'|hOHR<D)wtt"%l4=4duF(i Bo%dtE&&t՗oSm_8 \6gu"gsoBDMWrt˝i/5gy Mo+b7O)5eRLԂ|\kM:@g- `w#wFڇ 0(~<^?jgP\v>_@ } MWЕjN|Q=lewO{ٷ72PGۙӟ8%~z8_MhG?;NMnNi3IoT+tR!q1>N)H"S[T!%fKyo)d=2ty .Ε":k{m^ AW+&_[)l+Dl5j22dCgStЂ·d̐1C,n a@BOh:+/pBme%6Q\mWh1~,>ECǴڸ&;гs/ܳWzO=ϑ ƛY7Я@sl)u-H+KH$F6̂e$h%d"]B3z b };@L2h1o}Cv-Q5-:Db^&< 6zhx3n#cE3s)@sPs ^?гhQ5h64z^cp~#3ɱ9]aPY07CRy!}(wKuA -YnvOW~{[UQ ]&^yg?.X8:6*[Ks(bh ͯ ,>xBT = Ghy.iW6bM̔SzӚImS9{;O+ckfJs#A)oPFJq=)D;fwګ8Rou=4ڴJOLq9"Mh`wSwk5߫<1 RQ?( y8J@&RJ㣁2RzNC`5|(C`Qf4@gA^ 4+%d0ufc]cjhuC@W+Fڡ;ɠ!uMF%0oC%As鉁x$f&Qux5w)=źHźTTHպ6:hx5fn;P+uݵ`:0z+Н`h_rXJ{ZJ-nȭz42VC`s>%,5ƂJ4z&Ίl닽qنNȯ4$usJ~#F~v{;+njۮZ504zQ@-t|"41Y!C1+  fzVfOTO'w5ʬF{QZHi ^KAW=elF=@M14{b"v}֫I-j5$ڞA3 <'2Rh wJԑt3ϸ<%PϮt5w)_k*V_TӨ{Pת;uZÿ t[n;zk.Xo[jwZ [#Xh0:ko_0tȌ3zgc2Ot Գ.J$z=)JJgRJkOiCYKmTE%U+5M4y%Xgc8#C@/K̑9r[ƝYRr+==1=1rMݟ /5OCv`d'B,,Z %30:@W+8_p*^&[LYbB4[ {:30z7u,UCNfb tfL謇oT,#eZ8F">jh? ǠV ױۋ=?+hD=h!D_bn6!X0 C:\ zs\ܲFbĬbFei4˒X̮3V'9cг⼩`m-8{ЁЎtpg'6l?/He5A醨qߺ+y2^JtDV߽#_ї%%)HwO[?/r|h 4[,R#w9[D8@sE%0B@"K*p(.z U䱋n+%hcFi,uM~Ӫ?T_ ~wmon=*ZD$7)Ս}=+@73Jx~}OkZ)jtqЫ7Fh0t ]?k7. zRU+i :']Y'|oWCg>J}|G;LPrПle_;(-eb~}k!;>59^rIr K*cI܇h15׮6,1)5Q&表OJ=мy5p^2Z/==_l|GXȈ( df]ɵp%{e<0 Ϛ%xz&ɸx,gM72g&lR4hhĪ=hJA3oC_ܓ#y ɶ:@=o2ڷtr+z4|爞g wv?  Y:}T`əss:œV: nB}XҸ+ ~yWк>n?$~O SodS~疠vYL_/H $EQț+})@+3 @K'4[BKh$^hS_QK/<_j ʬ!64I0q-rm<.Zn%͔ M)o29c|?DصjzMQjL37^RPby ^@ HR>&|@3n-E!10 Rqh:xuzysB)I&MhTDJ bC*44Y8. /I)N[փGōg׍Q_K+Ky{[wgDk"mkÄANhf򵩭@TgU.yb]S5Rn<-M*{ZeoT|ݲUHU_o6Zf; n2zZw"kѵ#αhXx|Ds"94tLy6:k^7/`+tZPX/mۥk۽<0f[g/w:H}sّ7?9@`#|آRz2TlpCdԔH C,:GH}C|f-)l3@1cpMG^wKhVbj[tl-E5gjLQaZ7QD 6DՆ)2 I@~~Y4&8.fykp䕀ާI1*V3;^1hlE+gL,@KRzDm؆lkQ, i4<ϼ586@}@< | zd1Փzf̥\m{lG[\Km vfgeMy5EE̒o=3(rlrHy<9|#B=%`_[lGų+_4F~?T5Q馴u_Թr'ӥEZ};<n K?}t{B|y1xفfKFw_h%( BY䶋=n+e+a-0ƚ^b>2uf]zx, fJ{#VΪ5wrOp{u|W33дV~HR>&hjX*Et4M%Mh"k¤mC@ *Z_ ltUbmӐK*6<;q';Xn9W.(\wER#ejNf0#ϴ+XbY.;+/墻DRs5hwvw)yn+oߨ7MZ lu!41Fn;ѵC#ѵc7T>nʴNgօ|RʭjNtUz)?Yw ouqz#fꓭ/wR_>!꧇R?9l65tj9<ȥb|!q6ahF&geTe*eAR«UyZ7YFe*mEڢwg_}%]YʝYΟ/ KmibiW?79yo~S#lU/KeyvY^]}d-X VTV2pRǪUSjs`jM;.Q_V=;Y#tuS;iAA o~u(%?pS8h =OZzV(1*R!X`d ȇ#5i V6+$݇jULUs>c>a˗#r<ti9VNs\*U]TՕҤĺ"n0 ]JNJvV_\\póZ,:ET] hO}E:[/*o: 0zBݍPw wv##XXF ON'339d4yиT]-UWJj]4tqt|-V7N/{6RmRmQ_pc'5SH?N›vNV]A@Сcq:y&8IL%Xz3[_-%W*"J]͸)Wr7nm.G !Sa$hs:hNɰ1G 'Cxە=N9=c Y8Aq}@O=7=B4G4cE" jHF[UFʽ-r{y$7F4{i@Ͽ 61u4aY_KeLף sG7L ,y+e|ɦdZ5uKRvëRD=гAb@&6zɭ--*dC+͜7~CXps9<il h{Zf{ɩݳ\̒oϿO' fYrV<^Bލ&z.&?͛h4oW\W'VO|kgE^/N?/_. ]k}ga>UӀl?(?M/Uw4G}𕀖 he{pZ@dґP;2ZkdXzVy(7[+OL1K529qQd4VN\r3u@BQ@bIht95JK/7R+1*T X *Mbv4ZF[jelWDF}٢չmƫϬy'̵gԚZsՖ}X;5WVWqReg);p0DWܓ.9sbQyIg%݃\ռFjsN՝a(6Y$elުj`tv7p uVC%-܊NuN;gs6 ҕҍ }Nm'N1zﯧ>\>A0tG0O$| @#tZ^)1@C Ĺ.ɝDm']LРg v!N8A _sM XL`bX l11DcHRx`II=N2t1r^hxjgL- 'KQ3cŕʰMzUezHe,sKh i{-ᒛvs|-B&X6L-sKqE5 dp!lqm \Df@#'$fGNplœ3S~|Q̍]@/X\O7304+ J3LQz&h&;@g S紅Y]a\a,kmoq\B䐬t򝟉˹ӼY~7}OԸ. %yIrI~~+T #K\Ǻih2ǖgٲ,[%fv9Yfρ/2-%cF+."U(Y(w#vdθʑ8 :kbt{mov؟d#0g|7f3{i5)mx\AVﯬ?/ ]uiԔ֜Vr c'&q:)(y6•"p.=߫{5YՍ"#^ÆM4(:MIk*-I5"1ЄQ̫U䀂RWHn)rEncx |.T $b<14Nt:Da(*01Lr KrIf,10:I,Y,0)I/jUQjZy4гFWh+Zsw6:vk55-_vdւ9fg]PcP%IT*4,3; iWvKnË~%_eLU(`5RsFQg:'ȸZLi7<g'\.HzziO/y{Yzַm!&Tl2hf# lF7}h<(^;Y;@Э&ts2v*9k+4kKKeJx^,i4Gғ|Vz]<:&f۸N§;fF%y\M\*/αtb:O2T0لޟbhɭB#X @,4`wW2jSKp0w=ݵuAll\k~g9ڐԄ<+PH'[>'#zf Z!raP1dł`hS~Ր RQ}"%`R_IIxa;RZlƉn \!s44z%Zs׸@sk\cb$[Lm-1NmMQ"*mDabRSiwZ7##Yf yVOɌ UfA hAhϧ<heͯh1s8K2l^=k7D7qqX=s&zC: Ho^,RO$сb7( l44Ȭ%&:̂YCede#$\2G=I!_ǵ2~՞2{[X/,fOSaB@cӀEnWW@ =i1S8~&[ -,aL9'Ń,9)͝nwCn47pYmp -*-ʋh1#0-Ȳ 6cktj^\@cKز8g> o@ C-t-K QJJ׬t Y+ۇ~{míUü^V`<>^z^6=ȪoWʼn꭬Tz UƘWZ(ul6OOU J]^#q@|C䵊f(yAz9(sf 12kxU"HD1 YH&II=4L==< h4kmHoH6Zh}ťɆY z.V)2ªhͤ> Sمt.zrйد@E7\jQ# nYn9̒2&tNk]WZO{Si=62,߂rohVO nC[խrHw'v 9[A1ts*:o-Tϗ*˥zzxAk40tP˿Kz`3f̧϶2_lg؟|[׋[*uF]$.TKsąuD@g'7#Tr'NPT/]|=TPaM3N{)Ot=# z\_:g 9ۣz4wՙ@B21tqXihhK!h.M!%xR84cigXJ놆 <١ʣ1mjGy{mG__}RM)g3_FLzT1UZ ֠ԂIA2CRhEA/!q{܁f~ qzH(%ȨẠzK)4E9BQP*/I!RhhZ) ->Z[V*j]UktgfڤkX4i{,T٪9!*DKJqg] WT$WD&j Fddq#xY{3co!r6S5VrurCuݣ n@i0% oެCЛNV CG[c#h1Fs<>m5NkgRRRMҝz Y".Nn7@܏ ` x&z^h qz"I5 `mPV!R7BH'o3n&<1#?@>ͭ6—cN wwg2c$K,E4GUlMshAkJlCmn.y:ǻ '|ޝqA?qB@OgxhG7SQlvm|yrM{_(ĥ+E1:}Z:!N)'?xC,'.z.88G[_PW3/8E衡ْԂh8$/BP nHwNxGRWJZ[hڴZѿszE~VO^>߬|}' }+o`+{:b޶+֭چ^W jKZaI-ae: `k@bR{PAmh?5B<h—:Ez76=SrY97Y!+dyl䊢BI$eHbgY*|z4چFۜNk1t&Q0kVMɥ'ՂZXɖW5'P8Qv_T K)M;2,|\ޙ; ygD%(,\$g  fGTNH)GcJ3ٛtb}9 g'\tA=t3)Ib fb$M]CJY`o=D) \~4t` >oM:mb\Lz._(kZv Y~*GkTj\çB*4 YRaS2j.:_B1|wЃty)t'n.OuFD= QFHڈ }X%iHŔ/^--[ēD9X"#7a^,4=3Ln0gEyDxq3{A:XgLbYtV&1H9.l2MJu MMf9poh1j Ћ%Ȃ/ K{ {,rp(zR, h@l=Bα]7`C%+?|U<ɏg7d|'`9W(m\ ՟F@B_/gũS"8uZ=[ B~chѹ1qtE-zAQq ̀`z퐤9^-zyB_\RKwj.PvA+&ud6Zcmqn|TtfN~'k5et`9oWT)m|O﵂tucKIAzӦmhedָ_ВI@[E~0d]@~1snvDU#8!KIH* 45X,KˤY47\Tfp3<]a0&]բ-hAS1i{lOU(E1z9$Bg,Wts9ə9 9g1IrYɸW c͌Žhc9pn5wv% zoޠ<,zJy͜o+*~.7K t5Yn6oEz[V@}(9hNBLr\,W.WW*kjv| ]|?igvRoRt2`62mf>~p+V³nA+{ :_WRgKԙu %O'ԱL #3طt;FC@7#&tzp􈕿 z #;Шg< ڜS4fo&zNq3fp&!\zГ77bz%\E6ц(4QRLqyp%7$D䨍1@O4 hPf]A;p0!dž2z7|P*E@+xb~.h ͈4 ,h,5CEkŖg5ixF-|#]gP"г*$.3N&@F@&Ze,@MBa}D8ˁ6=ͤ䛤|yf G4U?虇!C=e@1m&Z=B&ȼD^ IUY+znma;g8Nx2Mz1ol gg:4 ",qoh4IʎL)[I>| J ^HJT):1tx]Z6>+'ФmM&G*x\Xe4l75Ƽ{zzF4e}'k~?o`yVu0aIA^Q7wz~v32ƶA[+z{QLSU;x"A$ 82Q9hfH#LJYX)ʘ1$A"ReTH,zZ]Pd EQe 2]!Z.8@ Bi*=qNg544P~lt6$EL=!ն6ce $Sͳ2W*8yX͔._t.[*+O [ya.38QƋh.7C:_YtiO/FL:q z`~͖-?_UǴA ,h5vM&SWTy[W[[*jŬ2Rs:m@z $YzOBq`B~e_t=3tr X08^04 rhQڈJ m@FzeIw?hA/J&ŔJLE:}m%@a^iWDv!Z.Fz^VXذ0!lDxЊ5+JΐԦ:)ߓbmԆƋMabMrfYf6-bUJf6`lCT]jCYj1Dped)hEv,L@/"VRnW}~}W_hˀ^O<4By'2WгMvѼ%o h}=-Z$vOϞK UMeW`D(@-֖X{ZU8|:}])"~k3vfn+ ̍Ϻ_.p{2gno+ ؛_7?{+YzDd*ghkֳlZ{h]UD:#Rc=%Uȼ0J=2n|0S(JMUƺ`;d+MY+:kdX-7}/G7sעQۛI;ۻY{9N࿽>Ƿ~T2#=X45wo|܎ ۯsu\:gVL$=M9QAr耚<Wv^nhZMa@!4>x&fz&x%9#1#7˂3礒H)YE7*ui!5YFRr\"5U\[h=|E|Cs!ŀC 5sjl8 eۊyZb6Wg2 &=7AJl8)Wd\bE@s97@W\=ϢpJ[igY)`qg^vx0 i@ vsƸ^ =x1 oSܳ@ JvѹN)w*6n; zq2tlĐ{~bp]O3\$C>#CGkZMdf]QDtb8?54n'Gܝ*t^= =3|z[(QʝHWS@g[8|ͬfsHϝێ0ONX,,%:z Ђ}Z($ 3Tg[sK&fMđ-H|LpҌO&wNgއB U-Ro .Dx˗Ђ'ЮQ<GO9J"S@L+@O'7+g8#*R&%JQ @Тkk%õ% ЗZ~IQpҪs.Dd,Utպ&]?_p-p =+QR+lLA;`b7,p f b-rgSXl Mi)8I]*6 ,u!nzwR hr{9-&w[b ^[h2_G h8~ά9A6{pR]UjlH-- Pߑ泿(>3}ueH)؉=?+f2W?ߙ'IFD]|Hd(SGh˯b?zmnmGkk$!@7%*]BF9+%[Sr*I$6Nr_p>Ȝv)RٰڕYض:F?=EO(/N*w _] e]gW~goyn w䵎4m0iNTrI -EhF8e`ZH ?n ވ}bz(AZoBs8 @4lT˄uLdK3 @45th Mä!B̿%"? ;+Q z&ˀHHZ!%Zk5hI(l 1}Y/2<,hT =ySpˀ^"Dz@K|ӳSᄕϠg)6LmY8ua=NefgU={h%=fbhο]hzzmƀ6`k&/ܔ?Y?P^] 39$ -)"J h2BgE. 4-W\%Pݒ`~#{en&OSe2~-K{;?|wۛӍı,z#NJԙ0*JxSo':}HƟC#tz1qCM.wnIs U~&J% I1V)%O+CeH p*t(_3:{ho[,=NAw߮78tⳜzB!qーDg"ͧ"(@uZ36P)<7 W4棌.Zx6&cfW˱+]s%jXU\",0YE6}9aw*B9ܜaaZ6*6P+ = Gfe0 >6F&g ~-vL n/gaz uo#C<;sci<בd6vA0tVs4m~ow[0:FchzӃtfwgnipܹWi?_5o6jo*;EdGǃx/7:W;ϷJ;%;Y%sRLUܭR;.dWZUd`hͼ @30۟5㨣ZUᝥ#x [33F(ӺPZLjq] G>c/(Ah|q<]9si&uP㵮KlBLJ0aoZ1:L#)JZpW!@%%s4_z @@2dLW@HiR!V52zI};@//閱KikʊuEdC'Y.6aHc~f't'7=;Ы@p-p Y!hRj!&Qkvn׮M~*3lV23ʄz6;*8{fUNmt&{Jg7.`CkYZ8pQU'V چR-(Z!#ܴ)7͓fS8yLe29/ځZ~$%Bxn"<*B7-z%ى[bK"fW#\o bh:"D @'ɴǀ.a+WZhN ]+k bvڈݔ 7xcx_%Rp3Mqj?,%o*ӧF,z"K Q5U*wЉ32}LS$n[Z^{3G5nGKK0B@YYRF(D:_ER a2d"Bf"T{$\a+w ޵bG䭰m:< ˧U㿾ݣޏGJVwg)ӨYawci ΢֑)`#]^Z4`@3DIJުS@+#ZeV@DX(BQB%6 zNN @@h."PdYE2yKz~))} 2-Цm>L܌C ih5CdIW1U\+^Etf23tf><cy*0sPx~914QQ|ڷsRrChxБCxo/98H {0ѻ;J~xxQڬ*?kG>>>f&|nҗǵGzUR;)压&se3n;/r/7J=\JV֋FN[ 褧s׋lg;3 zsR݆m$0hqTjYޞ ÖPxOB)}05tT2gzhW:JHQ Xy < 2A˘I=%1/ECs@i7.gZvBO´%Ly<B44BQ"虜O"$MHgH-ITLITu ySeRR.!bR)kU ZUb% )JDMQU;-]fXZ2.-Q%H7|[Y2EL̫,B+"ȄZ-O2| ˵ ,X.ːmy[d]YDN:puNXl гe}<R Nmr Yt6,䚕Z6!͆]n:tոi3n2,s o Ɏs(('29 #n2lpiR&/244΃_&iZ#2:5f'ڄm#'o k3\VHNz` g!efrӢFmXTfՆ0 u SB}F>) ؉ = &h)ʵ.qIRCB.~F5hZX`sV皸{yVD*ʅ?aY4˹ LGRVV.^]蚈C-egYu롕 ~/XRė%Uj UMFb] %Ң"]6oCmT_= ;^xwћ3sUH(ĉ,v?Llfn;?~(ܕomeZ`w#x>LJ۟k=e>B3;t'Ηݖ8K[jue1ZU$T5"RUMUzSQiBVSjU$2pi "f"bS5">:"4ݎQ[a݃ޟ?>br+-q`nԼt;?;{#?YVynvVVf4۷oBh^7:JZ{)[riWb$%9 n@#|hU\ʠCy7yg¤21!%#(xYP :V RrJUA*)UE*eAaֹ"D4 5J[CuA i!Z׺:=N!7C}i5 !<zHzлe6VX{55Z)䝙 0,pPKYTzV/ =b+p}R-T9 [O”353,Јq(׊'(MP$Fg<3(< B8t.dQh"%[柃ͻvfݻƽP·D;dzܭwA=T+ w{v?Տ(6ۉNr3l(?ngJnu|To>nԟ4o6+o+Ϻw{GgwǙٯr_o.wVIvU:bǥQ1sTL,o3n&Ja<ߏ;R;ZjKM0Q`he~3GQ0 xnbAsFn s}ٟÌxi{ЃQUu|Ȟ ނly36PL i`6C|a=4YaQJXV5d!fj͂АfÆ(jMuɜV*gYnr"=+M.BȈ=8GPܴލ1 @\3IAa) ׀[ LXֳҪWX`h4Q m(5 3 0i&7 ڰ.Zw΋8qUzRFh]] /&B 9s@/R/'8oK+^qس$.K}%|FdY[Ǘ%"uMƷ早XSh g8~ 5XRH۫k!Q|X{/|ʜR'đ"~s#~<$n* t?w?HQAbz.KJ'tڻ~>P﨓w3*yGdH ~$O추K!՗tNNt^W%7I*)W'dRATd$ԨZU@DdAFY:DXXN7cp化Ӿ{>iwƴvq=δX:KS;/ZJ&d'kz2W Un# ڡ~v[ȨcQ|0N p/? Cwod7s|ؽUnV{փFQZzfvN0|d|e*]C~}P.ߪn7+rf){>* Bf/d(x-N> pΗ!dz1Zt?Dc 7337QЈΰyi趇H=E6WΆYCz>[!hx9l#f>b M95c&|Q1xz*7>J@)]/Z?ma|腐@S v^smҁ - m7hJJGK-'+Kh#z-++U|b|(ڲ$+/6Y$zy@/rbֳ<ݹ13:CY33yCгC/eV˦i1imr+08&69FЌJ-YmF?eB!I/F$f<AM.jvI!dWm瀶пb+`ye|<2f됞+Y|EXV&zr} ]k_h.ԥ5xvV}c-y'DHR"zoMg.YDޑ=4r,C%ek}篫fhݻޑzk暡KȔVM6sjL)Dg"$I(*ESI=0q s1VbAC"bL$MѴ_0*vO}潯Ƿ^ӴvY.ky*<Ø?߬_|5z^f^OH^_ٞD폣GIk}kڻvG(-K;S)wx)r @p=4 :!Bt:J+#S@HLg!  W B‚g*=Up \^H3IPhe8r^HAz\W!0Zנ.x1}G{1h@t(Czn;-bqw-A.\ٲ+]b9˥Ld4dp[bf, \[a[6bA3Na\8v3`hzzgKsAnrh^8 лIw7л^!oWAkzvnz0VbB`Cg|9.*;58~PojZZ fz)o/DУ{ȻA@?7@QuԽ׆\ X5$hC02te Fhdhe@/c/E=PE^ :f5@G5 LhL (Ǭ+([ɶN3M^S]HB\4Dӗa }@ VDemXMy֫-  3Xgy2lt48 Btް67"Cz!@e]NnWXJ/6"=c@C̪^2iB/棌~ڭC 1#2469Boh@Mhgg[pu*Ƿ4a]Hn)E1˫|K"pֲ εv'p vC^Ƚǻ^(2;ƌNv2lp@ޭ:zB[~|8ljVr{l\FwXͳ*2t~QU{]{S{ګ///< v//Gƕozᨒ?,JPF!sXH_Ͽ:\h9f(_jr% (Zy;}ݸ">(1z~͋y]>{oEz.,وE;38DgT$jE se$·,fY0 M{.^_4vw .f_$p\t ֐RO Dx R4;k1EXϫbe@L+f*YKVгMj~ @V+3EiQV (وG5l2]f˜ p(ա09'ҳR] 42S85gڇe*65|ZWZ=ci#o#*@.>4QBt6 !E-2%'/_!y!9)aqpmkH] ;{wWWC]ԟXL@O[Z}~ǿն%O6o[H#akm{[.6}}"uF$N-2qB%< |y7ߨg$n8+5|rL9$RH ҳ.'8CkL5t'L}ro?٭߽l[NarvX-4}K}؎?ͱ G?X_ELæoߍ^/ﴷmQ9Z&g´G{=}> hʐU2CFyHK茊c@'0%9GrЅZ9@/yh-(Yoݢu+7%7̆t[ZA'Lǹj+BL1, zNr$M1Pɥb- SFr/4ϪDFi$iY2٨j, Ƞ-?(ye^5fƇ~negwFs`ڳ 4:w{~B^%xP Ԃ~kQ;2Fب Qrn^au\nݪu8nUꕞ 22 s l՞kuʷ*oP1{O| @w,2t5B:\7C#C+k'qwnl;xٖm{.pČyhG-Gzo)TO# 1C$-4~3߿C/_RrT”8 RiT,HSzY+y h)zz} 艞>xa@rs^2͓-bDh4~GdLDdڑ$"&S5ڪ[+=gгԊg6fE1gvn۬29d܉s86‚Og!`~qPϩu(ZR Bh֡|Vy:7M N6b@ ;DLJQa2MFNo̬i^hj:iJB'[_ )umJWzzkL/{b6-%@/2x*ЪA=#I+ꪩ&7Ů*3Eqf/!x5Q'O#u"uȜȲkoDzx3xYsLOl-s[kة*w_LP#2qFZkO*O~|cePt 7m SsC[Y TN:XR2UBATTJMHM֤6meHzLI9cq[,L\*lz#~rW>a~!vhn9hGo|_<ӉG6d4^çƅSN^z/h; ~ 0V5zg^J]\D ^?~hߣU>0DIlJެVŀъ8H$J zNeJI$Bp,/U }ɍ.O!k$~VjBֶ̥(]b+wi5&:DPomY~[3j&f$] :30ƀNp9T'ĖpSA%A̵blb(ی2Yxmsk>m %3Yk 8#R/cA[nff!__rs; r!c LYn yB(l`hnܿ%6a1[ 앂+ZhmۭNlԋ01B[л~n:׋훥qsZmݮ7!tq[[E~W~_ddT]}{T{-mnU 7`bOf3V&;N.δL6BzPj o+)_+kG=A`4P>{h]nWc:Ӎ H]7Jٖzb='(^JbCGpD ?/5yg~%/^_O3aԴ U0!BARۄ7A:2c@jWDՕY1,N' :8j !au,=WڍE@KКu^T+gMv~'_{ݾc=d1v9ӁǰЏ?={r;Á]wå{^^~'d9 XV_}:GmLU1-{Z5>QW{~hVdT!*d#x+QkQZIJ)6DZL~4BRC^1{wpb虞iMVP$@5 ?AbOBӘOiH}(C6!@#܀#xkMCk7zbP%|g>>>>*?ߪ>W0]@QBKmS;N67t'6.4#V8u8.ԃzR VZ_/@3h}͈s ;!t1}hrhs32}7c]m1u;^GgݶZV Zs!{>{N`]]h=:8_4.=_D9_ / }y߅ QLtMBsI&Я$#HEB5ݯB`%mm Z @[Z VK5 z0 7.2+`W~2bg"YD5S␬8+pzpeXbABuvͬ[7,7&ʆlۭr}4;dܴ;ev[\ 34y*pJGh9֍ARP Q گzEkn h= `e-JEi@((3Zm\Ni*M3@ڴF P Wy )L+8y1X6:Y<hnEoY콌H@+SEjgX`b@#==Ch=zXf5xJ[޻_Sޟ2g[DDn+ g=mot')?v6:ҳ)%PCq ߾,xs?l}<~kJ8V';DoRWݭ6wCMLUc/36uMmU) 8J+q FmҩKd ےqG"$kt/S{nO^>ge_^A;{mcua޶wmq*Gݨ4xmp s<{w<,:[⨛ْI''ƑhǪ.uȡ H`@ ^nLgApTE)/@!DVnЃ#E7IMKi^H&ޕ>e5MCyҚ yd0 ̦wTRUθW! @g8{2I6GqR+CliTΛkQ^R3ln-oF7 O@bMW5#?'7`xw&b_hl=04fv<_q{B~,,{~w^x)^>xQ * ] a=2nDq+>&A5GۙvnJ>jM0t~Yj<C+?C> KlUWބ <ѹT@琡Q[$:@'xQt+/6"f$Wj|cx]e-l5yOAp7pms#.fz؁sLa:[=dygޒ1c4npDsX#a`th>|2=+ʀ.@ 4Bcn/ǿ" ©'Tvc*К ZQHҥhe%3bE._h۷G2(|<Cن ^Һ:3X']3 i2Yfrʪ6 Y]2$3 +4F5#Y tv5OjCGh-*k6ZVw΍dܫ%$rF7r96r$43N03ڕ+]Ye9HVza ɲ][Ҩv?<ߡVhhD[$0'4Тp wyt( h 77vq˖zihD7C 1_jW1  k@+2nZPj ]Faʍ9 2t,U%=-Hϖ h ZzV5TD=}O>R%oof'Ct7'~C6q"`_m+)@vTd#7kOW;}1ubNޱ&-tLuLm{[施6-#ZZgLmRZx X3@.GȄilҟSU2sh [yw/Wo>}$V≹ ō$8 bkw3iDɝ > xF| L=&gmsQNܧwO+=-&.2 h4S@ah NpB@'Q = =%m̡C5Q ҁ 2Rg2Y;u jFLN,5ٰh7 m\+/b."P.*&r$BRUT Neѐhuchnu'K)n 8njV ư3h6;'Ƌvn QqqIqŠ]:G[.K.0t2Щr/YEbFTXID,F(nBVp,_Os$SӍՊB#@)C;d&<9[wYo?{O9NE8b W$ ϞK-B4qЂEO-7Ag",/@[Vt3}ꃭV_/ǦMp}]%T8 GYrV7|} 1PMX|1ȐgJݳ$OmSG%yWtCsH׺ێ.ns 97 ɚٲG΅x@ϼ'Õ pFO~Y~+ C=C" 18]8bBbgoxO<oy>{nG)y:x:{5*8K,7uuxX7Szȱ`mʘl{bY@0 4 ~'c&p :"ۭ^pGa_(N:!yCCf$MyВP H3@&euI:n@;Sz0[@kh랟43Lϯ>r>9R&i 6lt1uX/dQ.r@9.ȤͰMD\]I%=/ m.kA4B@]4M H1FMsza3@= A59'},=g92nNp9tzXUi%:&L4; t^v2̍G(?R<>kZ<7%C?hOۍ7:NeNnްިMAIZq^@C=bqXg,_)&0]!tJZWZYA]7{K|=U|E7\+F6 <tGt8 oDp %Z ?wiYoT#g, ,”(x3&Xs/p\3!w'$1/hPȲكt _{UW|/4c)^9 +)"@3Fc2fY84a$bV2 u۠0H#7o*,[ (UQfvìSB3 3f΢×Q6eN6:&hjܰ@+2xA7v׀ݲ5p$_w/VpW.X|-C-#DIJϠ L%)| [ hKomAcRpoM*ܩv4m^mOp #6Ж; Ht@NJ}Jo Vgdv 3"`Emv]@0-j.[ExXYCC@=C Ў]^xˣH^-պ[gCpiN-[0ʾ5Mb`@4^Ϡa^ګW{t*YHK 56 ]om6΋?%ۀIDATbRW%e|MpL [ kroS)ՂLo[umRKYYf.eO5UYj2[k7UKTmY&2~.ҷƺoks6,=CvX}>JW?t[jjWML5޾oo8j kYa)*EWXSkZm>,&s }[;5E>;WAޏFo=|in=b X; 6h%9o6gUbŐLy,JP拽;?{_|x݃rm/1/i]Ha)Co[}yPG~!:PCug"o=ONT!CaxR{Lx ?*$ݟ?F@?Ht|dCTm`83Gx 8@g GyȅM| A.iePY6kyCiuZ#t>股u EQ75 6;FKdE(uAz{Oo=j8P108r +CstƦ&lfvx4wl u`Ns=(oWvf:X\ Ұ|*K4D!N@J<(:/D(jA`դmt`7_%:1D hb?s0zEgIJĠϴ%LÌWbLAƈ2!M#ڲn&3&Lʨ:ź^ߐ2Zf=Lr@g˶¬r=H0V݆UaY>oL(M? Ym(\TڀɪU 7e._ӺUK^и| V;Vi:ZfVA_ HzcRV|*W=ÔضҥUb Ln 2ox-0M屫a.zz6=Mo7=Mw`‰-7(p3333L-歰 0 vjQ5f5eYQ@mG6| ж m@79FLj!3@}hކb@қ29.ĀjU@[4^wuE٠ 0t;nOZ P3|U@+2ve7«N0=+ aM]ߌo&e[)6>!f̯ 릒 *P"Hf[6P}Q_sԾa欬54eF2aOmOٻ[c[%}Kj'懿k}mmV8Ԅ&[SZ*[m\06,%ZV:DmQ;nW? ޙ~WQzbHXLk,W '7!+~FZd{&giKfBY 8sȸi_!*V^y?z͟w&9q7E#6c"p\:txSS6t;%|۷ӓ>ǎBtG5ݴ3U)9":jxûGo >M̙ ]&|_Q!3p{ɬ+tq/Xx3ch iO80 Aco@{Q%B>igl,MnVW֕mUm0q36m9:y!sڥ6ꚙ!܈훰=+gs]'>w:w%ݽh'ZIBL.8)'\9yqyP6E-T+waoPw5*85: 1sgn~e{7}WCQ_'P0>"C<<9^gyGv YQY9 ϡ´ ='䤕2VfAhRϊhEh;FAYҬު[ŗڻ==xUaqW}*KGt4.FPKι(Wl-wҥvJɲ@CKsht]Ԋ|h.BCfk9#td'AtbA8C04 (bUC`n}fM+rjޙA:GcX]L< Qx!4,"8x+16[Y\mʀ304%x!hhЍdӬb$hL¨m"nLY @-2|% R,2)H2h^s+[ gn@uC@oUFѵȀ)Zzz@)d @ev-Ρ7 + PxHt頞1 @JIp׮=;4 =|- x#qЊ1 R י,0N虷ֳ᫁͌xC6"+ .'qi~Л @ oc_` e@$@.kW|/4FұoKВWC_, ]3YSEԱfJ^f^.Fz3Yu!6e -樮25DKI9ZEѷ>8@ϜlG̩>X|+=>o?Еo'7=Up XWhnXJSQiʃfPQan`- 陊SN>@9}Ϛ+O#_QF{ȿn;=8zczVWj ;J>g)̑Xxw.-d:_[?~yֳ|?_NJC>7d|bĺt]0䐧vIZdˇtvL]pSU.: \Ag]d=6|a|{3p`ΐ3*<]q$0;oh3I't"iMc>cڭbӐZZ6FCZ_g\fY]RϐΆũs_j hE@o/=.}_1Z dV|q;.la]D*n͐˱`YXł.yZ ,!BY8;/gCըK.9"&+͂nػ ]>X-'Bs~>>_}H @d 3ah>0Q"̀Ki%2AS1 =i![a;;F*B{޼9$C߂ÆY -Z|=UV!"Q/앎jx4pfËչ4 6p[Lk1Z30ѹ= tzvrFdh5glXhÆ%bV`4hti34i:`/G8 4W{h@ggڽUG4rk:33w- ke@+ֆZ2xyJM os#V:{+">ѥl >~Txd,>5߬GڎnGJ_wQ;[*[]i* y.!#7fdZV8jOw#}P&Kϖ{hM?8SpJ;~ɷswuyz{:nOCZS!+$ٷՇGgQm؏z\6C>0Б"܀%wc|{G;߾|u+H:ySIQK(ag2.`p'm7,CPpJ2ϒ[{' BTOVݡ3p1;4 lFz#:y> W7 fh @Á"xzA0(:t "@Qih8=O. 偡g熎ʑi%:ŦTLLI3=nfFMdNv8̏FzS{{μ>ظ+ QS|_opS{_j77НfH̫i2.&B4WFyj/[f+9]z!*5ngn½xo•vhJYC=Ӂ!^3rGpN2%CY@f1Y D~_S^|8!^Ы _@]AU@^]4; r=.VJ E2o( U@o3 /4[w68~V02#6}!: ^XF^x|^v A/z"Isϗtָq 3<~&R>5x@7]- Dm@433Awt30dzV g᫁@ϖ(Գ5fIvKnF ikjA6d6-^%B  v{6ah|pn@[p@ ro)[J@_銘/zUϜL%_3=_\I[=2(wn8&pđo~iSG¡6vl?/?OG[\m@c-\R }JO2sQᨩ:ׄFz~_'/#g@9u=rDoS"㿋T>n Oz` :T ڨcb7MO?|_>(l %ʴ|ʉDMTCF:4?R;߿{IBTdA&dBp&/M"NT\) wМ 4G^)śqV'wrQ;[)9By| b1 m7lh`2uz @煞ƍ@ZPg#s|Kb6ƫckcA6a{&lڵc@S>va=`W `5,ƃx0'`>,",*B=G"HOԁEm4wauKp9t!*ԧ!煀/ ;lpܻ!_pC\>\-@1,x #xР4~8_4 G=O00f\ OAeaZkI=5naۙQ?7F44z;n=ZVqG#C%C?i+-U@@jbu^Nq:.'%q ]BuXrNNWZ̀U$@gFne:'B=!}:uOwyzEF%#X\@cWgCHbe-|C1}6yX)F/C%o0 nq1nk4VCdhtZkȍR.~h |Z@KЮs@.AzD(_s@ym{Wb@.y "ZDp+i>Nƍncg 8(كf}7Nn {t[0,г+!:#=&3סk(Գ%[a臋/Jz/b&KlwX m(iGhVB̧|نE_hЎ+^z h5U2=}ڷE@_ @T*e[)vFͮC=ϯ􆥶aOx г[ Ok#U*j {-eP;N%nb[쩡GoO6s[#m o3W-U0U|;Nȵ0v1UUԎ9vlϜVN[? O$4%N#ֳ9<0#<{7٣?{V2=$9貛̸?/-aܒ+^e"X*J@G%=G`V /Gu1F36FW|9d eW-9_tMq\4xP^" hi .Xt Na*-z  ZJ@ #WpW]*hMmޔ6ul _[׼]u[.XlP]u/r-43 Xcj>e[pFz)݆ tV{@V|kv68. hhNnAHg81[.6jqNq:Lp1``F/Zl@9v>!ـ|%f5G-fl,YϡMv Chx1 p(ȫ[/| &U5^NVs\<> UKK"hbV+ xؐR^_[o=rut]-N+Y.n/-ݜR?KTYk E{MΆQ:P#3Q }ѧL~;ԥObG۱c]VVRװMru՞ 5Me[ fLmE$簔7 tL⽟Ϝx1Ir}{˭7$щ|nOFOϾ/>yN>ejuku`+ ,S]6ѡtW<7# @4*NDœ!L!]Ѕ*d935);UqSuoh~ϟ>:$~e=aa}ޭ_>*h`^:1 +8ඍiFH9(jS,dD^cmp\sW )W|-QEp@<¡36:km :B \2ڈML ۵b{kp1h2:,z.=9j# D1BPeT%FHPDA"sс&^?/<Đ$FᐔIc>IaooyB !/9?ID6%Mq\^4^MC;~'rii)+i%>%&HLQ#;nf'̤Aa<,ƥܛV;n: NF^S|'miG|֫<헟jON!EqZa>*Bmy;Y?gjTE%kK@P!= (σHϵ,8PM4 ݋szc>2޾v]<3`YKX/:p2+ -|o2K+_BC7t xU×~K:_Pmz"@K'kڪqn*2L5OF5˱ tW rϖ½)qxgʆǸeK=KgϪgg5 &~5|NnHzv g;33sptҳ*e8Zrj f7IF6-23ہiv&g  3@{u4~v#- W-=uu\og!=ZݰW7Aޖ<ؗ}5V2aPRx+oH9b֥ՑhMh;O7MjI 7\ {Mi(n r3ruD /\ܰV5榻'fv"G;n$/3w7uߟy>ßN|_Woog/>8='_|<;?yv=ƕx$j*V2Sq UR:Sl葐r~*/~ӻ]>:"٦,Cy,cfgQ!-!cD|Εp OOy1 8vJ; ί}Ew0fm F1si< o<]U@/ A@[|e[ݽww>@)($2.FtJnF5@|7`":4ѥ6B: s' 1FvV D]x8_8G7 g!ohZ2>%f)L[$% nhi~֊^V8 W]n rZh ggJaO7_?~Gћoٓ|tguDc( ͒._}g#o/$MR_{OvQ);-%h/Ϸ \fi^dbsb-# lpa43h4O$A!NJ1'ô5L&Yd|Lp#Љ9 Et/D>t~@D4O9~Ʋ|Z3jOaLB@| 3y;v2%:KzFY]ޅbC6 gk@9(! !/(zS@ U9D_b`[4 n A|;45w^oށBUyՈ+_  @33~&; 4{X〃sڋһ3@RB";a)wJI91$ԨI#3kffܬ]u ^a/;rgۻb{.MdF0tK*?^o&[bsq j/*3d=n$CXo6= xMpb\̕.,c" _З|_W^`wb^54e BEq=jgZ-An^ڢ2Yՠ/W @V}y@/n>4|^?_&hJh@7*y @o@@;W 7.U]~TP#8<׳ngw #j.;VÃgYsnM9,7m8k1qZK/) @Sz,hGqnl2/ڹh۫mku}fוȁ5qfn-B@#=K^e9M:POΌ®2yV_~7wpsp MNݽ~Qx}&"Gp̘fJ)6"r% Rv 3 LM+=UJ=f7Sp×< g3Ӵy}Zfxn/%tjs^16E:H?즘V# (0q6Oxi9lӽ ߄`{ ̩]ۗ;U㱨}gi3yXʡ>#Ht:+8tJ6M9{嫭pp$ o^iɋ]X^oZ"_%@@ϯ)ueDPI=oڌBS JcQn)ɬZAUQ5MTdQU`u zPL2}K>h~2oQ|IS'‘)~G=ď ?}\Ŏ7=D4 O}x9r߿`-N7rB*r t#@7'p8LCAHQkK(Zlgv{{޽4ݜ$^=8խ!ux$}_kU3 *nqCCGxĎPie,nf'U4<ĔT: g,[8iyEeR(|XU"~Eij~);vzS'y{ӋjkWCl9/"ΒQOb7v'Tȑ3a[[u!tʣ %u.O޸,'b0|vL\> ;)e+LVg3L—17 <1<\ И2g:/nv`.xچq\Xs@EC7>;bľ<#9v'n'pooh^h ć)> u 0nٞu}(\K -!=KlGd;98on- DY@ ?XϪ)-n n'$Ā~L8O~_ , =kKՋc"ETzA@$;r,w>9.o3~l>NRLY6uKSS)s*gRnZM+iU֤|\' eU!titʓneүa`Xߩww;{;GQ zxLe=OφgOvFYp7{VwޅϠjot^zb.tZj嶦n;|k\ghfXTJn1+%ev1*Ķv!U?5&Qef9HAE vlXA1K+9v<~] :gҰw|ZJaMPX|ېNejio O~7\>~$?mHOœX qwF <:'^c4x@,gv=~sИɫq"!avf C@k:&Ggu}7fflыHv8{+%ب鄍Jک8@44&zk^H-- xiQH1WS|%Ŝx@;tU@yg:=]#&0kF'JܒEn3i3C̷ 4x6G\h(mN6fu@x2Zg MCBo[D~pn͙Es@/}`7LʆYݰ6mM{yYѹjzw2`p#IO ~t5 X>6*•ogSOG}G^nq+z[;S?ǶXsbŽToZ| bz+s`ʁf@g Y%MoC%41)L#ug[L)#?E'DP uLKI<%Ai27I'9XQzR(䃊(7㪺WWA?w;__7ROJd&Ob̓!Wu(eq6{NOsҟ?|b}7%L%Q|6MiϰQb">HZLR:4S)Lܠb] +wqiy=vX:9v{='w >Z&v@rqM%Ar ' ,p|_o Aם2:3>Rg!x3";فveN 3btFlxXŹ+=(&Ƅ#?9!svlx54u^1^ \8_2}U@;,|I.= lgs8O˽)( S%sfO b4-OIE>+ x[4v PX>W=Шzwokpkt=7G5{sVݼ+@=hMY!k3i# `: ] @r aY 4\00dlИqaI3 hJ߼8hGt=){8m@ga!=3({A1 >,Hj8@ /J_h\$h"MМ#Qї:l, Z#/^r7K:m(9@g>Z8g/ h = !aR7MKiZްW6Us4|qW oN 7Ʀ>{jT'G?W}S'^>IƳ[yٿN?fQ9д[O,Μ#gcFo`Y Zmt6`/e#e ۦ`J}D/C꓃?߲Ok\YD}qcN+ ^bd,&4/MeZ'<)ǵqtЬۍxsAuw=`1< shGΫ֓Aɰhgpwbg4 :V+t[;z rzPJIzSJPP _EZ-ȳJ0d9‘2a% ;bv6nZy=[y 8^+R+z _м7:ὥ{ռ"Z ٿ@ca3@[Y>ߩ6:;^:so,=qFqo vmL%`tA:$Pϊaͫz.0 \0?񋻥_ hmБ/ h!8{^4uzcEfcM:,=oXJ:kY BFz67:5Fzczj %3dg쨼,=yИإS gzZPOʅFUhէhW>~џO۳Y/׬sJ5"WDI$4K`b+qnq=eI{ 1{kzl95f [6`φƑ\GR*aRo?zu"M/;s]![fs "9h-$@qTh@[<尧:±u1_ )X`pacw0?V || Cӵ|Soh b@Ԕ19JFŽ4_-|yB=“ 1~"p1G[բ4 o PQb>@|/.ZrmmzNmTkFy y1P2'Y*uN2Y6} O蹡s0dR"MҸ7[X[|-*лCh]m4[#t гNoauzo?;h UKvn%֮͊Ш_j/ls-PgjX*X,)P\ @鰒 ):{W襞_hFzqچ :%&,^9`{h Y>SeuA1 hW߿?605ٳ ^ lb&/4@zN!@g!gG.@;г+ TA 433sqg$~ +Z倦le!{4h9 %P/4!rw=B=4&7L7s3JYgٳ4ؖZ 5 !;5k['/oU_x5z/w~ѷLԘ92;H5l)-?inOnsЛVYo+E%=[wޯ~Hx}>S<83-|):!I,w 75=tWVN ρ3R@+iC5@/zxx1J?cp܄oƦ:G8<]c/A wI/n]w =;_pb5?H ΧYx9 },zF>C90t&}vЧ9'qIqU:CC_(\̡^eoPFhz>o  O}`hN~m>{ht1ڙ^l @w GghT DX kBoZ+5B9ũmNmF-ZQJ9$P@IR.P ~ @]Zv *o@=yKOc_MO?i=g#]:fhfvWL"(?@~`m/Ua5d鑋=p x}8Ӌy/GK6߉W#È|X/x"%YB*\ˏ[zou}'{ⓣXMXk"U1JB_HJ+nuɌS;M&,$bϚX] 2K.5KUD%%=H(P+HOfOۙ]$pW{i+LV%rL{(WxAoMa0\ b o[8} yȝe1ϋ@"|4p?3sS9][ËI>D|(/G|wCt( Ƣ#tw yg%M W/L;_{&ܱ+t K!Z_/d,>FACgf ) "2t~P Gt|)CCkКw;p؄FL[`64E}i^px?aeۥj=xXz~{g_wo~}?gW?7jZUN.plt[lõ YJ$QaE֭R)ltH^1I0m]VeQ\fkQ+.9s>Tb7*Χ9=>K@W0)U#bDɅ$$TSxhI$1(Q%Rx#7BvhdpB!:׿%a< Cϗ7͟c20c`h"p"S$8%gd."32p Oi8BQ=Ȳ"7sk&hج͛Y{^ΤV8M*U8sFL8 HNxg$jtq~9f4{NGif3[+]X%/iIgpPT.WWu,>c3`8CR EϲOTNTOU}R&pCԔI]=jХf t*~7p99j[I ]t;WUs5_FWig HzohDgX-ժ&[Do6bM-Ԛ|+-^jb/*|'""6)Ѻ(dQd!K(9"wŜs:"춞 W|׬Y@W_}zw]̂7Z̳hm}ۀyں9#@:loh =4m@.mC60z6o:5Zw|K^hBg2И>9hѰ%Bi8{lfh8~RڔpBkpmn@=ΐ (U3ty% VF|t@pX0`Jwo7|áq.iקlz^9rb4hV MRpT6Mw}Szt^Y޸Kg-gSk u7]oI B~'?4^wz]{x}?`<2SSbXo䮚%E0^L޴( hvV-۶mq.j=P->vo|_Nӷ❟?D]o~o>?_.3,̒ |iU\֢RpUE%l[ &]D3ǟGEidq:;Ne_5[]KB>,pVUtq hld"!w?C`&dg&8=00>_2X`bF- ΁p3,; f >9JF]JuUxƺZg|_5Ph zp] u[9OQ妑3ZU=E/% ?D^Z!j02,\(Jt슎]/T.v5?gB 1,ϡa|v*N<BiI>.+녣Fhx,G 4t=CC7emqzOC>.{~r0.;Yo3:j t%[zv=Ոom-*-6rEHd;\;o2-J9TPTER2tz  fJd.MfoE|U~Q_ Ky7E}6VlYPNz)74z6 76یq˃>@یsx7F7E ct @蹞-4k:n6mygYA*B=J^-g_U8ƵAՃd5k5Y3o@ ] :eקF]Ȣӆ)ah*il8gmscgx7/@PL7956'&if,\>~oo?wW:'kX5O5w噫}''?ܵ\2dM=Stdu ĖS3z=e赗 :bLQоswOgd">IoS}GGrg77[?~.G|=n<-UDNA"$ۍE|x5Cl+“+*nU0nl2]f.oXనq[o/ Rb.)j@m.[ңzo~VQ쑜=rЙ${X{jmTf"UHeX3XahL~1Dh N(Gj =s3=ţS_c1Z`!8Ьl @ثzbOz~?sZ9< 6tA=Q)8C=G2S *)s. [Z8ԗbZC ޺ $[:K AaWhG7cgxng|a4?/A!Hzka"]:įu.^K#FVbcJ|04N^(Ԇg(h|T̝*iQ:.|\U5u\+vi }*+=8G-;Bc[Cd נϻ^? /άs5o*.#zN7(؊׷bX6RKP[|-d:|ǥ{lIt7DӭH(VAUK"!J~Y Hu@31nz]ÿAw{_@ꅀ=9+'r?z6@PFܶFz~}&V }+A{c7Cz{`@a& hĂHXA i3g@ 'o  ;CwPRe 4=4/"IgHFпF! , 1k􊡙 МX:e3E\z؆"hQt`-o:h 2=k @Vj`eFvǘ:2Ng ?K}+a=7\㏇?/z(\}3kb@[kxU,!R@̊ѢlEjn}mѱnj=#WMp^ Orꛕ;[ڃ|PioLfIO2q&qFIve!oq&O5#:EZWxWrVN`0*. dVfӒwHjζ*M;C%/ԩb'cU'ߺjTjZMrI&w_Ey{[B+It)PB3tcʗ43PTG!f?#c? |q@^vENi´7<</3/[4'1OC0p =PAn0,Lݍ"i44N0OZXZ{0^(v9\v&fR~ϳ+KCO zaUEqݭkpz wGpC{ά>;FG[z_T4@=om[Vn*x+6crSȶtOvA\Mv#n4э;dZl•B1(IDN"E9 kSgP&̲5=NSwS7yR1OJxA2@ wvAbEyWDpPh6_3㔃 ;Ø%`ڄwh4׳8YtLQaR@:[wY;ygWzAs=5:J+8>t a=4x־\~gж ЂSCN. : %Q4Y oϷ<'.KogF%vOMlSw[~U|zէks |ퟍĹEfzvl5fe j4d_ hI0.Y]~hh|ܘ&;spL L섋RxOq!>paT wHi_&`#LCx%UZQ ~[)>Ξ- lfhÒ[vibshZ;C8e%WkT- Eio>w?nmı;<RǏ܎\Ef`!Fx #+~@S-*ئ=2=*z? %9&a NSod'<\3z%P90 Ah^4SQ􌆝y =cS>IG&"{Xv\ȶK\ķ ]:bCweXKx$''24]@!1pcp<ɪ9h;[W Ͽ&%}elxC/8 hh Z |P<)H'PEW G^ۥfU9T5O؅[;{rmz;dtwFgYg }PmYz;N/oNj1cl wD9eyى:l[BVN 䔠@/) 2 j_e}K(d*%8Ei熾 ]mD-7zvr /6.361³8hO)@ p6#v^͞ٳ) h7zX3YhJ9 L:nggJre'\(ˆ'TrJ@@GUNFk$Q2[A0YjmLuI>e7F'Pܺa&c ` )7 I 4$tw|>O댢(MlV|nm0_^4$M[`D oJ7|n,^0O'ʫV /=uʏl#g홭:{Rzh ۷Cskěw`+,7 }v )܆$nCeQ6T`͎U϶vy]_䐈~ zb)?}=ٽ03!ECN8bmI&Њ;j!_-LO-, ibւ"-v†*٭&ZmŚ7[knN vd@>L:$C]$ ]h QiuJYK8/夣t"?^;?xsp; .TH)R~#@J5hx t͑(Y+:av"c@< 5&}+CC'Ax.l%_|S i%ٻ%e4|ܔзJ/?h^yqXE xgϭqn-hEل2u3ҳL쵛10Fefth{ 3GaVCl%q17:crh@i ^1^ѧ^AFmE=@!:!1a6L\[<`xgm{&ف;FX.4;v(ӧdg<W~Q~*=v(XTT_5߬}h<ȗZ5طitM֊TMaMx d9iM.v֒V6+gnؽN @컩;=1;xdbvN(2 1 P 4`p[n~}U+ޒץ̅rA.ll7Y99k5lnfՉ,X%UE‘bē|b6 *Tq/WTQN$e,*Gy {_}ǧKrG$ /DR,3Da*Sx\@πr W+QV̐wh0$ge0}?og3"ȟ{+2vAg茤J `#Ch7H:UX C'?t 'thʄt>DS1͜Q̌zfltƁO꘣&uc~ݗ}-E~TenPaXؠ"|ʷ\ TڥXpgBgk_vxWw%o+*l|[zy0"Cd`{^a;r;p0$=F1=ؓ07 3Ă,Ϟ@yq(Z- ˂=4~~odܭ.jZpS8?#v_q k. `:uJ]E&{Ex*O1tAI ZJzQ:lavE'r Cl G! r{8&qw:3܁Gn ܫA[AN :r-uR{kV]jVEܮn-ݮڊWڱb[P;N,׉e:Bͧ:|y.'Xϲ(ߍƻdNvl7"V8[f2+yP^"fI9EIq9YR3ǀȸA l/Ӕ) MAtFziCˋ8Bpz'Tk^X 1G:(|$4.Ds_zs M/hhh2 Mj@K>Rz+/L v @/flaF^ &ZyZm@4E?sn4Ŝ@ٮj Ц2ozF!@#D,* i)lpϭ>uP&}] 6#{:PlO7+rmGNک\k{Z}d>?~Kg빹*^ؒstF,dkFGdZFܪW=g,-*`-^2;VWi8-i#Z68]g >C .6lmA FU?Q'bUt; 9G64x<г՜Y jhMyܑ EƓ|: )ReN0sL-HX8ŝ|iW,=~}D-RR+Y*sVA$ 9JP4@mik|p nf݉Gwif Й-Qnk{.~ZQ1SxFg7"gDN1{Gjϋ4:n' LLx MAIY9c"4 NS)?h4 ]-kZ^>lTj۵vu[C9F7Ga{puS6;m5;NԇUA2:#=C@z]ו [v9߬[T9jfҎ:1#]^ ~,R ';\b5>4LC'zL#kE2yEheBNJg\J|$24"4|zcYz%gosn_'A;y=7hfYh M|@L˄Z/4 9&mCہ< ZD[Q ^SЦLhŀf w4+X >jձ0}ԦuکGzf_P'(г A;X!W #8z Ab>k*A!4NJ>[tM%ZGFdsC;~wꋚ.}O';/L jٟ;gđ&7TV;*[]i(tEZ+NϞ/ :%׀ -W3jCVcyԶ^:k w7O7ޖӴVWZduvPjlyU vkf[L91k2&=(sFKksJ >_}Hi :7 9@'솘͓JL/ys荭C^:ą~,wTiO~PSP@f4KS,ΡnY<΁p81h'4O ߒ7iG d34ӷ?o{o|_maPu2ǝ{ ]v=`ho: !@}̷{p8#O ;g>0.a70Ey9j{% W{UW5SZ5Q#kUZE!Э,i8!PH': H59׳arLco`&oc3b(]%=ā <,%NZtD|- NCǢ:"wECoM9 Bv[/ׁza, [a4ꕇ_*QU24t{nwF=dtE%[dCETK:dMp۸K&gnl v0B@\p3d\r}IDATL@QG2LE|sv h81ѳde4]@?D @cY=ШZp 03þ jgg17@lnݫ ?m=ԛC÷ E@[0Eӣ8~QdwhqZ@kdNNNQ4Ʒ4..IzfťuWm ?ɟ1E@{}"atMFϗg"^w`5U@X9.g@ݳzfh6B.}@Z~@cn`s2@oրvC=VU")5]VTRrKYflUG{]q/ m]XNmmYxo5~$>c3}:%ZJP g1vg ̹2v UP5T冒 ?geu@B25d\R遡yQJcNn+ն^:ΚU78k[+-1h΁Lɔ13fclș@ztN?3zmV՚ZKMgFiE@5Y:cԤ4A Pyҩ`6Od4 eo0MfٍDnw>O^o"M鰟g|YK@E@E@itH_7(Ad;{,?=}ouOr?\7/:w 3@ۼ[67'E``· #=±c ?8~D`$,ˢal'J&$1L R="+3*ө:n&i2&lUkеU+S"60tjɦ@5tgi@g))x܌퉞U=ghbLA8uglCwQto@@C=ЋC1M=scWiyh z^Ί-Mq$t =$A[Y16!l36ChҰ[tK^/wнqCo5;^_ovÍZ_j 톨ZڀΓ-XG8%@cb6Y]Ǖ*lu6dlQP!P@ <46ʵ5V0^ t֝>xp-$szBƅ~<=N|_EӏHDgyx֟%Y {*34`CF(wi|֟_pdMFn?i! #Z6=g'}d 1 ;C ¶bvI3ib,nTlsWڽP5{\ֻLIUjTj偞fjTc-Pi%fn?/=.hbi|7I|ql=1h?n&]p/H6M9F ICĦ-!=t>]$Cka0h!A{ЃjoTqlm6ۍnW4G{Ns]n-9ߞ.깞i|nRВKsZ W:,d,b-:֢"-xƁ({%T[Ag>jcu$] dsdڑL:q{*f磶LdD_a2=%Cߔ%Bٞa ܲ-J(_֪ 4@C:KiZ]! @? Ё?3Q6zFԨB~"y:x=/ziWSf=;TCT[wP|+:b@=K8lK2&OuO9qztԾ<-gWʚͯrZɒ"qKNx,?krmlRP@qi&)dڬˁ dXϼiWkpBjRmVjLyg&nZVzjdDG2|(cWB۲ZXY|[ cę?קNtSpP_x32{ ȹZrgMnA=J+-uZ)S@'oNވ_ 2&TҲSkj 4F4ϥR箤RkW44pVjs:t52fo1mƴǜyԖaܹX E2W3xoݮwRF:;NL+ą>K(Y3@d2d!/Gy,j烶S-P24$=?u_~ }N4ޥ;p]&|'?7:{cxth̀=K|Ãgg?d#:xL:c' ?q&V_Oiz3n FaT^m5z7TtEʛf-&kG| Uߎ\~#R-R!KuYc[!NE@%@=ǙNHz S=G,=LnEl{w$= mC3vAOW6cDe7V8LW:~sbWvbhyb5FhCtiř6XGwcTG:x_QԈ4 xNpb~/xWm@) '"gt2=<_I\ M^׉O|}@Ka"e@S̱#C -:OAC/Z. °T fJ_aݍZw۬wxK6T_*ߪti*s%Rn-Nhٖ6sTsa`$#>/'h b8 `Z7/Z+dSTܜ[ +'b6y3 F|9>=i)B%1=@&@?%Ў7MDdhi@,~kBlzT S=QBH G8텀x2V Lz.ؠE@x,y hGʀ]@WE=/@]@큩!+Y`SCMzhh؂MA@K6©&E@OՖ+n Zz)"U ZXզVkFAf.ȬeгZiН5xT@+E@-YxG<\˞NУO6?w~3w<_2ЖĽ?kyr[˩<ؔ  紹)35erU2T)OMN+T|p(Ҿ0MjZ3tFΧd]I]--2Nh:-|ѨMŘv2.7#,tn~t?VRLF0YĊX*sǏ^?o 6NX L)C +;Ҙ'TI]'9BBN!zKut9xp |ECwpoz^A.$=YgCO8@g4~!bnNS<=2#Qq4BN6Tu?Q-To}q~<_}=RXi)B*zzFiŘvn ,?LZ]'Eқ$EP[ 8A{C>vG@.ԅC@?3q%7y8y4YM-@ M14s0V,G$t O@@O |fό 9Pt9߯ҠQ7˽fۮtNO ݅еކtOamUm4ǃSJ#OtmХ%+Z%Z+p;lfL$:;g Ԧ6uIq ƴ󵀦@ -?u`tKXM k}ec:}sW ό%=_hqQASCW4gM'RA 3Z,=gh1hx 14&-@koLg4s@N b 2bCH'ys)g8Qv8m5& 7/5ts=* tI8@ [F :ʫDCKC_i Иhʮ-*NY=[Y~&媰R!9lkz^2etU+px9#?@mг  2tF@+C91Dv"JXQ{m =;s;F̐t_i_-ۗ-E.sV5CqPO/ 99&e\)kUr  |ђ'GSp[K3Xf? &&fz4[-,'42|2f5T:փ |ATbN%zEj$FzqB/C$jo$LHO=n{NϞ|^ t+~N] [ӔAO}Z AC? Y6{Ptc@  !3™ Ax h7:(&@uOGz!plwjHh8 Q_Sz57N\IsM)#=j"#פ=M[jx721f*Eh%.P8[2wG+n )+ё\֢{%or|d.kܨw~je|^{׏^zo{jV=4>E*nKmZh [Q#mDqOiq~@@SC:C=Sc@gF]w<wpcs@m#EIh7>4vZB|NN / jN8S':&Ա:Icip~/#<7{S'ASL>&`hx YP$:aБ404<jp44,wG>7[6KzS]˷sQ4F%,@%@Wj%VF<~Jm.]6;3thC6EHVD3ۂצHu*8-@C@9@HZ~^ =ђ;wxk$a/&xHz>ճ#8,He虡3k^=h虘h,}9g0KdԳ)>MQ ~eoh)op -D841KN¥vªV@h^߭v5vaRKwJK/ mպ@6ˮs8v tI6'7 гB@KM26DgGtNGLWU"ՠB+)q(^-2lRL%Aj@g 0LJiF.- R0(p3ɂ&bY < veСDaSt)nV>D`@茊8L7Xg} l@†@̈='I32x'xV`ޢ[^{*viskaz5Q/lY1>đhx1|uЂ%=9.sAi`h'%ޤݟ6_ZQK0bF&$b D QֈtF04A ʀzl.CU\cm@=L>郇W9Y nhIO5e26 kQfgPrz%LbW*+)(iQ)a PpYA="c #-h(4G k9I2⻃š!/^ oN[ []h(-g-sE={`21pHommX8RfWݟn?0U^w_t[2w,=p[[}gyg%^cJf(CƚbVŠN><䟓o)ҫ WU<(yU0GL =Kf҃\V1ajJLԳBËeĀ «YN*7_[T륷 ]ڂNW0F=(g֥lۜFYҝ `.Cںk㟝TxyoRNJ'wOV8_ 92DH ҝ],`4JntI7[{ J"-  //3?J}9ߝޝ_o :s.dOZ8};.5}9C E0!0>#A;b1 N'$v2v13aA49 |8[[|q~ޏ/_h ᅊR/_~~J؉lV+Fj%NÍuT/Jvvpt 04=AC=S;bG@=c.؞ ]ujv^Op~A.8qiN(lHzj -~pNZLE4Üy 7saN },ECLK/4HZqFHo2'{ aG {±'!8̉!D OG>?yp+қF2c!;A< \TJj_Av+w^>VA7A#Pm[ Щ 0`U6jZ-SfL7Jz)Y++X-"zT\ %:l oБ6 R\b;$I- ?bte2 _(D PM?hnzٺ'TkX+8Ik$fGm5Fp~#=ӎcOlɐ5Ɂ,qkISzH08isd:j-$~|ZS7GEPLѠ14.Q81|bfl4&I84aqfUt"/<CrNeV&xZ4h]tPz85t[:AFC@0mǍΉݸ6U@PT T"drT+Qc _H%'@jg%IMn(aEP-NaT&9nyrK@;(ȥGzP*zVQs)⋃0܀ x ,eFf_ '7&ԳCZ]z.z=^'(h7 =yP@@{=@{@i'0WtMI/a&%c&{G$f@C&`h6=㜁d$m (=0$ Иϛ FT C@c79՘.&mʦmZ΢ ԜI2(C@I;7f8 V@~&.PX6tHtY^R塅d,i;:IV4-ˮꁞ Ƃ\+2KMn+ pArgؚ ȼ}4؆V{Peo*/4'a(޷8l{KyUu o~q-w+B XOm9f-]vʀn@+ \UgAzV3YEm r蛂tN)gWx|W\z^W2JF}OٌI%wdpW@.ǀHע/^O~fv^ى4z8 <]q'Wl>gh.Cwp 3;y+p~M#}f>!X>|4nj﷟k2x_ǏiKdᩇ}?}Nȁÿ374t}C0!Cx /x($zD&c~K)b'MNR[9.<=.0"30&p~;u6v-=_[Y_/> W+߼ÓTn/ MZcEi{ zq';1c[݆<=I:omcnz^ A/ hz BNԁS@Á-ԆΧ7"o\$s |fN1̞|% gs QBCSp:;t:|BLr+mdӠy@ Q^baX*+A2lJJA ^"-YMmM\k)Z\й)W3r^N˩j)QKX-ÅF(&kk[IW]ҦgQhN z44 FHGr (\wGjH: [$j G- L734mO3TȖ YS%ɚі8aVI| ꁿ<6j^$A9bAS8h ͷx gÁPs1ӕ; hg@fgݢvX/sٴ.. G8Lfq*~ nFu~_)GTJgT~ h@dB#'%./@[3p"(g E@ oLFFhy ,-߀7=[Z7349fzn52kCh삕 q#5a&;4L@ÝZܩ!kE@+8xUۼo;)U@O&yM\+̊:f,rxsg[Ch*gWjd7UۗY/ l̙л|<'b|,)-'uj*genioڍo h8 }%&=KҸ8 ڢh6evN g C!C \n/~a݅nn1H6^iW}-5¥\<ړ&.t$4t Lkt!|#X!KX`5vl;W;*x`zs7rۼbvϖS\TJC9 QN+Q(& ~'vCA8Ib?E$hWvl^_ /ot}苻Oӹhv=R* ZapJQ]hh ; qahÐ]gm.B,vgz hz4=\:reshx /Z4hqzP_U@GC~"c2hh&t&IZ4(s˥~@7}t4@+'V)Hu}7V`Vjrm@gL@ !`Dsl мş.-zr<{u8q&\+zf Ǡ=MX̄Mg3Κ ]Z¥%ZʡZZ@/Xp¢tJV\5gr>Y3z6&֪g7D=h7Pjt]En=Eh_;Rϵ{W~:To+ાlm'{\剽UvCF U_Wsgz~GoL&瞯| hɐ3scFSKL)Kh!LҞʙ ޠ) 㯳.F0q'L6&^ !ǁ+h Y{jCޣ7J |'n{nӻ h8 (|J4qʒyQ'a$LFu>i:SGI Md vsԎ@miv,%f\aFz _ݽt󐯝 ՗z_tQqSx?n 6W{߽B?\i5Vd9`h:)$Պ3 S]2d_^{~|w =:2Cl@DLO<$Nqk:\_  ڟAGSpN:'A|rIA@2CC yA2TnzbW@䙡g @geLm _JTNWar9^ h\3krpij3^Gs=@όt|3( ^9u^tkg /Csu7WsqUW\MBIG,jF,%!k&dMc(sl r]>`^>o^3b 4Fl@#Fne@#F11 ެghLl zgSv~E@ۿS@OBKG&^`hլxܯP %PAC+ȉzP&5$=mw+YuHl 8[K}@{wf 3a_::ڡcmPpfY):ws]Z\1MDstvksrMZ?Kp峭!w4Q;?TVrȁ*}\7C!Ϙ笽d5w ǣX|ڃ澏n{g{`bKp~ÿ6c|r ̑g!h}bi9Mg LL2)8^<[`v V(A7oT 3#:o&pa?T гԺZSg7D@{i<Zk@k74nr mYʆMb[.ՊK+"(Wrʥ)Dϋ*+g-r"[ <Дnhth /%Y4zqit)y9>rZ_ В}-x<9;vg^hhhhy@[ѸCB9!xڄg:GC htЀI#]3={n)z2aհf5gTFgP@@f[ gSi:Uh!-L-@UR)!:PE䪨\ Ji\[hU)@+ x=sZܼ!ݜRK2kYnŭ gK9=~ Y3|)6"r )3k+ss}Hm/3JO?ee]Ex{rok^Y5os\ryF@*ӫ_ \fhY0J*+z8}U{ ü?MG8L ،Ôs3>Kp QJ[/xr +Fy#@+C`9 ͺr;ϺK򵣁A48NRY$vM@/QW@Tu*V|OG؋#E}Ow|s=tv@ 7YMR$q#yE ĝC|N dBYwcz@oYhGUfTc ;h0͝vf[mw֣Xw' :ʃRa^}ǛJowz;P~o'oFgq,U r/\iq*[+, LMZlN^d&$1"MHgl+ خ^ӽϞAC;taGΫIndA"',<±hRo˅>2-d@@31˽Cn|/D(LTsFU(@LY,ɖe9v=静fvggߟ@9{pJOx7Cpp#Zc3NsΤ:;y` \ .ZbVl2 czX{kfJi[9@W SjXzTcj\ gP &@Ś(@g}@>H_nh?=}&9=uОC`5 IYI쁂їx"*_TjQm2N56ylx@OnF5~ǫ9 '(*CE@@K?sHVl8AQ@zV<@8@]Wwq WQ*GM)qEv1-hŀFA dc3; (^.):[Q}0L9h m,RІ4ghh̄_%:of͖Q@LSC:sDu1*n"D.NϮ_eW/ lǟjǭFf$'ֈ=*x7Y% ?$Oem7Tmhhhq@,x!NїtQ( Ðp)9herJzZP_P\1@ 94B{KdoRķ* #[dw:|w74+2{*K'҉2Ӽ]{HDڛ"3(?*\e$K.ȠEh˼G߹$.1?E~=@7vӊh⇼cK/ tI.jUUΨt\؋QvW :m\[էlmVFiXfBw_{gR ֳd5#b\ >CC2>Sg),e8gR̳lإ`/w˝h<xo7=k=rlc;vhslfۖ>}Xr;x^L/E+1f=Ao{j/[R*_6K۟-䞶 -P_n/G7+N8-/Jr3P!kE@ 4#<'Z^Cb>(:u6tӊmv܂}a_E>73 O~}@4̿o!CБZ,z1]L tr34hn#k@ MhФ l#߀.\C7,eÞRйQHӅtt5UcЉ2+SR-RGrt(zƚh7>om@$I@C )'78@g=44Y)3 S+oDIFU&"XP]xDHj8<(cͧqO8I@3ǖ_h{Ч{8eWy=Eh18@`08?ȡ!4FLmw(\zU%(D6.vqBZ>54.=6-E(QR)JPf=e,攚di\ rC4wt_||%ZЊ =K088 JD 4=.q@|ΔEy.?S:? --W@C@spF֥tts:ՕU.jwK:u.=K*+[W\OJBkwIωOk2<D zN]l"/6sx'y8X Je &.g+@tY,kUe`TV56m;\[ ~e|lQytΞTTrR{TJmQZ|I7-PrXjZNlv6ڙf3/ƘHm1R]זcHu%^[OP[) +WJ[LϏ׿WV~v8/7~[kEf7VYvuU ^:M)p3 7 1 wۏ,- \{vm(34: GFlǀo6m%>g^+Ivf>]$;irh_p+ 7Bph-^ ЙT_e\ h6C]NEh6:ů@"/b@z$OL9 D[p5/h6㠚[+Q1ehtބª@H b<lФ{_ =91hxps=n;߹)%Fo @KLF$5 @KUFOLmq)]VKXTd#MHaR_L(r@3м wrzaRA@ ڣD}JEҹ24Gg27|&(泵aM0EZAQCb/?¡B$zЀbRqh, 00q_شe=_3 ENMiSi=虪Xz6sgߨk:yM3G|"(멛?[߱շɮ8% Z"C Z-^.r&>ufAϼ#K>"~t|f:3X^,V~ $JYը:Uɨ.Z41J 2z!d'Kf>ti2F=T_)|pw~e**Gl5}T$yҔX ^[cxl jĻlEGhn~ὕ?>}?o=suspמLܰmC+у;&,ͶUgʼn]o?[b\_>㛿8\{1.ht)uJ;FmfݮooS[Vaq37n&J+Kf'ʛr7S @υkm*}}=w{NחwxgsXR`j T TzgO3Nqwfv<-2u aw\VԳŵivnrzx~ x5뱃v"g]hУqW n%$<3!=Pf  kj$/ËB"ͧs t@@-BY*4<4c<1Cv.Z1U)'Kdz.s?@M@瀯>gO^@iy"&8RjRIMj<ڤe.]rabh Pq5pĮ"q DHpB2[&":Jz&R%x=2 u+1UX@?4;_ h8љFc:.˰º e.v(=CC{ F7A- }.%>$zIF9~ZR5im[~.Nz6PBx;7&Bnz (p/JH+;ߴg#$} Oi&s$/I'HİVzEڗ7ľe1>/r&Fq@ZY }g(f27)eN~c%ax=ʣMz«]V(*QQZUŠ*@ ~k9⢒x-Wpc|^kkF#6"-&dc-6ּvzcZDhh[g-{%@X豗I{3^g+-ɵo-ݍg/WDx%s\Os7~g2'.;7,#^=vmc,MAsΥۏwoN-׏ݹ+/m޽ Cz|>}O/=yᓃ{o?xyû WD@WVS@Kg 6\kOg3_ei|tc^hЖ/tl>BhS@TK*PC= h|L"#@p wa_\1s_@@=C@ idg81=_'.*szZ槵Em~g ;)vؼ\Bϲ$-HnK+|7c II#m: -k'}]ib I=/۸wk)xhL.un hfvlmp鑞?p\)ݽ~[wO<7W?WgO~雟O;~x=Gw>8ѭo|px탃+o>ZY?pѸBՎJn& ٣br9}Jߢw7'۳r,tҭJJKT=7}:}[x$DIP+n{'E[v6m}=mrmt;&XWöAa°3zFZzn(@k7t!+cفG0g=ho`XWXx1Y=Jzh.n:`r F3tiFtR.eT=%jGy~ &`<>hxXl@C{&Db@'@ h\e3^2e 33<97m dXG4~& zh1rDHЄ >h$Y*Df9bQWޟ"1g L-t6k%fĬg&46@RQf4 &,7@ ;г *f@a8/]_ֺ8 +hqXDHĤH!"֛s^-2!&\\Hr0B"H!BBL TÝ <84}w!&g7*Q I1\2-srG(Su0?2qq׹RZgFS8yK P2WLƚX>9CS`h#45p21 Z(EM pe.N jsSZ[6Pd̶ٖ6RFXgO8zG\gtw GDk0<.U*T 7 p%'NgPۮ m 7ʧ3w4)<_/$~ f8-U9j;Nn$b@0)H3:$I$D@<cȔ81E)#$z$Ĕ,yQ'o@hKS@O fH @,h6 Y!7#!楞%wUwŇǿ+k}6ޓ&ӥ uH?{γ1w}$)ɈElifS@4`1(I_.ȲS촤iynZP.EPS/ ”&7 RgPȁiF @|iqB N $I4%_ObdA$+bFFg%i"͉9DWy4#rX+2EQdD4|g *`eVBCC4&Kr.sIeR^7iv]mƘ|'j%Zx0N߽ѝ7 ^Icո͖n.%Vm`Hs/h7 Oook7]}k?t7h܋,?>5E͡#3;3mc`[7X umܶڷ?=͵;Kf-8Yέ~xO}Ǐuwwn_vr}Ž ; w==O.]Ã/>xgyNTSWJUtq+l!R݅fM6}]ܪ/K{FL_j_eLӌ٨Վ[b6L64(t/6l \u\7rFtLjvpxc4ϛ/=ǻ\2 2:h:tOWI1e{ #qs Dk@&r۳kѺV.xŷgw8;.%|07|q݁-ǿ@p9Z"ht1[LD| ס)`f.3BY5+ܽ|αL uPol Tk\tȴǰT)Td(WE*VGL$g4w0ބϑ?Z>om}p zd1qL p %hgܬC= {^`U3(%|-ɼ̃W7gM!m8Q*U=HṶE 8 ޿=شeԮؕa28X!RW'6F oLT\ʀS:RyNSGAsƜ ϡDJ$@[$Bh*E @*Y-1H#t͈ͰS@8!1fR?yDϧVP)⟇ =d4?= h| fbUb E)aR1!D\0& MDA:\44J.R]g@<̓,"o4C=01K@ԳEJ+厀>}bGZLk3‚R fNϖ ^7Xiq>C@;k4@ƨڄMbQC2?rhv3h=oqّ̎6F;(e #5J ׺x@ҸBZ/zHAyd'} xۏ,K%-}hm;vӵ^~0x|ϷW-.-2fo}tw_7>ʳ[l^;XF%n\B@RhRzd.zv =3 0P:kQolj&-?zx`bs571g@, K0#G͍ANЎ~/t|@ 4_yf1v/|@J~ &P )IbJu;SJMYti0+#0="S_#f܍*bsC:)BgfԷ, B[Ğ(ϵĶ$#K(S=e@ܭ~cd"ےЖķ.#VYz zJV䡒Y43-^P.* S´(PEH[%4.0צ-i35eL}Aˋ4y*/TDH FՀ(Ҳ8JVA17+a92'WdT) zǂ.JU^6kN]cC6bE_g.7w2sp#lDgJE׷~n0ZYX+WI[qsT m5W}2ݾo[aO6;.涳v;0o/}U[5plv=s196M6жűpġݻ~^&}[׿\18^{ˍGo|/N6nuvsng;]v{mJ:߫tNjtfנ6돚g̏w~sEwF)zP~n&뫿F.Sv#t+LAE/]0yz&ي@ϓv@sϯ4,'9k=-;lӐ.Tˤ‘Fm%bEsEhhhzE`d1]cXl!Mq$)&_>2C7C"ELKl̖ljfi+ХULVr9Y$KTT=\3jshph_ 8=stn&8@Nt? s;d tih#t̄cPH (tܭ8K3hH И' |# / 7+T֊ yмpQyg s 4mt/4GBCrNCГ(MISp "UuC=p< hEL )6䆳#fķ, JÛHlW:ozW=q$6ݔ'4/d{ R)rkm)}mZȉ.T5͗H[)i\o Y(XAfJ(Tʢ34K4|}5-U\yPTʂVT+ Jb.%G󸡋rEA.G.h&uѮ-3DLT{y/.x|ZYMϳV+>L,ɥrӛ^ߺW 5 ^&cv*V!G VQk ј&|%`.{ڿm 5w];nG'>+}b XȞ 7̮ٱmvpMz<@Pu7WN>Wl쯱6n=d]e7:GF_gfloӠj[Y-/WΥZjQެnW۳_]啵ەНrׇ _u-w2_S^Y|0:U0 tyY͐lͦܭ[1@ @\th?틖_dh#z" =N}@"C@bsh'oRV&$Yй ]@@(8] tab-P4 t˅d(VEh:opyС?zA:C=Z=;];:g 匑6Vʐ_(ne WPu :41@Lf/ =zTπ @j[hM$0A1jQ:R)V&B .bH|I-A)b>\)Ɣbh89=8=6Kp+_gXYJb22hQW8΄Po}lzh_x(C=C@[ZeM h"lj9/׀rU-*5VWNY*eY*+eHUQ(+ ř& ڪB]TzMɠ.Z%J|&*1q*Aޛ?{uok%ho$Jб'{Lbcsd3'w eRl@u`hM؞;KͿzxA~K%G0C OWʇ fn8cWK6ЂյkuX͵P?#ѓjt\n6[\}osW}Foy{ bD2kLwYom67nuGRǵsݪŇ£VWWVFNꛃٯ;gO'[tӕ7v]R\n7UZ;A 0U?FLͭ$h'Nt@ }_@k} Aw_b_7\]{gvzƠ_ %h)^D1|,: A@'t74BYΰ eYP F(*y3LAR\LÓ7s!n~#: gЁ={X| !< Afz9\cnAk1Wt od.RGv+"2qU糇:sg;TF]_R&䞗gU@;gh'p30Cvȉ^REr@k4y Ya| c>ZsJOj ӥqYآM"A .)D"Nً=44ڭ+@cO7LR_{ }Tzt%tΤ֞2:X;h 44tl,y0ЭnM=QC@m1 90S@8@kQ\Z45ͨ(h(TWU* TV&#,j8QTZMI.%( ٪I*9/?w~ss.lvHTIQ vΚ^ŭZluNo`y?ϣ~ꎷ~S﹙ݷ|UgshlXφЮ ڵ='~}Kq$qjkKbk,ޢO[ZZ6_9Ďshn.Pj\{f$ @ qHYss 6hlɍ`$M4iG9̽Ѹ2@=h9#Ƽpڿ@x:Dѹ @D7t.]JݨfE0h9^, 8t,4BF$ ŠPϭ@kMEZn% j | v7k'G" n)tلgKFh<Yx1V2Gt+B")C lpP=yxsW::+b+8 h2䆤탳`J0`s w&h eb ^\@k0-p  5sB@s3Ч+nPN9h揷&4(h.wZR3CjMn0áeĤXeRX\(r H Z!@ropz.?Q@S 4d4wtQ@3@/99@Cht蜝f; jQftލq:@ps$ ?-WkVy@W춲^A@.hhs @0`舎3 jp0WM<*4zͣ[JM O}ww91#}@Z% $г<\@Kd1C3{F$h)B)`\|hQOO!)$:3Ggh6i*g)uyZS(.מgC@ oh%Dg^B,%DzJS*_P@.*ʜPV4ڒDK-s\m"xb]3ԯiGĶ$&"Edc1Ԅ@UUgqIDAT* q^OK:?d4!` =Xf Y"+ @2UѹUzW3u6Câ֢Mqjhu 4j!y@+%2%P%lU]zc͕sUs>f_}\~y6f"]g3kr%ڹΗ~s\3 p=nz1:qw KWO~~>]_g$}xzO{ŮBCqhؾ c_r rI_4^/k:}7}0\[[뵘Vaz<04XZ@o;[mjkOP GT넪b[{k+wg8`v}\YtwWWvTTf3oZ29Ml gx+wbfb|<9Q@1WzӽQΤƸMw˜Xn8/|y${ gƼۘw oM>`x:@@w8@^ ttehV G84QJ)\K|%Y:m2l8 śX3m`W=^&yfQO809s=i'A3gيVt;ʭ==XD=hj!CO$A\A4Shg=# #<[r٘&B;۔> H0=WkpQe;A6ٮ@g- m[Gx*4τh V끡6a*Kiq(-vŬ)v!:"\x$bAIh1BVr = 3У+v 1<@Ю:bp&ޞ۲3 P3hhhh34c@ G8 Lm4}c.:<KV9@C= 0CU^>Tri>[V0,'AF9\~6@FO/ϣA@K7>5xЧ }=dً'斟9=W4Դ&3` Y@Eb;|ID 5IlBpU ӻI7D>{%;̞n^K^q/ qjG~wYZ!קՕ d@Ϲ!/*КK8{хUId]]z#v3- 4pQ&뙣ДUzPљ3fh[̌ ~:M--m<NGk4uCFtY=Ȁ¢BUҨKmŢTYaG-[OG?]E8Znf7kܵßrd>z.Ə2'Mk;E]-w^7;~Eꞟ=̃0<hA:q"@_fw*sZJ3W [;`fRuШ4#^5{pR]bvvݝ:ޥVjڸ\`[7;KOf/-}ywV@3'jra) ;n4/tR097z0 n \!:/E/Lb/g}/@s h4X:l/t {!7q@K@Ϗz6#mh/}@W!R#_@tRP勱\)Fhd4J@ρP3l;=|MhIx<,4辞P>y=Sfl!KPEY0ysBǨ]FWckpp2sB_Y2]=`a:Q[Lo_:X|t兣yX=fΥz&۸ThU^>jޟ:l`o3Oc:JY?,Ǟtc^,BtHlt s\י I"uڝs;sn  r H fJT$Y-ͱ=L8sϺk "diުIɐi<\S #[{] iW__[\|FcdA<G8G9h1C:fh4bv'"}m:臀 h5b\O t)*2d(B@'J,t"g?VEHC5ٳr\Nn m\螞 _ 躉kHe!5 *2f*gH*xHx_ .g{Owԗy$f!8@`,Lr{@&8j@s$@ 1{5o-W)rxi7Jᩬo"M6dݎhkVI[$Z$١11;Kftߧ~wd;6䏘‘twOc*zM@/@:n-ʵe"~a?}*{˕b~o Ut֬ujkc{W{>y'NL>{<|}oo_n`ԛ,~z܈ݯCDž|^g+ȍPbđ"SN!@j2$OԈuQc zn\l+}zDS| }h3s&3"20 gg ;4e퓌cq۝cv5z^okuK@@#CWb.!@b"UJ$ˉt%]M@,'\u@Usi:nF1 <ꙩ]Gnf kz'A==31 "#*{H+}.);qsT~3"5b]y@1I&e?KK cǠ_$f)9hBW&Ŷ ؅TNƀ>,6Zက@CC˔.fZڪZAV$`Ǥ m8?4f-*/43 Oo`4n)8zh R@g% =7 m򂼧Me =E@!th*37 tk@۸J<|hrC+/NI[[d&mz] j0V%bB hX- 8{F > ]h բxNgႋbHYzh2wQmOM!̀gn (loۖdms (.bKؒƿ@%oPGg_hmЗC`_0 =C@3=@#==gcfqvO#@O >s@@8=#=@w[>o3m|k:RMG* 2t6ųxhPVx #@'3б/󆋞pUйvWeݜaG8%kG}-s42=@I5TDņUQR%v}NρSz=}Z(i=_ kh @w|h)Gw@Vn \! O f !C A)4TBn4;n ekY3WN6=GᲡpx}7t3Ҏ5v(JƥFHr8N{zpͦ g,4KlbY8D%0Q3&SbC*A=m9B\B'T( -@fhh.!M@z&Yt Hohp(MjS M? 95Μ՛s Ȕ7 FgcdMFg[8No蛀ˌcwX=EE}8 y5?_k5eᚪԧ.ki \m :8ݽ6ƶƗ `pS9 4ʼ*WPMwٶkJE |f6^|*Fxw^QSKzIÀE5R0 ZӋzY<ՂedF8h4sVvN4i@,гcsF\nаy>o} "j4XACWj2\LTrr.ZEXR<*3|5^xI,g8 'Pq| o5 jؙ:X&6)Xd^x k6fū 80  o P`+Az":2 | aIq iS#U>ˊ]418ls@/!LΜ:g7@,z]f@g^Iœ,PILE 0tƍAI gXh  shx-2EF9fT J0Z-ԫ9@c:Ӌu o:1~ mMmUjZT:a4.)*բ[{4L %-U h*2Bs @j -1R3)2Eja9 bbŀ|">%"#h l2hh\OI)|ID4(`hx4IEHͤ E$A@;0-&b'}RڧdhcTmfdJL) V6ÉˊzpFzִuǮصmV{ MuhhS @"f*XMy9k1g,Œ2[&Aq@{4̇󻀾&_$>,/K@?(W+Uuԧ-[u]sP5y搶9mAsg62dg jlEQ;Hmϱ.e7u~bKok_03<-gWx*J]RWDn_ĮA@'~uf@_bGy83wO_cC,#l[`bs !D~ZMUBkL4903}q"kfr~;H6 \#W3{dCoӿ.M]gڴ7̆^kJɸ߶#IwC㉭O~s~~v(LIwӅta-WYo46^{dkLsq09LO̤fӳBnFql>q=q82hjwO17hv;(~wNjG;ne{i~z+z8< thNe|DzyȪH4At l:KU(Gx7>" 9i&M6Mf9m^ m-].wO%gۊ,'eĚ^Jۺ_WN {Un[_ ht1"UfU 5%= g o'Mg}@@Z);ES; 7}1FnPiv xAo=@H HT ."|cR,_bWcZ<shJќ/\eM~)@}F1C#@#={(c좘嶵ӡs3CoDgy3sC {%a&OzthIfO@_@wǠnj=I;1}=v]wgP5#R4XNʩP9 rt 2t)/ǠQj,[gt1,@$ B=% opv\hgݠEQ-jT=C=7 qh44]m@46oPz2@kIgXOhPRG"@1a;(x$a0nC rg7%3zůgoΊ]'EԹ y zgtsZhVgFZa \n4FU'%BB4h b>) Y.:" fg`B@]("o hNv}nBҹ|>2f!B  dh3 hX"Eh%g zR.  bshEv 4<=Ck@)=_jh08$zYy1_hōpzi~I_&^UdW՜Kꀾ6w˧m Z!bL@M)k_ /F՟9qOf 8 ^Wn<|sXj9&86ES㩪CҐ0寊2 K]Ʈ`ѫ5Y"qMAfd5u;VsΗX0-LC@%xAf+.N\uDhTC@DZn&8Ǐ?k@Wx62 ^͹{?|ax:j>vE81;5r x^Wٛ?u>@ !<L 9&t{3gX;&φٵiC@[umƻw[쁯t7;?6ͣhC[n92ytӷNz37H7cx305}Hdt,:2nJ3\0^Odn2f*V?[ٍQwxwSw'WrsV,<:u&Yria~۞sZ>+mDz619_szF>?}'M-*ig%jC='1hfHE""@[I$ gc,ӎv:nt 3 cR"TJJit r|>/rhTbR4YDEo7eeq =j u@ ]%@4$4гLjZG5Q9JWHJ;+T7F'\ .8?B6sͯ; |rUd:\aӄZZ#UzBe6TcVQ,'z[TkprO_0(&o+C@#IsP81`&@^:ȋR_t9?- R]7󑡅4{yTVn݄~jiꐼ2()bp^4Вk\:Hw]׼3ԝ_gynf 7E=]~wwA%EI1KjY2k5p$0,d#KZt[i&צkw{ǃCqVS*Rx76E@ VU!BR֪/GZۮF7~sct)'ѱLxLL|􋥱[o+mG#ǸsNf\p8%whYՏo=U&}{=gkǕo |`r_h2@C@sPjVajFUZRǕhZE)ȄD@+1s\1!7qhZ.B2@/=0t IB@ F]Ý m<}q7t4h`<:44kh@CCwb,g*i.%t/)}BԧnC3tOzz$Ɔ s?O<8Ώ,毱W,k/J+r?VNJW @ >A zEc59t67` Q!Vٴ/?k u`h^z]ٖo=7>)B_yLJ͗dZǑA~8|}zڗw*Fu]g Bh:̺2,9YqkJU|@q*ǁgc_ݯnһmE};O2/P۞0]]2S 13&~;js vb&Vh73y:>~| !9@g C#(_4Ӏ=3P]@#=#@Z) }qQzq:.'t@@WÁrȗs@>Cht1-rz> l3 9U<24s"pgP! 7*8OkM~BzNq@ϠvdTMlP*\~/n:V촉=6k /.rb/ճx9o=w}:1d49=&E@:="k_u @s\طܮP QԔJC(4VުXp!#$"!#œB%AC;B;&dx ht{)Z +l>5:pKR K,I#@YᕀpfE=36kj.3'ЄB-%{Zh Ok`laQ!- C=z7*ڭbsWv hV MɜIڽvȈoNg[ݘK!v+gVp@:C= |bN'й >ZHgL4/W`R?3Eҷx_7 fx3kzƇSC~4/8現>u)/)Hn / g7%&_*s;ؚ 4g&;WuMAepU"@ >~OB@H"}vT67h3N #Kǹ;_V߷vW׏,cOÛ?-}(r}5>hV!]~HT\(fI\4гTV2jEq*v,Xx_Skil?W,WB+aλzpӘq[Z!@%И4%$D$<<") erx\ ծ,4EXb-^0ՔQt~W߯a@gZ[hs 8U'3 ]u8vx|M@:W Y@+@WqH箞{b4 ]Ʈ@^ hghh4=A=-xTEDTTXńP: Gbb \6*[E(-%x/$>'6AN\[?04 mΣx/t){t=DWZwQ܇vҮRдRC)L(m0J m Y%fE8C_"hz[8 I ' "@[== 63zh#tl:tw @z65)c2hs5u@_Z Ay@gm) : :cZ& E{ԌGŞҳ h50gh hm:htZVanx,0)@CCwQM}bhnO@>qݙ]d8=+ҀүzsͭA]kHi!!)@p9>L9\WӃ냱eFMQjG$mAr}(*osoCq\\deOWׇTAY嚨pE"^@v5/G8D\eAugAs}3Əi|gĶ^8Md#C?'N Q~SyPW%t pR@SP.p)$gʜF׫rf}cߵ ;\1\́W]~7p0u`w-f@"IJ,ϗZjWm貗N8E_FgWt=>qշpy92 }qx3kYr{ɝla \<揝#wth?="ҷ,۶xv,m`hsٱvM*vIҾ֣o}?' L ? Flj'o'o~l\Vxd1 gٰ}:L Pcz4FuT3M5rt֪zh+c'Kzmr+nE<[c?^Xg= wR^k{3dllvN@&IBs@C@:bY/f==m -[`|'g=Du>DbU3fu Vг'6^ h h$ Y@;-tՀTJ.a`.%YP& МGЀHӥhsT@`9\KngUҳp=_hg:to,O@ЧJ@' 4!4343QaVa5=tTXB d7/r[`ǟ*ussjҀZž/9hqB FfJS :Mި/z]{o>tpZ,rJdZ_|׳~(j1 ^STh aHKmT"c.yJ&ռVAxHL"#(|+..y?ŧsd`2 %\ GB~_o%jǑʃh; wعdr/6|_f~ӷſcZ;V׶ŽmX}M"~ܡsw<6G{?7oI(<Ύ>,O<unʮˑg|̬^bGɱ1$D+NRT34KfѪ;k;9 l=τoCQV$mI++VB_hugZ|Q,99g)(?D퍰[-h' 8G6hIS&!7š'w@ ض*Eno4RqpcN=~:fVADAB8>tzh+]z'`&̤Cl8<33t, \ƫd5,b;XA~s@s8g(o@=/ ~_+vœЅ }6adf,`^򾪋?t.cpV7xcv(v RRऒ((&Y0>!1b!X@~/P. M -3`MY%k4rF4wl1sY-]=۾G@[@'~Fzҹ h{UpOa^i=_~ 8",|oņD1>?XvVf ,^ŢN^ ϞTs^٭F۝ uAc0uM!#  =sLxfѥIJ{l_zw(!Hn [.ېMqag(ny6FGWU wqGNѯb8U2Wi 47qWEQxe(ɓe<_[*|kG0晔UcyP7U IpYSpu4]7*w(-0YF(U9h0HsTo? |.8ϖ3On}Xά#4Y3-Vd&‚XO x%+/0/Jd]OyofrqBl_x)Gth&xޅF$m'ҷɝO+{?UE+b'\MogY{M=U9$ x6e ߴo7mޛ6.4xo ";$ w\퇹6>#ǿ >N=N>}~i?ȍ=jνvV*M,+Њucey9ħ wn|km0ފ$1.mg~ؕ%oxqN.~+ڍo3jߊ\z{̈;rR]ʹ)zm›)gh7rҗBL9k" $ײ"H+hZRxʼ=D핀gP:jZOM@L\䌙3=ʰ#vzvt0et2N N3*?+X 'Kp*]@;}5гՀT*C讞_h=A],鐊d*ƜM @[oqzTCK2^ hg-҉:1z |G@s{E j计j\or3+ $a M·IE$$@fĔ]B%O*@k8@I-Gl@i5ky`2qB:[Q E o|g@kTн-/t h2@3U٣c_he4Ӏz]VeF̭bFS-? h/@Zbм@'Nǻ  o$d~yP5=|v(=׏@hAsgȄ2Fx8;g=3}uU_)뇂/&K;8)lIK7[;lW|/,ʃ+"5Om~C_[Wk$ YX4E C8_YZ =d{&EYQ`Âױ9+pL 15/!h]a@P$A8͗OKiJ$HY:2,A41gra[;O kwvagnڇ7#)sk&sɠr{%"KERevӀƾ}6x9DUb?yN+53Vn?~םB)@R$5!] BvMت [6lM1#hrgP8J:Y?gMB>RFUPBjVeE{IA6|(50tO u&FuҐ:dY2+ygܐqv#]L@A}- Wk[CS3? \]yC]8:ʜdρG2enra4oJ~AFMɨ!ؐv4jAcqM >DU!E^!tb2uL:HG3#`huaTW1TF,5.w4GGqԷ8]T_(9 &F&Te̐kл33YEJ_䗴 ?G/M-(uE]]1Z`h7q,?͋Lvsc>< /Υ׹ɛ\80#ph8Mc1w&Z[Sk@W4Pᵢ3Tƪ#9М駚Qx=}v㣷n~IM^%\9 􌗚F9#'S4k{cl˽Ko7˗sTl_-w~KogӉdv-V\Vn>5U0BT ~n+L|ׇ{~fǠ8Oq0$L0+vîu@Mht')Sꤞ:QT(#m&{PLܺߔ2f|A7 BzyE h;`ܒA->v8 3,N $@GX@G T21\ @bb:Q*Z{C4Y}ζAN2ی6Q4-PH}@{!mųqP24y/0v }u Eh]VOq8&BFp IWaM [/i5V*ֳ Ҩ\iF haR*9h3ʍ``Cuh`g4kp0(ygp0dhY zCF`Az_o^C4Bl r0,G|FWA:%U2ZW1F4Ļ1h#T=Ђi؀ i0Y33ATJmDF@vډ(8I\E.DT t`4(I-YO-QS" xzL>WyI܄HĘ@8w PMFJI%@L`r:.&d6b!j"6!lC6/ Z}A @C.L".BQ>a.օm?;#mԤQ6C16Nu#Z%JJR MbTG%FКtFB ܨ:3 ke^"USos4cq]鸾rX=z6RC1m\ t"=#@Ѫ3@gMB33JF0=+gd@^ߒ,"Hm}+{J;~?1oՅsiu *ʝ7M;o=V&6TUbF q'qz'15 P2t鄲04fːl-M C>-rcYflaWsGfZj*WFak}Tr}Q+ȵhxOˌrR"O QҢ+Sh؝-AP4;ʼnS'מ^}hǡ?L Oj;-e-4蹊8!|ZTEg5n6moMhV\'љ{EQMU2˕J5\,3Kc՛gߝ6_jeRj-\'73lL6޺sǥ&e:w㭝X~+wB{_f7 *res׉M"sߠK7{BkGK,(w{W\y;"XQzA;sԻxL$s&<틜$oǬ"Cdg8zz"ZMPiv*M8Pm>{sqǷޛl\.3S3LJ!|Olݪ粩Dv+Y]"Pi"Xje_;# ]%Cs=7Dņf+4JѫjM; e䖅6[FrH i 7 =#u' [_B1ж=g30 :$Y @Cz,0ZZ^l㐛q6nC삃w n~K

sC="ƽDG@M&4ՠIUPtd%-b@6al&\GBĎm쾠VXKPk :5 &g@aJt1ԣ}ԣCQ].4Mz:fгVizmB4qJÞqI* i{ҍtҭΚ4ݗ\j/ː7iC·z.#=Ǎ搥s:6dB ":gw^ޑ!@wU$fG9г_. W"kCco g>x(TYM:z>(^m^O| ++FR[ҿdgԌ==ÿu<߫z\[@#@# $CdHϩ#! t$3L!KuQqF?X?[K-T3Z5ZϮ6c k7O?*trK*:Xײb\ryqO?hvw2wNq/\ΰDVn׼+4n3[t喻tS&KwعZzz/->ݟ%OX}^}7Rz9,_}#;ʜ$ΊӼ'lsn C., 5Q=l$3a'dUl`}&==/VfU3ogsBj)vdcn~>[H߬比JogXa9ZV:JeNBW9iyYH9y^aUZ%UZPN ܲ[f4чn1!u驭I1Zݒ>MOoM#2&U[ B#Y5+:ZS܏[ׂ(;;\¼y#,1,0<Shwm}퐿[x5z2\OEH%)g#|Rc :d5f*f6RRDK"F0Gpbۇ|1i:_V[ u(fH~rWa3ЙrUe#UΚX،XPD͠g6a?aNGh:|(&Sħ5J~$~Um 9; ukZ Vvh/hРdd1 V)&Q<̙ӨhT %P ?ڬl !8|!GyZs*Wqhg33:@{v]@'.C2ET1'"N hk4]h e ")=@3N.Sؑ_лz]@^!@wQh>@YJ):ԠR69740Q}!Uchrt8XEz65%@!@􌭌|0QS#̜CաPbܨ?M/F$@KzVSΌMެ=ǯN7ew^A(`Loj]@Ӕ'/4.#Sdd(C%K2SEn<ߌjøQ[}ZT䦲X둞>"obкN撍&dh p[.&$dɶrS{Z<Ѣ]uWlZXfsd{F U&uƅ@G1t?yyoܕzz]깵FnCޚ'j5VH+j.],~pO<]ɎMID}@ha}w?_h;|UI7nS[dUu^Mܨޝo̾7|oawo7d*b2rm 3>~MgXϳgh+4U3|5_&N%C]@_mgg g!н})Qz'1Q:RJ:\@rNtTJ.B|5&d6V*NgDg(Kx3#u_@mzҀy5;=3(AaCЯ 0y% :& IW)ⓛi/CGܼ]j@]SmҺL)YhMm h|-yF&hr &3ьE*:˜G9oh< lCu(wgyJj >Nt%=K&n{5 hUěYZ_$ Hhj@X]*4]2M"@ h6fn.vUޥ3Z~F68 vi#NmءEq6ǀVҪMZIpJH.եG2=~@oEFst@-g,sLIVOס# fGav^/PrSޖ1O'aU"Y/ T4.3g? Odk~vqM;-1}a@kե"p$+FzsZȢ(CƳʐ$%L%4l. ë(7 EnO_" edhKbZ5fsV:l20a-8vk\5*F\}ERU)~~P5n5W{q" scIdR;tw~~qn#@t^oZyT<~7OM7Rj@cЙFʙs_۹LNjAHaG[;w#x$^t}oίWno&rK}oW^6}1j{能=R6-9\6BX:nF_ C"tR E ;T_Ckh ؔ,WfJP/ҥUz~]@#=k;Հާg дy<:,Z4 3T@>k{-F|ӊ ͛B5"C[ מ ѤZ~ۨ>+{f41ytݟ?hsnhi~@Whz+<^rO.gW La4.a@H@9A|g|-\B)b@"v_懾~s€9"54ԟߐMZSq"]>mx_Ψq":2#zг;KCX؎}@ё-9܁w 9كYHz7z]Ge̖r^<~ߋjWt+Euᜦt^]<ĀVV:séMyxE_ᇛ&ֱqcS43h0#URǕʴ\5't y)?l̏@@g}vDFqz@!5.`uz4l™&Kj;u65\CWu k(>o 芔ڢNӗX1fsUig -ۉ /&㥍vaSX@ҫ"z?Z)fTxz~is?P\@gkR[- G0D?Ͻ}o~ߋ+oǺC _.ro{7~8EjEx3_zu3t?\\x;vti0?އzk!t9Nnb V(r45 O͋众T/*Wif%{09OO~5Sߩ$U׫ɻ Q;b*AzX=if>ٓ/N+ J[ԄVH1v2Li hvr%@̌h.2I-ԊZuRkVbuGƆKzgG|46n4g447Cp=fh3+L8' :Б@:P"@Wj@C]@CSxO56Og\;kP-@]=K=7t>hj -B:$"E.vJFo@AaaRv+.eȥ -B]rvt> ޟ В`UuṪ.Iv ցsb=K?+- tfN1iA&":158r%a= mՇlxd 4bZlh.m+$XKhE(X3ڬYG`hۨ׮D}f<4?hN4143YpPM]@Uz%;/C\>hdh.^ht+ThSYt!BI7b@#=m(%=L~9$Z¢9""xYt3@Ϭ>FEQFH҅m(3EC#FYÀ>0šJk:4e6@Dˎh!G=-H_Q@UW=K |3蹃Ntt%+Kt>Ҍw<X'6ecm擿?erIW)"@*եsh`eV_7R׼"Kn"2\arc섭}>njÀ+Mԕou\tfx47Y|u*3ʂP^Az>-冒܈rrp0E?5㷏&r䱡 Z]7L%3Tm*٦bWLAWo %] 2KFCd,MVH{MZЭ&>w9:=Sn;v~[iV<ɗraڙvx|oSܼS'?7'kTzy3kZbhQl:1h}N~sorD{O|SozB~M&5}-ο%,^og'?俽W@;ɇOI0rY%<+ PXriGy5%;e[eV IDATPznʩ'ۥjV#uHԓ؛ģzlWX |Ku/z heCX1;o"d^EZPnjI:uhqЇ@iu->ohяYbWƟ螓Ip=!.M? ?cᅶ Eo Pa#쯇H TbJ,:T@C.F2XœxO N<&Վ!=׃att p@_u]{?=/M: €6AB6AZx@c=e*YHtL,9c"Sf4sm鰑8` F.E(R[t)NeMqi:dS6U=t󡎂fCn)X!=Z65ؽz;6=w g4Hh myv5;&hb8ח6R5 -F(@_q h"4=iuLf4 gnhhϔ3H1>Y h.Lf 4424zb#f<h_9|Q?b@_h3$Bz:z~@m.l7>C#=Ki$=@% J>Z==X#zxОȗZF螌 CyrxjSQ8T>q?}]֮KYM鼲xVQ>7Z9:Ի=HHjqgqK븹m@К!@P@ϲтl$/:;35PvHGu!}QǓz4-7MPeH >/(S4F :Ce,xF٬/[ue*4%e֗L@aMƠ4Y&5y`ҖL2dIu{I6ІXNKU 4fZT+֭Ͼx秛3zNn]jKz=|z>k]{7/}sgN}i.dodKW [tvu3ָm"@ǁtla|akOGY߮?ĕ7>>Ͻ~"=N=Q<>azO[{[g7ۧ?}mQtџ9G4E2U hh!@1" Rs"9&DKר{k|(sXѕwyyWOn$o5ɻN-q{H>wjN#Z;]fٶy9:3 2 })zVԚZfjOЯ5;@{.MM$O m^h bK[^o+ !WX":5t. ƀFr47bz,ވ%D+j#xT44^>z=2!Cc@f@){h訁ظ^a] Q^a"V̀>j }M@çCN0m1416>3ӢYdGմYI!МY[ feZ+ZQVj5Iht{_IS8f4*=]zENxI -0@6x150LK Sdi h f<˗rN:;*ZB@cY]!= :g} ڪK]r`hi~CJh5YlWAZRW`hP%#(GBFU>lnJχ=@3mbf!<},)36Mɯ3իUhm gF/;?Q5.2Ԑs층msƷ 8iC[; h -1r ̍!mnH;aȟ0!e+h =@hMB0 C ҢڇQVC.E[jY4CxӨ1qʚ4yh^kːI[6F=%<ν= v&h)?>zٷ͏K/wxs${sOoS I&64EЛ@2,XHh'y/=dbl'5+b􂹭t񃍵zr͹N#uYOܪ%nWw;zjLl$e?9ə J7 q~ $G#@ As ࡖi kVrLtrc7|3͠pV,2nQ@ۘ f=4N$!=x[]ja%]:x:_ĀDSh7f,Bڨh'*Au@7wZ?T얐 ;h  thHk&ʨB2Q\*C:$f*t@(i?_֫5f,/eo&E˛y"F΢"J mQq6`EFnսv& g*3U =0U|(1'&}džƀ[TX4SbXhA9bͺˏ9QGCa{gsՀl8 h&.66>:: :0Rk *R[Ph @dd (@eFKs={'!a~ȷx"|,*@guU u颮|I]<\PUko~0w;2ưo -?3h=X+}tohG.E#K'UhV#:ņYrKuZ[j2$ʐ$ӕ JUkrjmVh.g̚EjPMά!]֤M~}tڌ nπ>1ŏXNscΆ@D60Y\X ~|DaYhfkbl^l_`}JxJt!wX@. ՛ҵdff|m|{O@Б7}SOO#;Dz g\;?Nhe/PX}_€fs{cH̝T`o-ߦmx6hyͣu 1caEզXtY y'y視0W_:bMG~}96b@yЋk@i0خ;Nr7N#=wn)&:m!_%+#@K@!($T l( 屡HU"z$5f,BEۀh Vo @Bu_&Po"qtw 01`@ JG}>B-*E:Jhг_C}HNfIthHϸn%tІfZ0Ax++: hg47haVAf{<-,o(#16 eUomZ҉Z'tb@/\ Dw0IGppI+3)rIg]Tg*TtHdm<h3)z:B#@QA A 9?s( m0H7[*ǖYrE/\4>4AzN]3s1!{0 `@Xϖ:5DsX=>@s @I8A-BlZ7)HK餴PZhlFWPHՠo~|c1tس =+e|]~ca@a@O_hhnp¿t?1 hhƀvJnkr >Ogbo~9}q"8[@Sl9XI. z%^nrۥV>Uȝ.oW2+tFnl:toFP=^z3ߺ/v!|(:O|O)i)}<.9O=?>]|/+HV".Q܊P'=+` Alh?^ b[BAtwwc_ >@>[ρDK`{ G Х6c@)hg:a&+M\ -zCxë =ʀ])YܟfY%~,; hR74֝4=#€ƛ](t[rëF?CO/?c@g i8A@t۝zKpi|*oz>x ЎÀ69C7:6|}m]8C@>8mp~C ˎZx qÿ́B f3&GMsu=@4G: ^^4xCz6l`"q4Q%>|ʥmLNgLdLE]LEݨ.tCt2T!`*C!j! /垀Іz&L/B"L 3!)(t&'䄟Sc^"U=XĈFb|iҗ"I?+uG(l#*YBBzsg3Yc5Dg4M>A!1݆Kwcv}bVCbY1.jF9uqΐBFJRCڴHϪ9>g:ox+tE4-VriP$זNhKPes鸶|BW9u1liX#a9=x]<P3d @ssPdx|XzSV:zyܸ+]R/+KUys-rY~oxVڒAޥ!~\ĐskQV}Л(A(}֪+@f4LX4fSn.:mUUg@cn2r/Xv]h&کjlZ@ j>\lVJٓv!wXX\.oj7ҕkڭg[WHƚh7aq?ڼn<5j;=o[}z?&ӏ{=ǿmEFGN~[y/npyg׫|28DϐMa6<4GN[(r&ijFwzQ钞)=e&DI|Pe;xgVn3*0:vV^+GUW|pjBK̄mo,cl'ȴA"6Mx?jY S: hl'W䊅X1&b-54^u&ִxO9Ї;<6MU׾*^!`hfż==za933kag\+۵SVvN;)'7b'≠#hzhNluQzO #}vu.+Usqr9P@P9EsbTeɖe[r;tmwnuy33/3@<3aD5K"|γZ.Z.Z63i=1Y# d!,P‘za 6`P]VU t"5IKjC$mEijL f9<4}9d^ /O~<~v;[7>߇G0dt2m&1!Q߉=< V;'+,>M4>IsP\MBDʗh"%>ΜQ=۔A H4FQk43|X%"W9z2A{9[[KFc3^{[vW.f[o+ՊT[2ג/vGaXttf8qyKz&w G8lhE42NxZׇ2{(98Q얛4pfk.nͯ:K>#xGX ~@ }c@7xa.UE*T%])J!f#Z6jPI5@鴖ɜB0^ KX%&æPY7 BlT`UWPU Eh)Վu$-JAzI%r\ԢsI"q~^q ?W x㠏ϼ{|࡞NTp97sfLͦtɘ ׫EP&0QEhlF ;dծC a13A, ؂n[5wb>s@ttN; ׿kNHsq]pUUf{^ǻ @C=7h7:gzhc>瀄@kFqg8rA@ t`Q %!S#jnbCƄSh~|,B@@C=4}М hbz м h3衡%s~3 =d4 nLug֌n\Sk&"\Y-˪L@kq%3Top+=gWyh,<tB@'h܇Ɓ= t.dN$@SG :g :ezgt]zj,: BkSƴ9nM{%?[E+a^=8&G1 j6,:Db:wzkOkG~޵oۊ7l-[ɇ៘Z׭ktpwR֧ٚhiҴ ! gx?*@"6_o^ty翭//ʻ+yu=?w_~NwmhBzH8{9@.e^GB3;4E ZENK $zYczQN]ճՍ/àWabc@A0BQ@8h.- Wawٜ:N6s"`} Чz]v 96Kh@Bq~/)u/ cy;̱#%b^E`heʡrMD  jh0AL 9ŰS8y1@ELY₩g>Gp ХC@sl? hn 9а%8 {W#0 ̍cWr노}pZPMC-ERЂRg9-=IVO0:4}!S8'L@LJz>$My ķ<:k}L3@f҉ @|Vt5&IOk۞u@o _WhMG g9UaѶ#{sO?r哅݅{|rkzkqgqW=7s{5K%znJߙ6&)j?YB[@Szx< O|'=44YcpEjլj }˙̭_'hB\5;5:^?u'% ۵Pm+w?|ݰl44A Q8JHi-YВu,ResfYٟQ՝P]Iə,)G1(e/R EZ: >wCxg$͔\o_}◷g~:Zcћv!C%)`KfO~po:[?ؾŽx?VL6_jOCZ hqRZԟ7c+|֗/΋ٟgdm꼣o|9r͛[|L""7m&|Ү%g.AmQ@h pr5@"ٕb|7#vbbs[ۿ|p'ܿ󿸶~}/77[DHvTSWZAh'Q6-[:Rymo Xf0k44Ao}#zE [4<{v0nN3 r-43#XΉu^ bZ*xr>(gCJ&j&J:RJ2&jݷT@&Ƅ9mMSd;&˓$џb>+RC3ޛ.W~ ?oݙ^ߝޞkܝ߱u7*OݏDlO/[ޔ=!O0)?/O;hk0]?8ߨ 'c@:Nq: VV_Luf#z^[{ycOȍw]G68}ߟ'؟zk:V8ݲjӁWaYA!=,hqR<3Άʼ.j 8abGv@ ّayÑEđAi ڑe xf,+93+'kxsBBχBȇY!_<D49=F#%?Z􁰂Uy>ouZ%GnF;+?|O|qkA7Q Zz,Ƕʱr|+&Fˇo_{/߮3>_I$*oKϼg@]{BW3tQ ~UBB)W"3ΞzQ~rvzIjIojz&><D»g?-'nNl״f/*ꝥ/|~o<_>{_ッ+"<{g:Z.pdq~)-)!C,[4i|58gB:tf@/{0jo4OwJ @o^!GA=ʸ빹Y&)MmFh1bjPㅪǩHr!h9 J:.'r2)'SJ"ijj,ZGz*F:4t0  6:SAxaC׫V22n  8K&gs!KL@;xn7ejWz.{z> 蜓Ȁ03J&P*Ҡ7t ;萃6 hD?g3@#6ڠas8LD Z>2dMtڸq >443!1whAm Mi.5Σ0K+p_h*eyA   aWh9B"VА:jȩF\ )p)EP4mC=|`fK<) ,&5KBC㸆p*BB?"#Џ򠕈za! 6HT3] Uh^Z0"a$}6 zu<3Hn]1,zFӤq89)Ip# 9pD(3 zW t.:% C=[~8czzt |FAI@Oὣ}x-O[ӡy?ߌk.,-47ͷ̶c~bqoxc2v>k1v n 2M:hz^7 <8<~.N.L@g'SsiSҦ`3+Rz@B4Ҍ0@39"p'?!w?@o7&ө عIckB^n.[ٜ"x/[=7l4UuWڢt{Ou7WUEYư,b΂ C<04Y 8[ƅ=XƇf)4+ Y^ * gFwe w&IG?  <$)2$3I2 q"J /%̈ kQ(YJ>wy=uΒ]x]:aa)tˑ/۟u7v# Hm[N=WMUAy^<׃+Ukӵl`͍|//f_$*8ڭ/=e?Ro'VJϩ3"4}M?2O=G]_'q _Gnt1 ^ŋSfGM4 " Xu`Cx"<+!~9) Rhj(Ljw=x]}zܸ%Ϋl7ohR,+P(9z4Sj")sv ͜Ch+:Nn|.vl|\/C=MqmͷY5BEʢXBIKT J J)h9 )i9n:S3(XуUa4@-@w mh ( *t3j|7E%?`zv8~zwt{.ǯ:ɂ ihjtm<>ISz"6` Ђ*:)7Y=0_}wuԼl&"7LFE[K sz8qd# ӀF;쀞\`7ZcrxG\6o6r":nx8݁aC@%ohҼ0^ܤ ˨" 2c>E#( a pZQpaKĘ[{ĄZHTO(Cx3.Kr4,3晒bkPĺ,B@aa|C`@R9PG{!q%"DAz=ĎznA= URE2tA,=9hgt EpDш?ECh3z< 슉9{N=OK&I,Mpl::c)l04 М8^2Gj@gg#gub> hSG;i<}8| @V1j@`ho5_:X>! '_h졡#3`] ek:3ٛJ,?_Ͼ/η/v.t:^U?Va_,Δ=A']I56ՉExk|ay!o^HOϧ= Bfiel:-lYyY~ӻ!w'_H~JlqoزSiQ6'4A7'4Qj3>8=*YA]V| 1o,@ tP >1ޖrZ_g,{Ur ":,ђ-Fr{tӗ7?}q޹lVFjJ_\OpᇭΣtvp+ߊ돚k^Gwn}uW~ѿ+ѿ˝ݽ_ݟ{js.>&RoCO77Fnz~կ]Ie}g?}n8m&-4&AmNu?W} <}ÉMYK˝(*`^ˡ \\CܒoV*\Ɋ_0 َvd#%M+ËTм hf h8d:@cY<7 %9tW5W zS\>k}lv1.fŬ5bA2w|k1|Yg,IeE,BQ.b1(Bb.$B@GsLNA=KO˱ͪ)z.ht zS V5.hfykMAi t[A@ynfu}1 @>Z 5-#q  !"j̦`Gr$lVfGz66ܯA@{ڍc;'=Z}N4|衘_hx綹yT$ĺ+pطZs{t[u`h4OsԜ2*H;."(v8!! )]E4hhLR-4 aRHn=bKZ]W-AEY2,gE%#AK'c@T(FcD:"X /:Գ1gPϲ+.@'9Sc@(hg247p|ñ 4aBa$٠'<(N;Հz8Ws8qmu'9t@S'=n~>w-hrے8[6%sKVm 46WHDAtPz.`n!> p[~ _ͬ{˸H ;Os+4LӮ4jl؝a3&3tHIdMVTOD7hSDGwĊZ6de'Y M1GLȓS,(GpC!+tսVצ@uI냜Nn}ŏ^\>}zW{yg;>ٳ|>˝헕Rv,s-j$3u=+K՟>\;bߝww]׫W~yqxQy. '\1zD&=nx g|#_K>CwS>Ha{3[@C=S>|X=̃=\&> e%+!; ^kZW*-RKZZ.:+Ռ\OPp@MizIu%*vEd";34!wgCF|@8@c1=3#z^1h^q=n-.(A=mk\,\bIJ|Q㋺P4BP̏-,.'sZfHN pA 5e݀z6zftkttA@WYuNm* np?4t|ƉWVDMC=-;g3C@~@98М(..@ C@;fUw46?:}qe3 hhS^dS5;4k@D hJ^J1oZ!thVs &Ȣ "v+C0QMG5é]r%EB#Ľ|z6UE&KuE+S4F hXG!fZIQ{ Kaۺ&%RQehE.HJNRuPZS|0L(AT8NEb$s4}/azg)8гJqS) $I 9Y?abv)e!hh hdCgP6/7>!ӀviNzݜ4'-3[w'@ɠIm¯3ʖؙ ZR,KHn/;s/?e}93ƹYmwFޞ7Նʄ'!&+%Bvr?O-$!S#ѢonM1Im7\^@|3rcƻΝȃ ~_zka+ܰfXӗ,Ὑ=#Z,՝ m 5A#=SKŘYxCؼ=lb)GKTڤ _}U*s-<9ƕYɗ 2qO2鎧(Q2/S b^}=f$6Hz7;*^Ȗ귛KOW7o:{)fpH՝p$@>4En*VŰxZtGeCO+v;Zֹw]O߼?}zgw~nAz+_^5E%|/*+j&o|һGG2Kjo+ϵ)O>`}*q#^W5Jo{^G/y>K_P5' pr'M0bg }&}T?@ HsK@e4RJdvNlFIZAeZFzBjfozkh?Ea2ۑ%z,1a"=k]]AOLq%}q=9x6b{>?@7=gsn\ oBIXPt/\PȆtDLELCǥdR((-sJ( ^TH+^Uj5斦 Unk uQjjMNmJ!nA==`hK&;$}m^}I:В h!u; UD:x гWp j6f b @:s86 dNBlׄNsg|J^Գк֜d%';y)P0@:eEEtP cTb+||%<( !HތKSY{8E"ɠ,הaRM̈́aMs 5jK!y9ԕb&cJ/tRT^ȝ*-!7 ]JE˪ <4ТBI6d Sh '¾ Wtz ЉNgS&a&P\zvf܇s@sُuΎ7|-p,qմA-5mOzuS,<Dt`xy?W蝿7ޱ-n&/3ʞMݝ-5ė'ڜ Zϟώ^HL=5^ "98[QiX۰Hu}Rٶ w=g?#/Գ s?U!\ k幽 ~̑9u1yjeZ^ {TFv"_[xOX넼I*[ͩ[I뜸+,6hr%P z`^2霬&@H/),: V`u@8jI`dvYCrL'ՌV o53{+[νvv198HSȾ>qA4e1|$GoM=uWOӒ}=@<2!qݣw@c5~ݣ\uW=Ұ0G/yK=0=$ =3hDH혀  6 |ch>3Lj\q}71k8FԊl}+QI~)ŷ\#5\#5C\+ȵ ^ܭ= u6ےz6^1 &!6  4BF hs3PC@3=/zl M lfxvo: mi{F؜Ef LlPn% \MBݢ8+Ⱦ>c[V7%eMW5iUV+ShT#HՃd-HVK'K J9*[&5:R]9׳2֝[[;~[o>xk{kѩ?hV7J7V\k|4$cDDOrh·=ۑs:RFݫhn-2Ц%rTW{{1aqVSZ&l;f:璉Px=IەDW8@/ +~]-9zW÷M>|KaB-*x4n>O.TW/ne?$ϹsnbC{A9/g ~6|Í\5?@>#>pù@`WbS}@&CL7tBL+HR ?s|=)1 %DtOM==C@S+''<& ŷB>Fͣ̆F 롻^yhr[e*@(\I _6yC@s 󩰐@ ɘONf$#/c@eEjU@ &R"A@x‚uxMVm ?M@7YG&h?7zh CuȠC vV6 8A>{p.m|lQ=z(v:N5' 61+[X'5<3,0;t.bM܏Hwz/Csw„W@~|C@ p c >_s@;@0@tpINb b"HCzq9T$LSAJq ɀ @)rhW'2@ÊP, IԳj6:ZkRZZR/Ь ~\CahPеt߬TNArn~bJ $N8FhXxu\XBKʞIJ̕\iΝR+9S3ŀ =g@#Xցe'̙E99`ÿ[ GGFha-=l)͢YbC*s:*~0qil`uT, Nn:ƀFjSh͂Aiwkjxmu!=ho[{2>oZ+ٟ^ef 5X=kx&~`Wl sśk5}y:o fsYegFpi۱ӻVDHeQ'&'333|pz> 4 igyS44ݚe6۔MC K\K]/23ly/ԛ}A|?)ss֯C7}k>EnsD-;1i)o]<'$.d^|\m?/=wTT ًBr?,.l'ȶl3Ƶbl#TL%ɔRt>K|"jbnz!ݼQk y:G(#H ע6EvXrI{ Sn[ +!a9$ڏ髉FD_ iA}0֍o.e}J:J@JI\1FBkG)2^ƵKf%|&]H@ϐN;0dσ\y7sQ0bωnyjznU_.|É_E|P4G}X`F}p I ĊDdO&o$-m3H17Eй! YW=^ZFvA= /!7\ĦMB ##@ه6[ȊFVVԢdE_:e( eP;&("@ }ts nɟj(_v>o|?DinHz{~`D7#8-NQE^TfE5Լ!ͭ-U>9b>)~)Slfr ʳp /|Y*X$\&u 1NHFAB[M(؏ rD8ٳ jZ:?(z ,ʡɉNp8( ӑ RQiDLcJ &/!Ң')zR' sAR>#R4ș$%H,I8' 9<`p΂ݙv4oGrQhy- :,YlE33RYl0}Ws;SI h뻝 +г9iN g}m8LtޞB`܌/[?K @6zƬ9iۦԳ6-t041>n^\I]&.Y3k5|ܷAy+[ӟ δ3|9/&¤#?4G5 gŞ_3 鹔u.=^Wuۘ[TgP 9lBf,}#%//-donn-{o3{HW>oFD|ns\W"L&Lڛzo{={KMJRI廪LOk(JƍK0 1wω٣Kʎ]uʻy#"qU;7?}swpo?G?=~_LJ~wr|t+k;~JnZfNNnZ/ R[׷b{~yO o;wV?w?ml{Z^5{\MKeT7iş|yƛ#0,dr^r9+>w4h_9'R=t`W ~`CF:64}#EHVmW8ewHyvq=B'R<#IE5nPyS, Kg>̋|cGn!g&/uE[~j3@o ?>j1jEn8ufcT`Ձ:+0B&Gnr%~bCĘ#yԀ<.ϡ5DTG;"ٶ\3d/Bq#x f760n70~l ƛ #ڮΜ:}L̺8H0mmSlf `$Vr|G2bt^`h-d !1q1I)91PA6JVVVUY/iME#@+uAmzWQmAz uyˉPWx7Q1֡7I3-0KGnt#4LO1hyjU!={Agvri'ob/.)ᒡS;C:,6I;] 0 ` %_bܽ# /Ʌv —S#/_׋ю̱ D'p"=I즡o:o{I(u=k^r(27{#V`V%CR8 \5oX>#l:vhг ΐ|ЗRY˪PĪ. H1/+݈G/-:zhN脂=}P*:zxVM@'.aca6bA& JdR%SzΘ~gٛ7cdX=3 hCc/t~ж =M@;kl.0KguUL:_6oJ&݀>?tzr [L|c6<+tyr@OV~sA:~>]-.2s  wmD8́GhcwVټ%b3T[ t_mmUzV@{?/fsQsWg=Cn+3hA޲?d,&OR3Yp<:ug){!wo~KO_*~?H'<߻O][=wJݓ*ϓgY}Ǎz;>o~{tǷw?Ó'߼o{o{rtAtJj$URq'?~6<~kÏO>77\yw{]{`FG>Zxcq^Z~plC9#e>T#6@BESoGBg|,߰yYOI;4IDG$ Z6GuŁ"dy(K(I "(+2#:%nR)nC8.>).!!)J>p©_8 '?rhG-}'!C 䮗R^jћ^zKyU5vSk.jI;5;j '=D6Wrc' = CDeMf=HX]tc: 4xaޫMfϬb} ЛN CO =M hv sC#@o|h=? =wi)=WL@xh8*d51c鐘4O4q5/I/e4:`u._ YjZJW.B==4v@,g|z6{;Szꁉ_ h."@_y @O}]"t(9Fid3E7 zn@>^T+DM-QҼӽ W>v\ 8y =S(jnYu)KU³̻ВT%"C^##5+q)4fH5K)^v@pH/B˒\"TI]r4v"j/Xn;ɷaH @U| DItR39 @OBzо}ے3cI//Yˏ77w輕_FMJ-uבIsF#g? ky7#gha$u?? 'G۟?}޼j^-Q juZR+>ٽw>?~폶?;曽ڻ֏n>`яo4l ۋDЪip ),IH nR7'z *yYvTχ7o.#k<-?ڔt@ @G zCK|GjUFMS€Fsk> 7͇vg@p~? y@#A,4@1hh䮓4 M䮛1CsnY6L7U'ꅞkFU2وU;rh#V}O>89$!IHfdB]@4Ġӗ9mY[z/bWxfp1Ŭj|4  @:7_s@mVnn4Y41nŃ{-?=َ [&@_yh(%ph>Ub:(BB",$#S$#:+'Q/JjYR+RI5zeMEijMT庨y-dh-SW=ٴgXo݅mfm^@_[oFhƘ hrRLڅ7n:̈́~hs#f69boe vC٥`{ s-@dBJq 꺘|>ⴞ'uS/O1|cq[4ܒVuL1YpKSdֽFЧZWb%WS"4e(Ŝ_!/y$f4+Ĭ^nfHkZ)}d't v!L&|@UM@pй^:bA:)J<,*v2O|W/b9ړ,S)t ,ha(;_r5@_yɍ}IgjAզ9A<9*\7pkamwط@ ; {GK' GCkB!tx\gE wı%vAԶfa4Ǎ,<ٛ5_*YWydl+-)F܌=7 ȆW=[t8VgCrrƾ;W7_~1r2rwrw'ڳ3GMg-|S|)v∝:c.9G\/Sj}&_|$3;l ƉJ꾢ilxp'<=ٷ'_t{ 'JZ5[qm>>ܾOϾ>9ΗǛ?\xkqAnq-{8$ҙTz;܊6]Q]9^:!2#5OF8wr΂מlY^v9jNNjvwn b-KK]dbz%nb͸uIC])a1Ύ ]q8F ƙ?`v,4Dpf;¹S?kIǞxcy9t҇S3hPN]; =q(rYan8u\CMy7 hX[ח%eC^nw_Q5©NfŬG]ͬ?1V0#`l߃yخo2?3|{zs| ~'˹˹}gVzYzFӹd>Fnۢq&'v(+ʛc'flǴtp[8ѓ_}?t"*jG{z'~zӃ7V6J{Y.yI%c~"n&F49&Z$B$d2I$H y:R.2",-^ιlcF/6wÎ\&naXx}]K{$x :8.fH0ɭ6wqs+vgz~@DpX"5@1C$jdHC x`ṈAxC g2֛λ2cHhNl;w\ yzNlmMrP܀lĺ@Pwp v|}ٿX_7EL5'=8ڻ^Z>r^18m$4ci{Ef͛+Yfq{ h'=v"7_K@ᔞ_@=34Vinn@/<o|A#= 9̥uhs2|4G|8!B(!@ Z\{2l&z /tнtairg KCκ.L tЦ-"=ŨM,Ka2@+ӀVan9[^hE Vl m--L:u=&o27{pv CZÕW>J8ٚ:ɍn~֤&AyGP=K`WDfZи"рk $(%EiZJ3R,R^$QF*r퇩tC˪h9aVis:y!~-?_``jT%-ZоYmb >q.c/ͤtZVB 7fRK~ x_aZ&Io$ttJ@03AMBNK@*k/6מIW Y:t/j@W<b5u 3&gd{ 1&7Y~cN؜-"n'Eٶj }kp>z;"%W0O٨VvƏ'ֽbv.sa<S&؍֢Hr5X %ǡT_KdOtLljLNi J<,B^ڋ-d g.pםtc-8Etp :~Gg\<ez( A r@PC*AEoQR G {rG4{L28D#?FLhTe Sb3rA\d`0 P^G(B(ezɿXDޘz]u װ\k^D1Ow B} CqmYd2t*T}4B= -?O=ڇv974F^sk.f>oAo8]z!k\~ evhnZwmVtb4Wc8 s@\gI|Ns&*.gXDH]%KT]끰bQ"@ 5Ab[`hAj rGC} 艡xn  _hhuw:N@.foZBg zL@.@b/oՆV싢f":OX^h3zhF43 t֞MF{ݴE:D.rhEH=ntew4ifHuwIҐ6|䕗]~/BEhcVsR|8W~zK<~}2oTxso`:x[fGBpg>}<ݙ ohahǷ-1hjsns{if1?g@.לЀyom_ 4^gUKx ^|oՓ܃w{G_ gw~|KGX-Wuwl/=ҷhc{슝cGx2W?o[{="3:z 3Y?UcU=Ե}C jm;V֊ѝBhc\prh\YkVnNp*I%2n(Gһn,KGj016=%.3 2Щ7e`iŕ9ڑm9=sNT(e,/?]u.w s1=ގ x۸X!z0 -msY!;h=b1OQjEv)G_IDAT}29hN̘fVf mn6CC,ϲb!~Ay]2v[N(0ԺZwS.CBӜ0[3g6LL#e|xkFρuZ^G+"VU'6c?56g6 >O'muWr|z&Q,ڗ3 bL!@qvg&}WE;鍋6ͶԶ1{1/;Є7*@_`6W蛀vOafsG|tG=O MEkϠgSlb ["8.zeE6+qY˚ :a  qt %3 $"@KbC^Q]jJѹPGύB? RͤKS?՜lcg53UG7}i輋ʹ"s;`M98FkϠgвhإeQ[~ e{h0!3W37r~e2|sM6Z/EƼ^\F3y-a4J(4l69fn /i}.A67C?dtqp -nQqʒSLqHnM`7"~=104'(-A+ ZN2bQiN2T('jP^ҡl ZД *JȘB!C데44F8 _]8&Õth^=#@x J@16aa& z :SPt,K=.^+tDz9 z.Ď g3וOU{'͏[_:W/ȃ_ :s⻳ά6ͫ+Yst{h"Cc3,Գ\:3-id myjw vsr3ڏ]6>6>l~F;Fo;~}~I?urw;#r/Gonڏ֛B--<3m)r[ Ɖq2#~M;ic-7Zxg7 (-Rb3#Tb$JFnmF ^$+v 3y/NGR&:HeXb3_&J-$j\@gD&g"dȓ)əYʞ r^[gÞq.G(:E *%r0wx:mz-{Az?h6=!C[qPa[,͢&h e^; u/H"7U *Ϯl6r.$=Y%]?ڶE;59rQ#75ƨZc yh#k\@LjIhhxdז hqU/x􀢑wY4 b*ΡT<:}P*mIhBGvY,ݡZ~&Y1Cz̙"@C30clrȋ yhEmcVa|OhK1ykG_9)6pDgg]|3 z@9¥4.sqF,Gg>zN}7˒X1M@"_@T7Н逾 ܜK= >VuBBgAF+=yPd<O}0f4yitE7TC]hEtj mC?9hHP`h mZF.g(T !d@wJ28̄FztWG84 h52 >PQ6f3!& tҩB%袈@AJӆƽkxJ9mXu __l@O4szg1yFܘޜͫ4E{uM?-ll`;!~ (4z]r#g`@=_K Ah;71#;1tC/9ctg:"V!tB|;·B3&4b3.6cb+"|< -ECy-CMVc$#`&M@L@ޜ6;NyHhzsOtOw|L4&z#@s5UlcQIC"ش̦6IC  r8`4z-eQa"Wl\%yڬAV2B{<Օd?ߘt=@UMB^@IfdI9ZR%R5fK!4m hk؜_@;sf囝b ۂ8}ApX9T-y+yghӻx'{ yXp/^VM]^-nYv)K=KXPא|ZoDdS,`袎*F m @ӄDe (Mz%||H9tti-RI9)(Υ\&!=\t^ YH.q>s -[,rX Kto)wwz7q`3k[/!o;F>w,<ݥ{;!@ԉ's+ߕom|/khC輭VhjEç &'I6zTOgVJDnLfdJUBCɵZrk<_ol7nkޮ.)?rsa$7XDKtʠh_J%t grϙ8snWL{Y3q1WFnaw]b?V ` .S D, h D#h.MlbS.t gHPߐV aPՐRBjPXF0¯܆l:G3:MShNzD;xy~W܁ZGQ+$5 hhaFNq_Ρ]qW`!ՀvӼ '#t#1p+$EtvGfXhGvBn&FZjdzVzNnfV $-4" &MGӘvڷw/r4v,zdzW_"7H+SiǬ=&}Snx$] 03U)fd9&LSȠd&0)Ihl :E\8\0 @#:WfhV =Y1umpih6oDẇL_ hPr Ghy aꙬ %z2huIB-*%U\6 n5.ka8,!%負Ygr%U^H(+faa/C2D C/6!@/Fz6"A6탫=(nH#NqJjQSgШV2t6W_ `9D :R(0N^!@wN$ԊDZp##P z @kɔHɤL@g&2.t-h1PWPf(Io "=UHB3oq^v3t) 쩙zn.,, @ 5.[ p}Ăܘ>B#HCgt_6n͸[f3{5c6=S 1Fx9is^ݙvymߢ ײCkh>yr+uWY3_\}ot{>~2x8|zjm<Ok;ϰ;GCgVU;OZȖE[Glh/v^[¬o}۰Y;-ʪ%m>I[ Kݷ]>d~/oïݟ[_p;?M=#ښ8^Gt?p}D~/z%jŇz^0y7܎Gѳd$;ƏrRd8n>_W팺TVb7&vB3ţ)P+Rhtywn~3˃ѷ8jg˭g{bn:0tƤJT:"Xs(Ww ^Wsi3\y@Yы z.r]W'1xaEXr;܌Z1S{QUWbZ?$hZLEa`-t~qc]5ZUizL#Be/Zu{Ht4C+l_7Y$BȠh_9/(G`h6e|F8:ۍ#}/j_Of2 ׈jZ,rY)VR]-ՔRSԵzIzVnązDh*EmWLUC tHs@Ig93 0+zo 衟y!xWסU=Mhif.BoYwR[&{tLߠ{4?8(7w@fVr3+ƬxhMn&+h?u?z(5l M?3lar,3*%& NjL\gr0p@8V9#iY^˂E=ϋ,/|E߸:}/Gߔ3Ut  oC4yšSCϙwl#704iD)=Fk1ZjBt6J ԜM@eD`5B6%] jP;AϡqXj:JI`'lGAf8H-ce#Z2=R9-Ui9R 1q>=Ha6b AhE.$E:g)P5W(C[ fps"2|UU'tFzUfkټ:ѳiXc:jNguËTyܘ9_Bf-PE3ά3EwSvYj<ˬrkiUΜ p3XB9K~48I̤oYϗ^{w?"?a>g?v඿`7>w]*>\ݵ&rdo9v%̑xxo~FJVz{zN(v'OIc|:jVw='opF!PIqZNJ/VnۥOo>.WիϪ[ܻGͯW~;ֿk%+B+d"Edbxg%Oqg t~P9+y5fU1Lx*7Tw=ݥڵ*U(_ @'Z"Ց#b?*@ƴn2τp½r dC|W FdAZzF&8 0?ԘH=A[v qr74Cxj6ɭPhq\G ߕۓhHuyP}ZsC>p+vg#`-@1c;1vc'vFX` D"t5b ^P%PSm=7RkVK`kj2R-!6#Rǐ:bq11b w9ȁ!Ό 01c/VAT7Ԧ̵^fE|ܺJvz2F7=O|Zqu{~zlcd(v`d. .f1w0DN2wf$D)05jrLa3 `&6%p)$D6)C\JeS:4dMDGh 'P P eX=êYNNVT@|Y=sU ˶ȶ^`nUc:G5x3Yg QMjqLe' voIAG3xLC#F8hd'Qڳ*>^KS=t137C197rA<96s(y %\ǜu$)b69,%cYfI6E]z&-N-> :V9OTUȲW|c\ ,ʹ/eԕ%jE4ʢ:-thƃsXXh3A @#=!@O y\ׅsNԄ7#0P`h/4}7Д +zF1}91WD~h =!M4_/$ɲGːyuoq=LJzQc8/%鲒js=L4dIFj˺Qk(\[H7fC~R'v,؊H#5߈ւj0^1%=V-Y@NgLFN@q!3.w"Z.)Utd.sU)@gp@]'zv˪vo|uh[Q}\umcj$5 /LgUarw׾LG[ތ>!hFcu;Vc9uۢNh,M@ƏZk'ߥ'ry -v..4YjХ{=B\clrUݿOGgRТoβ+Bu-vfpUgU6sxk̳9a0V-Kh9S'|\̚=Ngƒƒܝܩp{9qܶEvЎ+˟R{_}Rk՞)Gj%ĽXn<O씳zӝOw>ƶfR$NRl%t5/TJb*h3w˫ohNN~^nnn\+ ?|gND/-z'GzJ*驐 cM/5WPHI`53/FkMu~%RJ?g 3 Tjd{׿sr{qRkgk^=kH"RhTmbZ^`h~`0}YQ!ZG"5hϜuR/>~'@p}Q)BG!W.Tipqe+sg;"Tr3Wfyッ%ADQ[RF==ݳ;;;ss;{w_7^]?* Vw^>X*(R"U:Ƒ(RAJCHy꽶f^9jmYֺZ*8Rђ/dAଳɄ*:cu5^Kg6Zg,fj tMH'Lz1yd#rg8 1)Z =^b;32cڶ>:Oy>!e~ʼ4c3o#i16Jt+E8 Fb(P4Mh"JB@{@)/CA=vhiM4@=#hJ$Ņ[3h*@=Dى(8C4d! iF^$343Ap }Â>geR2iiz&:5 a Фh6`71 cv9@!6m=C@z4hqG6FEfhii v$ZOZ|z`l`G1wOw\5pZvFhoq}bM&i817ld8L|>άhAI 6E(õВhxh.b@aVRм⢜3py(kN%YR+ K߸Yx hW ޤIH苊 r9Bm@3:#2g<`ڦ[3%Ca$Njs'-)g%3iNR0sj̜n> yؒ2Cg/wMgP̝]38@ 8|I?N=C@51tʀOZ{w_w?J/=WzəGQo?wԟ=K5 dɽĵ R9{[tQl/* 3L݈m.KˬeLH!t7ƊDFM#7+F/E<^5֌>j7l5ctw 7C'cĵZ=r΍,ukh]mq/|"c!r eϮsw}pdػgwpkuѿSr{h&a:dz\;ƃlrn"͹Bvm.1\oJ:f*N*SUBX͎ViBU ِ¡gl#<,鲃)"ˑr) YY7UDd9g9~'3cxFN-q7LDdEk=cXR)< "Ah&=Ф&< ^p+^^G8 4zChRi@Ɍ0,TY{t9ӭ|9]y {wNVhgi+Yʂ%=&"Xd L9ҢC9=QyQAve h~zza2dlyn}H8%/ȡ^:e#7d`'?԰тgؐ#i4>@hsL'Aڎg |(,@S%͚Z'bBy(K~$`dP ڕ s::*H63@' >v:R 9!j%hwr.fhwZ&$A@ s T:PM$@g44dy@[2vNmNoH3 :c2g'MqSfN# )6!@Mz.@獓_h2\I@$\t-B@֮׻C;k`jP1}=w+tX^6=4fz3,hcj'ח;ߵo>cg}`pO]`QZ]\%mϡ{kK*p-ߍ X@{fY4gp.K}ޕ>eߵ]156:^7oꭡnou<, Is1y^zĞo'pm)q,F^s=]p#lm-|}wn#b+CU/ =tOCthm XhB=OXRFlz.dAs{&R>%g|8)>ÿ<[{[leW#+aqG$Hy9'稜ȑx<ܢ yhv6[6655GK]0tMgUW*itMyQ0kYU˂f Q4aIm=G(hf{8|˗ /x!‹^$ۮ asz_`h"@NL@Cg ;̸h!@p\x4d4|[FFm67 Um*!"E7F;4_5@{[@<՛R| 7.{b?&r0,A>. q@@BGedL c<XŽ[ehkՀ͒Y;Yd*M{=W'JuM]rҭWZB_J/sG]ro+w%Qroy}}ޏ;_NL=(IcAp wܛ>iz۾iB-?7$w;X7p-S ٚdu@ahtd9sŜ=ђEsx\(Ls {iPRk;V_|{4sdܡgʫo<۟wޕ!uqĹ0\f-EY@|ka'9:"RhO:.'p-Je?㽃Zg)ņP ? (NC>TM)8 5euZN)Ӫ4V@2.ϒǷW<ލ; G7Ci%Pi29&AYSM{ϳd'U(6ϒyS(F0t9 @9"/R-zD*go8znlٝlmn66Z͓kVl||Gꇇov={om=lDrL{S9؊RfleгhFĀ$wqL^ី򩴔(('1.&sT8UrHBaUHXD!Z+:j Y n4-IKd.,EV` :3B@@S4eG۰ šVU =NTPE ;xeNWQ4qX"$&\4gϸ c6qE%nh'*"d/L@S b4 Xizg6 z Tt=PTsgl4[=G"hx M`q,zmԮ2o& )I kP ͤ6OAVxߎѲ5s,oD("N\R)٭/G+Ϩ+P/Y/":AQI*( >}^Vr9R:!>@{!nhwZ&OQ ! hrm@% Z 5=1gL:h[)k4kA@kfQKflifs4гɜ4eǡ3̘9;h=w>ָhhԙT,tpuMV@ݦje}/{sܼh@_45OU ٸ]ھ_EC[ޛ?x^=RWޛ;{3} tWlǘ>Tn;E_m?#FߊQt(un4t) 5Ҡ.S05%>`$JF{OhSܰgiĽ8^񯍄7ÛuPZ;w; ;,8Gqqn\ fq mjnyO#g@ ]; cƽǏʷޕs/My*lm{X G@nJ>)א\ IKRMZ<:\jKqE&! 'XgɡdWrqe$(œ-fGv, ʲUySb2-y) tEv@ 4Q̳D'r*[ Jڬ%}|͓kOM- Fmq|Z=n5Wnm>\}f/vK [jqdgsR 8J$ 2^Va+"b-Zm9٩<AG*'sr[f^~utxe` لTсHk1V2Y+6ln:aL%RyrXF&n*ygD[B8uR-wO7OfO*yףnu;~<")_q{4$]dZӜv|I9 /a8t}7Qy^tCCFWnVfu=3.nd ߙt~Oz_#O8wFgqf}>=6vz_~s9@906iַm@Zz ht Чm'{18>~ S@; {ٶhO,7أ8`4 4d$FΧ_QdrԦZ~}~ |3iљD\`q'AsL ąDmdd pY GO Ow?Oh9͡ VYxsVM$a t>N:4Ϝ}@ANrXYNt@J~F$5,)a3R39BkZ?{ /:Gtzv#`X p@ 6l+LDe:*ã,g18)x瞁[Yš0kdAVKd9}pp1L)7 7@0)3ljt.|\o鬓1>\lTp 7i>P$r+ekzT}kC9 #Lgd_ZG8zjk˷ n_ m]nz{>:L9&|;%>k/@F :2p# g3Cå{W75晇ك@`Gj 4,LDh6jݦq";5'{mY#3~'zF45Y ֆ#ݱ̡|uҫw~7w/KC(73MO3&n,5{d75~r'bnYy4.UQvi@PW]\s؈e<)׌ՐSBE*R\S 2*9d)gR'y#ۼ o H́y 9*2[u Xg ɭoU-;7xl f+ve.T^ 2q*ѥO>͕[˅|~~&;5Z*ͬ綪{Ikꓥ֯ŧ׎wrLm-ߚWZLq4>Ef\xV%J*Uakm `1⨬dϹlMDVNF _{{ǿs'߾|uy+sѐ#s"7j#Hj+MZK7>?){OJ^^/I>9tE 3 )zNch$Q*iOƁ2m8s=5'7tup]'@= mk_0Fw+8.p47:&;XuNhtO=xCDaMY {Κ̀,铽6  4DAKz:31W$\qT\z%8~>N1,A:󝮮Ò/oǐ8@ "Q Nht趃.z؀w@4Qog5q!  LV;Kfڢ:x; ڗo.":9t7 ^K,kသ- "44]$MڭQ| ޼ЮJs8`h9;A!A *(JfWXrd:R^P!g=(Uk tsZtB3-<\HGe&*@92L'h4N!qҖ N?gpK\yT md s2?/5@?RTp)&]%]z]5 6/L h} Z^qaFwlu ]Pwl?s4^-\8+ 4pG}<=KyO5QA=!4th=wttMD9kyQ4u؂w;g}pbR ,l}oX_y,~J~ԥ{Wvj15hSlk* {Y\}}g~Q#q8u<ѳ7BsVZrruQDT*n:1-|sRe'^Y =Κ,UE"e]Eޛg=Y;C+"+z<YyyWB"4GdDu 3̽_>~uխ}2$\qKM`hI\c<[ؚ(=s7=_-VJOls>Z.NgsjsN/?_|eݙ\eP_+ӵD0z>|yzJAGMfdQ%Kj^׿]+ X S*ь>O VDly5?a)c⸹4i.Ys5"Pn2S}S.sVƵno>.J'%âr +Hw{SQ0$_ Gq7D"28L[еWAU }:ˁUVb ^cpY6?͍`3OO1;y>V&$^]Kxq/l47ݓ1c# hҊ&P`S=3fS@c+n Nh)pU\-I Awo #@гmt`Oq7x08}n0E@~pݿЃ }i| CFym\ ̹͂94?h{#s>gwK@CCwn;B-+Q(WMo񥙍Ѭ9k4@s,MDT?LK< ڞۀ!/ڥ^}z9@oGҍ]rxp?Y{V/S3eR1eX[:22O&s`tnֻf2g,WKWҵ_HطF>1;־~-n~í,^ \Kp8oo2aGcmM<+|pkww^Wͅ{+›(M|S[sTQ N"*!&o4̾XYy|R^fU*ϸSIΊ* ˱ݓ=q!㳺]Vl=Vѐ94iIK]3ϟգ|2׺Yn׊{|4sK-7DaJZT/Z[Փ]{\XIN%F-^oLc&ט7ve6{oz GV,e+\MNJ|q{NVٜz袋,hQt1$۲fL=l:%X]Vqr[^,.q̅?_"|8ƽt҉'y$ IKpAlMZo sl0--b)$Jyk/h?}ϯ˥ǥࣼy~Rt=*J%AQvN^Vӟ6ȴNxR&,MN+d,91m@[N1>݊=?͍?z/p\4 @ \W'Vr$JLX|Z$qXaagyHE.eFИG1ESE O J\`$h8].ē4`i h5Ά7JЙ3/v˝ZhZv 4a 9:4^ к5:<#L׳:Д2L)Cp~C >Ԗ@}a·o Lw4zhׯ3|?ڍ ]4Єv I2 Lt38 |KR([J|LvVCY >r,X$="8kA,V#)rJI.JtӒ%y; C ($!QʮNq$J!j#6#:_:x# )#  7vq9qh;tk:.@g([|{{.b"b+جy5o̖|jВzEФ0>7¨0bs#҈|e@j\~gmC /L9_sjݦFggnhw[t}>3;^AK\6fhsըzwg{4F{F@/u0^E,mƟp+á`h({<=]]+-?86>/ D}ERmRU#V럵Mv&>4Hu]p^q4Jr-GGss~wgO/ͯؽ_Iox6>6Vk~nӣ}tmVdj#>6Zpѽ/+_Fnߚ˷"3:L# (n5j?YY|2OW92 Y.ެg<'(9G1B_kNMy1A{E%4Ƣ @ Ҧ- 6VKؑ<Q6"%r%#_ó?fTI9V?)x]Êf^}9XJ:Q.'$:QiI$>c2P93T Ua.@ +pGr݀F5@_t+wv#8f {kÙΪ˓xD8me&DS&-3@@h<$!4#.hͣy{ O aQNh4ߍHXDZy3 ّ跆?C.m_. )Z\l&tޙr yW aʩZ 0,qQOn>W2hb>_qVQp~]/-> 0Fx,&39/yz*~|Ll) xZAO3䝊Zç~2]: [e*4^RqcHL7`֒Z:k,:7oM-ޟYݘ~8h~a/HWRdn!]ϔxf&_>xyą\JxA4a'fx'S=Sa1Qɫvøy9 {Øn1os##. eǓ@A8B  4Ǝfx4)/ )ջ|1w|g|^}J<'yߣq~Tu?_n7^7=^h1GBfR.XA6զ8fљax hK Ŵ-u}\T8VzFXɄAh~N3)+D}9hu@~h=^g4<]֞2˺A 8澷@:fthV3}m@3ZC6ڀ i 1Z0y#(56FZ4t=419J`fQ i lz82c(0j'agprF\GgFy1 `w$Z@ x܎ ͵'4:c Xi D*q @g >)q6GQELqB*겫.Ʃe]v;$7 ,{YU|H;(z;") 9ASI]#zU {Uj!+~Vr^5q%]wy?#J:j8D|J㌸QQq 1O8&{gfTN'i2}ISWT{#P0٪jVZ6[&KiRn_tcYӳ6X5, +[Zzf6Q`xsjWκ޾itYW-PWU~$6SpzA|ƴQ3A\.%.hv^Qׯ׺<=5cpX L~xcu?{wscP?uܗ<޵ɿߚwpU1SFMxǜ12FTxk<5)𗺬ُBOEw7,&gZ^_׾5doG o]5 QS=T*Ȣ.a:hi89Hu{bXoٰyIv7i%-ж,$<$Sn&s$B\4-GٻsKoZ_(efʭbf=_tRL1Շ]b VF "ItZe nͮ|7SxՕE_» |8hXF#) KLlY̚ YK Dډzob芵~V]A렷%4PFZr:灤{hp]K^HY₀=Ew׷l w"# iO܍ow+7Yz$s?H)ܚPsbrB+W lԼj-B5k2tpD82FKǖ{Z6$^G7݁Nnp iz܃,`CtuOSfq*/ڔeF.\k s8;M2-Q@Z34cINpl;յw6_..ggb ڝRz.$5ψ Rruzm.ꑭ~[G~ ;;јG(Y_|Wzv.%#l8 }ͨ*៮gv^3{'/\kb³ΗB77֚:R#5W+J3^;|~p|yã/NNs総=rn6J%40B2@R_}U_NWTOXG> cZIOETkzb7??{7I0l}F0 z]j&R?y6_򻪲q>nx8GF92;$Ox2- d?G$2o"Up!UZв L"q1jk SF57/4O ӝ SȔ^w>}a-ݸgh}otc`a:UiE(V>݌z:-N:zek1[@ (G"!m.¦PVDeo)؜)ID$Lt&sn} @aLd$ JT$$ q`hP|[JA=) 6FM)dFLĔ6Kr:1+44Z:i JYUKQٛ EhČM((4 ˞:Ӟi(=iG4H 8kg @sÓ4@wIۍ#Gz1#yvڮ?| h_ zK\G/@3>l>o Iڭ0B= =o3@EJ%9[҂N8ń,$E.%YΞe,Kg}0q w8ȓ @#'GNpi(9HH%KN%ֻ=O3Фwou@M[g~<5m{H#<ȌX*F@Q Me8a:X<;@0C Nj=v)PVyސUoM_?q nͱb5̒:kE>m/ˣ 2o~<\i(ckU $}s"kp>l?W*4* HNkٌޘ<|А(5oN_1+m ̔obZqgX3zfS_UTr45kQTaY֚KjsACtҰ=jML`i&<ˮ;0'YBJ{D2Nb1@S5(Sh2elh܁ŝDCd #Qtpe?t?^_bG ~$|=?.d?W[DLP9(!eCnDhfdgM,i].6\ݛ_wEY .wD#4j?{ڋ_惫" ,4}qՋ/6{Ѝ0t'HUF5ZݬխZZݯ7k󋯮oo$Ыr2ɕt?Ob5JЎ,B@׀ƳV"igR$X5Jyw67,~,r%i"k@W 2(tsh `0Ѽ糀Uno6OB9a kxu(T z`DxOgMxEE @ =s Fn׃=ۇ{[Y~ЊO+@GHY:4P| =ht&@@̂a G 8[>hsЧͳJ}=+Y,:gii)4@m +3nUm1C%46j ?j{az~@|%Hu^Sv87,sԶ~ t0՚G5>GmN@.}.m|>iN@;Pu;PI>'wYRYb- 0t A? 0u ńAny8V H^F1?,@gb!6LJKb*@5Y1 ``>N (Ӓ9@~% Y=e0`b eRj^"ZC涊쨩4yqsQZҺW޵TUZy][W7TК* ,jWjsph@M}dk$}E;ޥoſE}o\|h(rWGWG#hh$s8vccmv{HZV v^i55iË:Ь3 HNJ:%*sw.ٛS)y8:"iM5WuZyT.ϩ!>DVTXQuW uRY~l1{s۝ -M+Slde-s9}L\ť]@ۛfF%8kPƘZÜtIYb]9#iTEtd+ߞtaxJ"WJ~,%T0byaQ.h {Tr'@-e8O :--o>q$tVlJK7t=&t|>t?lvٵ ,21v#ʋ+;_=͝Gnv蹕^lg s?7Vslq)WFӫk+kr"'rЋ̵=o5JƟqgI-XfN-=9qW4;aoots|d/ܕM0%ktp ޫwWVxaK.!鎈JtȞ Zs ږə+#s ww7w2;Y w3\59tCǃw{ N?ٯ/7s a>6.9HpmM-1QD?[@Yp=$)Xi+Oqh5A D@n4sx46W XN);e@SxzzMY4nDc'ɠS:BQCyB`32o4p!~h/04d׋no4a \&Q#-JT$9Nq O08G߫g, ̔fNzN)t:34 Fˠ&< O;):̉Yw%{<6ɍY A41+Q#^}(7x&7y/jh #Ј:4=Ds Ӡvxz \?<`pnS093hacУV ¿^@یrsp8/p]"Ey0ǏT _ى*Jbhgh>1tXI>sۙZ"H-%s\,-~rtן|xެ@>{ѫp>q,Ko3VsAŽHv)K~a3~+u*{Rh[m v#,e^XC~}x\- _D"L4t)w"||3. J|a. | (wa"h80῟ <2O̓V[˿؞S]ٮ/rdG%K"H _Rq?Pɀ%Y3>*!3.2 {~e+cXňRGHsm0o=@+J֓r_j3a12.:?f2h4&qP4Abk~}=(M"svNeA@ëǃˏ;CiBѳ@KfKl(f&cfsLxfXYG^qt$:@L I#3df1rL]_\n<9ۋoqRO@̽} =czƅɞIarvжS@L:e0}d@o cVhhxuthmFR 4.vqsh ;@^N y ,%Y/x-ۂ; >Yhhu14{y @J|4ħ8>/eIEz,\@j0t"X$'8::/}@}@9+v쎜͑زkdI*GR3Y"\E/+Q5g_{zFʓI>؄6n6f#2 5Z!0m`SUm 2t?_T[ @@ =΃4}Q˹q-k+ZBT*x޷'Rv6=?^uND6t}qo/ٵjx82zFd`=}lG-]^~!?ˉ-MzGz[RqC!W[hilM 2P3dCO5tTSoiMu(i]]j ^[[zKKKtDMhYUXUT hy)LEB@Xkc愳=\ksR/>Swqe -]ހ-cE̔Mq(&(,e.s:@ih2&H!|΅DN`nңf%<4&QɋF<죒~[HYW˫;+jk>гjp04B@"ӎ0-m+k/ѭ$ńmNEy"o?_ȭ/7ۙz'Qn'ww?'mN<ӌrI򃵍/]֨mA@'zg\So*?K+Fg7: A[k):EhR4fqȲS[IHH>{(q${/y\h _od~Zi#yG$eEm%N  X"  Z@r ZA`kK"I%R^26 ]/XEh|@!,{)V~0Gͭ;P\tF1<&r?8QShnF30, @ Y(aqd?h2 #ڇx `fgp h Sp:! gOK" L42͂25^,g2 ?Ѓb=Czz&8=Ap?狀#0߰uA@_sgf@{פNi*:xhtڠrI}+o #<h zX3z-2@@ۆǬ Hq;h|igL.4INSæwzol&X9 [qlg6./3淿.`ǂVoEp,Ȇ: ef$h`hCNĸX8O8y +_!p6̗%jGIС2,tg3p*,$9Q4! ŠC1: _>oIz'r睮Ùzg)[T YE(bx AK(ZF)z=6NL BgӠg(RE4l z:Ekefv&F*qQlV{=gz8 ={OL55~4C[1P"*󜚜W[@"̾\ָVU-g]VV{7Af0os[y49v44;熝 עο -ih_+\>MW_ZJw+hx_<]De*0C I]$Ia}+cI'2Mx2"QB '-\YU73H+Ԃؘ%Ydq"L17*mY] :m>+@ }@:wcl'+oo}|}5_:E.gm9|9.$67םr'ɬ׺nێ73sϮ=zyt!SoD!AxK$y9~qN>ά%+'ϝx)%J_>z/reW MQɘ4 pB-ִǖ Zeb1cgBVk;G7:o0lҁ!]|_=nB/XsyW DKdɟ(?Ҧ#*/}ӍZ{+?xՈ8#ciÜq)=u^ M7WuG2h&KGA"0KAJ ,*+@!* Hxɤǜp);,@` - H~)L814 h#g; 5/|IqD' 3X~Ų4=%, _Y4q#(kFB^$0#"A?ћ?`p fqK89㝀8q hEotzb>+ |u5y@o<4!MAʃ2A=$?n Q8Ŏ1;Ш-8bqA`o`4@`o{g5 gl7 i%81Vx+՞a{0ʥrN@vO{>Nef ӳN Aȸm=C r+Y@N ?)lshxu`g]fMh0ـO3Y@JRkr&Ce>T|Nŷ:~ v[y=hg,SAZzt2\@zI96P]1nQZ?װ6zn@@#u7i 7ghmh4Y@C+aߦ޻u/ c;u9o^Z3K!1ߚ(Wf}_frM'.#ݱXlo,y 7VBmtM_:yW'miumpU_N|pW>ǜBNzk`èeQ%(ccS^gkgs<-4 %Z%U7ܝ$ƯL&Q{K+ۿ[z뿲o]]A &W{Z5KpGW4,g(4aEeѠ9ʘ#")5ɀ@9R`MDCx̏'Om9SzqتH7U60L{tϞZf^ZMWf݈r =?WIF+4Y$-t)盱l+i3xo˯?YO6RD >>t!zTb'R,y+'@#Hֈd4i )vXR^*7K3sI5I|+]>79zc7Y2Co&3wލ{ziP`!hJX\ ײwO7j q"t# (vD|W"Q|7}>y_ĿǫϚxxKbH]Lڢ5&Z,94!J- Fd"9DB=^21]椝Hڈ &<ӣD>[lªi <ASػOמ!QшIŞM8a !a3{-<چ^7q0=C@d %~),[>-zIx+34|(3\r);oLгh;tvGQxoi}7*'U{~~ȭr t^o>|chMlà%@~ܦz~ /o~+cω)?BoύatV )l뙳8pc449͜ .B3 C3;pAt2!] a{|. RPBbN$`h%͇hG: =v6QZ0[ fhYe sh#=V 8N=c-l uz?jƹF`"roBC45 l7fw/~$?A۠"Ty5`!U%cYXѸV5@{^\Zv4{i] zG[]C`@/+:au43o=.ʐ5d >!NR#֯Oh|t]SW5mu̦. j}Zϒ54lmg'de\6= +{NK/͔fJ꙲f-ꐒ-iZqGݩg/?_KOcmܵ?nlxd eVfiG}ZE ͙x,1iB0I*8pL3p)H9AdfEq9i""bA" 2dgr[?I#:B* ߏWjvxyWwRy\ ^kia_I-Uc]`vr7#ܫ>4B3kų6(ث6sLn3o$ \7 sb;}Ny)Jt ɼZ0$ x'fszKh'lbBy|t3!^h8] a@`EW/e%η9Ks]Zpd+乣r%A7dhѳ^F"^s7xvfO_o&] E+HeKT– q cXUa-QCEJhpFf`%P$g2e {3hg"jp/ >oO(~X4gМs4oמOK0bREY epMp fY b @M#~4b0 s8=A@CCcHPAE $f d?3a=QgS 1#Ƅ a^jiIql&,+1)xNJR L<5H*k}=C@Q(bQ{pڦ;g =`7y0ժ?9O[ vj؋= hhD0y{ \>/뜧5<5kV#@4}1h+h*݀Fˀ~= מ7چO 0ڂ@V=c,lh؎rbccvƯpN. nWR#(rDŠ$t1hMRa)E P0T=C@{|'n΂YEV2[D@SDz6}@O+M_4G{_WFMLz@g aF6BZ]25v=+;]O} *\TQԖ%yf_ikڽro= Ŵ:`k*<r 4Q:jk[gmlaGk͍0Kv 3!VG;cq}JGwFԁ6}X}|s~31@W;6TK kH ]=7u%k@[pf/3)NcL.Mޛ.?]4])Ԧ --{ꬸe!ٶʴ\yn^xJ=%k^.?:DXOJU0hDr)=mP%Ka-HĎJ.Tc|8;Ϣ!TB^GDw_]+U.gJ**̧di!UT>.uB 24kF&<9 %&|d:.v?_\ʋvZ|p \C⿿O=_nEBhCVU^\dRd79JD^-owq8-7Cw y$0ߒ}p9得?NAN*.\7}L/}L-p9D!Jb-}@{=;`rWuB@.uB=0ƨ0F@C=+=@Sܛzӳu cلLqLx&@}@'fNLnY=GҤYM̍˜Q =XhJ@|.1<tg%fF :Kz輘@ۆ55Pc&FT8~¦6F@IK˽.ڨ4E"}@fh39Mp 2 {"{o+nvp*)j sN@n >ļ0c+a!+F(f@#e_qhs[XXppJ3rA@Za4ca,hH2 r$Zu`@sWh"c'Ny|Y78du({I4lT 2PP=@]MaI:@h{iA1+sQ7 ܛP_-1e:k'dn1{Ujsla5SX2tyP,>?ǟVhFvne4VӳHʈ$420zF>otL Gqh sH/+ Ф <@e3#qz1J(%g9L1x/tͰm7{Ux>)Hd,6G&^Q9 ladx 7HY4 =bGʃo䵞=`i8' = VbYOmYvEui#@ C  *|ΜKݐ}=+lKӆAЯ#rL9?eLE15p УֱqR6ЄhӨ)4=EfH)@i4mO3MS81C)R7[^x[(F;{07bO7vb7:M9LNĭn}:Jw iV<`!B-:S]"Yz#Od}B=Fy$8 BDD#p#"sU"\EK[,NqY!J2#EIb"" =1ӡ ~BtM{9p쮂Y:Vg){V̖R#ncD]to4VSjLaI1%mN1L 5NlMfrGZEAM SMt\ٚ0S}"+mj(WSSrS AC4dy5?dY.\./ٗ.9/V.ACo}[{Y7wu}]`` ޶r-jgWh-4Tx&RZ+zGn^Lhxhbo,?ݛL'&G#mwGL?G) =LH6}j͡ڻs-3gWa%-V y1j3z*L M.Mޟ\^Mf RR7;;þwy*k]n}?_`O- Ƕ[\Xz=Sh9y(l榼a"k3XyTNΤ'S)4fψĬ`-Fjd2܈E#^Lq*ڒ]U%\\nLQ%-kG׹|v֢t_hYNZhɺʌrUiw#iҞ[} rp1,|lVM#XkFH-?ܹ'_V%F{zJSmJr8-vnZ*ϯOvVڑBe 8˴&rvz?=S>`ػcxcuQv(VRq 'NOС)4'MISoL aH9>d4F$bD$"Axl( '0Mγ>ˬj`E6=F~=``h; B jcQ $"4J xTt@e  zM&ل(chFg3A@7OJf H Ncʹܯ'I lppgvdIAF zF T l Gprc6 `9+il1lV4qdջaIRdž@ရA6ʪ\msYa55&z7-8zt2cBI;hm>6 45 J20t:t4\!$ƹpce% 11L"DA`"LI٭ @;E(=[UgV%==q(^G4Q7Y1$5Ax{ֆ/Q8qm`Sc08vZ4A{uٝgbǧ+o"R@9wdd[o_|߱s}gCo}*֐ڷ \\jؚڵq-mgzVUʐлOChkyW':n6u]C|o4?!_^MOnÅ];_z~?D??1ƺj}G;*nMOxGsTghh+z6j&3ꉌ\2h"Ϫ'_ͫgjSIU4v͍ǂtXw/צd|j?sTk_nʷn`d`q;7hZ$ROL&R ivRDfD4-b3a,k1w Hԋ'~s&,G,|};ܹ[8? w2uD7kO_Fn :難吻tΊY :gwE| y䛧?lTVvUhj4r[t~Ńkk|,-&˩Quٮ׋Bi1;b\,=zn._j8 b,3ڈ4'/38b3&c50SłsEYKx)o|ܼ&3Ra<|gĹw- +}>/w#w yC ~?],= t?#Dn'QH5{KG|7eq"AAy'b{v8zCF.W̺Ŵ#(%͒H-h%/yB&pH4Gk OXy<\{FHy*;<'i-r[ka7ý;֝1q21>hq -7MŒi:LnY3b&XԤ1P&Cx $L nhzF+4,dFvoZg~bgy3&[PA `0 W (z` 5E|RA*e 2zVroiֻ|yv:W8:`hco>6e'a*Lc Oʐ"8 C:m?,6{OyR7[/1X=Ô{X1`eBi)bh9Nv4ލ {gIgLypt:8 מ}z۠4gRަrv^C4yV>  L,8IEIn䅆A~ tBC3sK\c?WR$r.+rYVZTJlY  Sx2<:$@t"J) <ۛs{ NO.)pеS@d#&aT=C@@+t鹭(s]ts0Ҿ ]BJ}F@ 鼇vt.Z W0K`mK=C;V.UMw }yHw]wGT=;U ƮlV۪*kEe)kUs64ֆ:nQ',뢛CWf&S2LllTxXDTcۿ}ş_bˏGG5FF-sSWT}@5Y y2=4v5hECtT`zƤ=>BjC~?&OGYj>$0/^> -f][sObqSa|&?9LLND&ř)8-"i 0 mH$lADyzTZ=$oHs v!V ͅ|\xo?i--ka_5쫅w|^J^KutYGwuŽJϞݪ-S X\_}q8쮬J&?+p=oW@ˋR7Wd |q\^)logw7r:Z n,c Tгe_/t68cxKY7yy'z~_%H0*r!X9D CsNd7S$%KǖmYe3gz9u@6C[=u fQѯG.Ke{ͥypzV@o|v{? ޕnTF,w#۲q7Fw>g}Ӟ'l|~&|^}/ܔ#AܹrҎ,|P}sӵ{c:5次)q1,3!Cl89C,?$AFv1 2Ei .?p8W}hhe7c>/3-Y@zGCG@+z$慀<6gMaP4Ec h- hЊy7)74:@!EJ u _uzxMy uD@xp98P@@;Ol LQl&@OC@[ ЂbÔgN)VcWgsc61H ?옏מ@gܔZx+ߠg0=jo4wx 9[֌p׹'Y@, hʡ~8Ǔ~hJldF.B[U1MŠrB.채ݶrACG4Z FiT4'Н oo\ [(ޑ~<~3?3>MޅzNCShzS?;??[ܚ>\l2W^&G/ԗf—Ӗ0Kㆪ*q0MhPY6etq]^+N"IwUCgMcgζZU4{]~/>NKOSX }[iϯ}ջ_;zϺGz 94ܼ69_..tp#׆Q]0:@AsD\ "26򈥐|{_ԒWeP׉ CJ>w#jןp[>zN{>K)֚ZP0W4*Ǘ{ņ/W">}G7^6bjU .-ɍRWiGH/~LB!wZ>zqrjq\=W*НBiT>W__'Os9G&nF)Jsdph$C@H  h4x'hi;m?<ʣBt+Jw᭴Aҳd-wV_TBƭG/|xruC)f½s>:vs;̀ ;i#뽏~dž۶lW재=PL#,sryp  9 C=CCD? Ca'3q!&Qqn" Jdp0g~ –^9T!ӇZ8l++ۆaDGO:RZ8<(@GczhT8Z@SD ^Hi\ \4 %lD&dz> h4 AI(LRaQP2, =9,a2G`V@뵃:mJM{>? ^[jn x36 gM k7#o4+hyܳMJL)^cZz6@@C@gz 1kT֓ f6N;oI.4cd8դ6FM!3Yl|ˇh 3*3LXNto4CR 0~ !$вȄ%V6q ,|"bf,,a5NEp>P('@S(t@!)0 :"{"!O,< :t' +pfl՞ &[h+`*o@3b ia ahbB3,i@/N>;w" uSPD ZEv7uZcDxdgDi`G>Qiy@@wG(6"3^P.ϏJz3|<G1iU[Q=q;.uE`Zl=%VƙjFO渭=cD2 ?|-Nnꊛ} O݃N[[oK҃⽙tؓeqgm±2aᣄuxx YI.@HN&$Z+duʠj77\z6W–'/ >{7[V#ǖJGƁdy/;)2Y[֢X`pr3 љBha1_Fu!DA QX%R<ŐyX.}tNՉ.d \?oo|V_ ;[AK*9RE7y͋L$yp5JqG{Ojt4buY6+zCn"K޿\,.[>g.\h/ז6յb[(Cw~x^棏_ܼOjLޑJSSedH"MiK!AitWģ 5>b)Aewh_?SJwg'KG 瓬vk/?(^_yv,Oνe?|e<0~t&IA~۽e^מs.Gj/>ee7#;鰃G& D ': ZʇU* O7E ]yCDy(Y?l", <r$QP\;,Cb:4C#ʧMb~Ggą#npI NqPШD#vZDLb2AȌ8X z0h0C@2AaC80*EC(%}@uZ]LwytXKtd 6hל8 ,g}=|#ѓ<7)0 5eL9if8=fQfT=;gj.[','3iF;-CG'O$a4z3J3f#SzOZjD:@S&;m>=8C&0PKYCC<#lXde%>de ŐdY[e5[al1-%4a8Cp2GБJDFp eT Å7Dew4 'u']ӝrNO]Y9oV5R5Te@b T)f$!tCkXZ4,)zV =mhOwuZ'=A4%/<<@НS4ꎐ]аw|PC|Q czL0z[p#ƝUF檲DnV F RImԜ\}3 ak%P9nimcm\-Od%>>ow9nҾJⶽm'jKX_/V?e~I}ފ?K;#'  n?ʹs'ɺv΃Qʹ==nչo=ʄ/8kvG,Y)k0a FP̀A!% \{a/~Ag:cV:78C$(<=Z\"9E74 L4C7/yTѳhh h7ygDA:L_h7 q^`FEhz@P!P ? @x=bOMiEB^$C Tڿ`-оF~7]A8|P ͖<#~FLSy4bhN0^47%0Й2&|<l5N@[vIL3Y@O'Ƥ4*Ǝp;c'}Vo4fo7гN z9Qz>;13*tFxi= bCrY@+> XY1x(#)$! BLcj$]ϯޤ:hr|41Xb6QAm14Hf0FxVHeIŐ(M,[-a5 mW[il :ņ±@4B@$404sI)SA9}1P {bAOIpaNih-}om|-?[U{L@ LPޑJ򮵲t_OE:Zs{_ZT mjv1z,SZ}R?mL|vh S0yTq?yv^ݍW!=7yz̵ԝB|,.Pds"Y2J6^\olzdh to\:_=\+u_~٧[Vo/w/זWjZX^)WbaTOӅF G#A!62m"2<6i\AtY`h- MuqD%ѨdDle!1pCw_ݸG/=Dvӎ݄y/nًZv#֝y'jOXf]/gY` fy&I~ʾu;yNζ_t\sgy# Q޻um)?^|{^tV{.IK0n E:+ A`X,?d|Zߠe!l7DltlId#bOZ 3ZEXqWzAxpLiH Y|ؼ=̡y$?BG,Q,aA%?@+=#vá b LmB+Zѳc(r  <p$CDP_yƐ-r yw:[EA^"4O} w ȁ{ĹfaSgY@3@ό ƛfഔ}6lAIF)N;=)kC=SaR&E1/FLS:j{n³B1;hbvF'Ҩi`SQqbXfpBCe q|G8Ta'7 _ C4z`賀th>3n>ꌞųb>hHI!~k}7zM'p te 3le#,+($($I$a%bFlV0f8q5&Cǽ /"t9DHa ˙P8$?%bxؓyAO: z9+guΒQluhRuTUhR|pDih-h < StA _\8! f{ Cxj 3b>bb ܿj h `㽋u{xT]`R4\zcT_uQ:ʬj~M-VƸa[\[/WƮ7RKO2F$i#@m^ n0NJDhSqgej25f{<+@*z̡sϢ4 ӄ8>33W{8~Њ }b@GthDgR4?Q$o>;74?QL1a \'s Q(%b-ְ[kaM:-q8az3,{8cJ4RCБt( ƓDŸoR@}hPy+oq͎Q1:.X뜥@kf0U)hT'%o\cA-m%iA\{i39 -=3i;mL. =ՙ _uVg>;qfcJ'֛{@cFF㽋{xT]p}OY%cd_u1ju԰6FV~t=45|xcB=7fj߭q9!4'%g6;aO:W=볾sMmZ t?w33/og$n&n/'LFLD.G.MMeoNMn/,>mLTkuћ.O[=ƙ2_''&\+쭙-u>|w~6>8 k*\f{\yc)lۊ;Ҟz$ů2sZ:gzCCGԴhQtH)^Ba@8)<ő9.؊8{'*&w5_z0O7ǼJε?ZiMzKV|fnSxR4DL -ek[Ý>qx~9Z,Wzي5Zyգ|WvmV/TjuB>D/z6{ţTڢqc=tMed΄gY4Cs8C9=A܍@#8$C$y*%RV&⢲N%{d%s?lx"In l [Du7n݋vֽQvw<;')ۣu?gyZq| jW #/*EN N_/ѯ:/:6w-}Ic(!bdFCpl'KRXʢ a<=f1MT'b WhRUz.L#WzaқSְ}3Mi"7f,c99;d:A (pG g/(z'wz;(͠h֛Ձ̃aFAoFIA&`CQ{ $(!X@A |z ; (fgbX1v-.ĵ 9hC@{@i7@; ,%bƓ}/@IDO H@@C=(LbAQ3p8!̋JRX0E,FKd6[#kfI@;:tex3cHFбh).Fp$+GSr,J$Ʉ?%{2>O=;=* gh %޺YXc3:%&@\ezN4g[sLkm–g43ӟ{SҜ\N!rOTCC3 =(~B%':?w*ƇHQ꘡?jCQww]c|sk*qY%A=WTި3fPVzVQ\h,)[oƱ2\soh[huu?oW_{Y̽-)p]IߜNߜX(Otc_90_vL:s[#55bcBj16njiwbM: om[˻ЅK%7{r9t;|`\!=\bg1-cX E>"Ibh@
Pgڋϟ~yfWv-ԌC@gZ>ُ~{m- <"oNiYj.Ϣ9$3 ^<>4kD8%1=@J,WzaVlyhف*@=)@ %g˧_T @G@^hC= "q@C+. +=м4uG @ ܄NHLilĤC?M=ۧUN͈]3bS lѨ-VN՘[54v@f X7@z1@:}bu+Вk=|G/4GX_6@@3# <444'&В9mDM ;q=G=Έ-GT(x%&,Fp,#SxRN&?tؗy2 .X]hlrT`k4c^bдz &7qqmkkA lkmq0z,:׈L7V/qЧ=@|t@[{ԁxUU "Wƨ1je)ߵŗSWqf*[c U=?fٺ֎ʲ6/*6&5G1 Ԙg,Y0{cܵ6>9WO<uуG3 ŭčص蕙ԍ.Į]+ƺ hTG1|0ذhuJtGQ]B1=k"Wa оyhH;Yq=yhxH4g ^>h>Aq72&Äpv93f׼gӌ8&\:4ܴcL[ëqzܨVK*zܫ1S ;ƙN@Sg `fC7=9E8"Ղ8 F ="PC@xHDPzAs ܌* 9w(vpEd ӤM:]2&j56ܶNط~{N. г糷zƇ=^Aʷ&:ni!bĕC #yITD ,E2x'KFl+7W¶J.ںܺJukf-T,N\*tWwﯬ[WszNgt+sTOc[O.\y{(i bǥ]LNeD $V?c+nֆA=<<@Spyv-05͹cq̰Y>fYeg2Þ!9ip&NÅgaqZx'N:ӢQxi$@gzbvTԩ*xTC38vhO luBmWjC5 TG -2+nj 5HeW&fxޫTjQa|(~\O=7zac p1x1&UJY~05/[@ZEuEE`: @E9CåhF^ A/Yq.XeqD1IaR6x4؟nxo$-a=NhPW11W\b~EgڠDy@#BT(4(N1 s!ƈ1Z3ks`J)3Ȓ0[kd%lI=p@.Oɡxlwg{5'(;=q|DGG^F %ps]|]|Mi}p~lRnAFpW>5TѕїAJQ"k*غo&\]Z*c[e^V[:jkJUO:cJP:քiyܙvmq{o½:=78?02>>WK}y׶{0S7I]I^^ōnDnksGVO|.ww.yc&vu0Z4?78? ^_OߚV6 Z6|Ut ㅧ-z>$;De=◞B|UʾPc[\jӔ}hxJ[dV?veD%ƶYV B$%bft0dI/qEIlmMeߺ;>2dw7͛/]}e35b]+Wf gs4O㇆NwR D"]3sU2Zx靗~~yc)nKF3l'Lk->_^^k]itntzݫz^v2J&H;nDShKv"xrwe틝G[D Hqt0)3  XGp;}Zy4a \ILG-҃aҴ4?L潌i7-ŃYy W~u-AyPmiV̼5O3?Z;?ﰮ]eEOVow˜+Ă< OGE,xe A/#; o38E&q<`^aSJyA@hnO7װzKOcXr"94 R) #:k2Q$\Fwas "tHٕlJpC댃(hЊ"]PZ^XE^\$-gpZ3!CɅ@@{O@fP7+ ϨüJ~P<0%<_%#Aa%p-JA:%p $ ?9></8y3O(kC 9|Æ pYyFM38(Wn}A8̈p:e;崔C Nc2hI'5& #(<{j9rL*xUcGٕ0ZeFűQapS*Tc3I8^._y SƇ'@*B&m3fzoq@!"ȀB@3o4 q"N |cP8Ry~+v ;n~ձ Eϔ0 L qs!6Њlb (- R6iS3%ySJ2MЯ1=ew H2Yb,]sL6 h$}hoAtqUѵC@2XZM 4*uQ@CtBwQh/6гRo444_葳>gwh|G+2B=Tkzv棾;G- Ѓ}}e=7FW1jfBJlŒ-,[&聡B5nlOec3k\SL&t^8:.ޘj\>t㓙ʭԍЍb/>|B|4pvDTt\>{nss?t\s_~ʽ/Lw"\h˷7{=|L-|cc|[V1]:KoJܶ-r8p*gRZ4׼F%͓\bdMuQ5}Y_x+~W뀀ruV_wAwm[f$Ty1E,PxT/&m 9G81xt7x"3q1Y$pzZ뿺lxT][ V0iIwӦi?c|5=/>u%,|y5`e?kI nTڍWۛQowt&Zx9C3ȹCt@,|h37- a+518A$Q<òH~8'`p4vFso4'a  <C1`G:|z003>8 .qbJ=9Խ!S@m A@a@ )h8zA a@u !.+!!- /  ^\@oꅀ<7x3F b@3oQ)A~R5¹g;5$4.1m=hegFm;z 'wV=Xo>- | "hvQiǛ~=9- @&,C=3à 58?so4iVDЃb>KE$ǓH 7sC t}?@õgpY@A>q1ln b 1!ESẖ>wzb@"NgR*_gJq t$ grNtVfCߟsоC1 EWUp-q:lж&ci@,Ф1h:E~yY: Rwmdw_3-I* TB*3P$ RHYйv==wxIY{o@P9Su7ս3vU2z^et h-!kl:Z-cRE_Wv_-Y%vMn7 kmv|;2NtjF۰a[mx+!@gPE CC35.n,8 mY%씄p+ZdYmFLx溽s]Ě$՞^oK:|$ٍԦ,%釪`f_;k'd=F {܎\Au_gmG~{l䰿#SwlxSiGjG~={~SbmzU:lԔ=4gSibxŽZfY󌑟sci6 Ӧ2͖vHaW&*Τw!4܁vtπґ?::ܨ<%,)p$28k-תZm L!Ts,N&3 'n>fkj%:2ONFg b\[)nL-FVJvNj2=OŢh4=MbHl6'F~xݣT)m lɐ%NC39RŽOaIL{uIx r$x-Y]NGg;*'~YW[΍?)Ї_ F8\#u_ƱX֠N-!NB$M Y22-p\@C=0 ra}?Fp*&jBY h Skb~Q?sCZ !T!RbXHDAWQ`(Hh8<8SwԯXh8Li׫|u@ RV/ 23#RHhMae@shV@ . wopfb?~X,H@roI+MJĨBAFC@cT _(4phؖn 5<i5b.G5Z3:k cK_4+~| `)S m"@zПhhHg_ &C@'hC2&IS`"4g |d8h$oICEC[nJ:@{%sxl͋6fD@3 VA@[ zA@i;4M(3 hvP3\s|=PԜDsKT,ׂb^+7sBsȫ ݦ[xEwt Ʌ[$|ˆۺ[֚9v04P3&n?oo؆:4e@gP%֏vǺM"Ih˔Rk=DZD/ psB8x\Urtg{"]If?;:/?GF$ɍ̎2J(Ӈ>R:F|?PsOMB7[yŧ)>ɳO??[āGXz$!g#U͹Ig2jO-)v35K4)6 c O»$XL1N#Axɟ/cvWօA.\+_mo|,~4/Wٮrg۽g~_.D>t m NIhs\V~ftWac2vp}>iv׺ Zj#,/lk UP>@ceP]>UwDZc'?"d2|cgsdP5|:ȋ{⃁®(H-(s)_ ٶ*/#סrsr~ Q8!5uh{2spvZs\Egmig9=5o#pt-]/f9}гVg=S"гF-h/"QUQ *"9 -XA ~.⚢(Tї :bK׈]&RÏ.tѻxrl21ZMTt\˔gR|dq'K>83΍Gѩh|&EkBݟPOe<Ʉ3&}|eXif$Mt1.Ƣ8Ix1GPIuԠYɐG'Eg宺]KnVx<1+3_ޭxsٯ6ڬts,>>?d{dt:ɘi|.$j9'q3?m>Nnk~ό9au@sf@G&)E!?0!'Qo?<shIq*]uRB6 h!…H { MK@!i$퀀&m@ˌ\gE=Tܬ)YtÚIDAT &7 3H0,uFkRxLBՃbnQ׵%8{V4_7wkn _)Y7?e}[:O~} <(>Ͼ@n{ = {p*syHY>W](+oO咽c?)}.ϾkCNSOr-~z?=|gA22^Z {ar\==>yKßma^{CAϜV9`\?B+@n3UiD&kɃ$謂 ` a/pA@P!+:#nH? =[>؛Y&3ch4] Bj$=K,&3˿ P&K\-nSʪOT@&(]Euڈmq%SC (`QJe6 `>S n;;S?Oq1sZJgȣRb"}<λ孏G~7 YӘ(E9ЏxyVkX}%?2/aDt !?۩(g3DBGԺ4N#xFX^|?P/R>t*Va7F8_ J" h%w`uR^4՘~Ai0**= Y܄M^F02m7>R!Du5qzW~fbT{5AC<h_ƋG8o?1>Gb7-ՋշY$fBbnHju;v8:}ξ.<"&曞9qЭbi/G5@s^z@5 b/]__Bb `K@0c^Z:Cs a9d$yb[ғ sˡ,iH_41Tt&A 1o 6 8M蓄13:g@Z.Mp9 %ZӜ-Y!,N@:kqtIrB :ʧ\J&s@B4\ P,7z, =g\cU'_ю"E~o %l! -EOoC=wűPY:S _ȋ'#E{}9M tw'sc3ݵgB;?:ο{_nmhg﫽|wӽ?=OwyOO@k Ep-D5. 'l}̹3qoP%^Ab ͪ9 >cy&ID3ceː5MDuht}㍩CKٹT|t*>2IlM,?wzP۞ rѓg;7ǧ'H4=ILDDj)}go?`zL;.c$Y:i$4#xk2A1+ HSba6dCFB|8i e-!{xbȼ? .BkF$p?ۍ{$<IQ}v=X/R?|`H)3܈Yፆ1A=?ߨp8/y3;d-N<1<>-Dhg|^:C*b"z"AI-u)DRD]P9 Ǡ܀hY).bU7|WYz5}9 -Œ>@G_h~hڗ }&%#UT3/6h,Ziw ti>x3Pu@_Cz* zhh|Mz~}e hKz)G>VNסq*P_S撶";}[o9b~K-oKyECZ \c5eD3 V\5C# } hcДM*@C=@cHUz'@("_ Ag:t:@똤NZsV b38s>gzhghhhS0vw#l2_LCC7҉7_ Af0z84噠\ctLmVcQ[pf9%H4hNn`43s! jZl\Wۨ۩v(KwıP͵Qd+[ 쾜o1Ԣhqp,ur -=C=t ӈQ^`熆o _hhu:k=f@:M:ӽ^߂$"MmY6?_@Uɝ`c,u#b ~mevW%)ۃIx3:2вןЗ88t68|&+*G+_|F ߙ_e}nmp>5'WG~tߞ~{rӳ_> /W>]hrأ+gqtǢ~ߒ=@{A\;OjG1 >ƚFM 1us"_ ^'4(|P4f~u{}ޱ"īCk;g~S[KKbn'kYW\53|wǧDf2'ٽщ/ON@|@s4CHZxk2 9.OEP`xD GG (%VG1whgy%݋xݘg??P;⩈p9&Ҩ6dp dXzOW+/ttjZ4t(i4 h+@k/4r h;Z4mMf.7kh5@A=#U /פMIN~O)Z8sչC>"!.Q&+S6FS*elSTg`,y y8--IGsylpxL.|:{H\}W=X7?gCs1_:7Op||r&vcѧ##OʏJųYxf(}ǻ,z .]#cO{[H .6&mtRF2&SG k#q4tQEPUXuxTG]@F9*lg"^&GҦhѢ-2dW1Wpy>ߊ߻lÎAZ2Q=JcA|,i)k?^ ;׼kzJ| &8]ဧpcQ?G`D@Ӂ Q>A 3D5$K#K) cyY~@X,{ӻμ 蛀]| 5'Ǣhe#`HPEb>C3JFi*ojTh%Q)61‹j2ne4A^zQA&^hHgQ>z"=2%LD0w-v{L{C@lҠK= Yq٪QxUJSfmvI;=#iH۽"]Mn~-E%_pM1gyKV5\׳ 7W 7A9?ФV瞹:,"k/ MH]ϿZ> RAf@L,kXj VO{|H8b>Sz 3phhWWlak`?j|z =xAYQ:jUQ@}edC,S[Ѳ4@~;];Gfkr,z̳M?α9y]2y;Ļp m>\luv{n@h; |F a5_Vet-@}+n猸\ x<)k&3ϾM=Y&IabIjHKpmn?7jNUt&Q &P*I_Le ?l8l^W)*Pr63htlpfSd 302uq;'o{p8x0=duG'~׏}{jat4,lmH4OMD&(MPG[@'DIGa" #a5֪#&Bkì.l%B^2)HfH:4d;S.߬;,k~nļ1}\GQ;Hqn?E0) xg>)m^5 [EX\Qρ#c/J"LH; 1.iS*ujM"i9*܀J@2HzI/`WiFXZ,b@ )T*QļF11 W fWDH(F) =ƃ/n3psV@Y04\Y0Vw|! r.S2l:I p9=aW`؂#@"njГ@0OrW):gΚ1Q[vcy@U>Rs#vɯ?m3^8.8R-p9bcp)R(٤'pgҾl6+D3۟?Oξx??8[X]+Υl:3"CN'y*e"ĴhtʐHʕa"8"ӡ!Z4V"A}8lGM8Iь%`sx.,wl1Ww_{'M{qn̴ew"v &p~ݱ߾q̸cvo-O '@BwH 0~8AKg;SڨV5qDTbA4!WH=C@hFp-%ތ/pq/twRЉ><>'dЗt"X|)GÃH` *`@~J T /wpZLi/N^hB -ڤқT 9#,(i(N1HhcftCIփ鼘΃T}/ BġgDxz~1 /sU. r u0 wʵN)'A@3 c3hxGmTo䆇Ahe >3}F#x]Eg2wZvI킆tK Inz=Mğ^zݝ ލZ-Fv_]w53tJ~@Qx!0B\/\ F1315R5u@s: "fB\הә)Zo:@gUzL,E4d4'Y_={Fw W@zWq_y(DD'h4Qa#1T%Ӄ8 ) ~8Vm kZ\M_Z0)vsFHFv5:%Qg\Dc24>6:G hלRLxIvG\ʉà*k=* H4=_.sZkZ: "Z#u.1:CzuKQhFC@C ڜ4 ?&YL3_OOf|hxG7г;³ꚦ5~5@kZT™ڐր-ȔA= '\z30zt :J{)7 t"CgB-:@GPx8#+0bzQ>0]5xhzpOj\S1P"b_TZ:A~y[J>iIjZaFf,KeXҋnz&hJ~Ӱo|ƄFW\cO~a5^Q -޺A:umtRo#/tm<{[@kr `](vN`h}0mfG hhTeFR} .\e< -Ȼ4)1UƉNv2O@w;z}34 M!N}O_}_>r(:T {̖$ՓMoK$] firS 蜾7FGSvC᳟E}E箣؝Vͽ;8|4P<eyz_9@2}P8Gbzwα 17 ;\>b#w9%x[zW- /VϪ <0{Z1;yx9<+nB ]DwNn?;Y:𣤩3 iNPԤqAx^uPgl1].Qs$i laGpy<Q:K{aVx/d 6CFȼⷃs˽ů%!߬;r狰UӻO{ݤND'C&"袄&Qÿ#г3*I`A$ j.%5Y ݋'%I&ѧ V19"@caa9P/xz1ԇ#ּФh @B@hʨ"M*%uLgE"\+{9U>D # 1t~!o1Bꀾ2t=&c6 ܀06o0 z/LR>^=`^k/Hęngw 06I.wWɥvbS7ۡB*r:t[Uʷoa8`pGצ;R'04Su*p6OCC[k\mپc[z,=) 7Nu.~Y#㷃>[>)/X82aw.&/-P l9)EO챴50lo a;橰6Bj#:<#V"&@C=˔!6 +N!Аk!R0CMTBlLЮ; 1"1>K@CV\G~4U3n wֻAqϗ&6®wfoY6:wt&84GB-W PrHK~YY)*b~={q)Ǣ2qFa 44D*ߠ{M@ЈSA@cJpX@jE *x#A,9h3 !0k B@1}M.T]i:UHӴƋ{-/_l9e*v&eFr&E@3Pp:?ss=F4ŤĬȺ}]fIN\ػ@pLZc6פ -Ussы̓h8 m/SׂnN+<_tCZQ:73qcn:_41Mhb8GwL!y+&gwR(6O7b6U$ DP(Rz-jKz77.GzMZ^<[[zFa@#C zMut4Xϸ %}@GC=@G$5Fah&e]4;ޓ> À"_(4(L:#0#sfNjXϗ\ޙ;wdѧ.W 9 گ#{(Y/sg3s]ο7>y9ɟg*0~Wŷ?EgzW//2?~@~#Y`뾅OmwמŷιWkkkgmׁ`5~˴?嚯C:~|y?/?^񟕶]~Yx%jڕk}x\ͫbT-7ju1is+Z^ޟDr/ھF[:2-.E †ËLx {܋@U̷A"[ydh%Bh#B#/BZz_d9E!6_yL3P17[Ln6Υ;L63J[4s3-(fZ{:Ӟu;F#Y%*XP+EjiT.5Ezh:#@n?!CLc:YToz]/)55Dg*+9s'W-~|5|1WrMpS)Vo[]֌cW4sbʜMx{\Q#) (FlHGDD i  ;fp|97='#0]k٦AbRM?RM/W|t,CJ,Ic#J y1D%4#4>4( Cp( Bq(R#^pS> 4-h446t8#iΪD1V#Fc͛ߗhto2rn݄5 ~2(386 Y-g򡳻zyZVO}UsBwuk!gkK&ɔǦl-ݖF 4ژpKz ?.h@KЖA_G! zA4hr7 蘪Ԓz=+@@䚤Dt_Ќ2=hubbl%©%HH/G,`r<ϣda-Y\cֹ'utX7[vwv{v{Yo7-]nlnFw-@'+A<C+lK8'~.|+2040/!@?f4xQvf8=)ߍwl_q9<.m`M?SK)zy>O nFG|NZa'In Y.M`lhGbZ;tiS{̑;wa={k]vh/Kρ#w̟Nel#GU>T!wQ=qw.ݳιv7W6n?U{Gj~WS;l~˟}Տcg\{{9wܻ{Oܝ{w%^wCCY{*y_2mRU;o+?~7~V7Ͽ)ͽ/}X7[k8o/gy;?X_^o^x?}_~x-QZ/]f'a<&vԞډ$xuWi.z0e<0t+7Ķ%v:F9y ΧyMsYe>RlsXpIӉleB[m=15m괴6tfYOVqӌj3+Uh5UJ\%Vyʰt ;P %.MM3T;,5Ap]1[yaĪdeN3|u󻳿9KFO(j5Ng+YUDd:KJ0$Lm: oУt<h5 &2Ck@~&;Ѓ,:7hނCHB z54Tx b<ܐ7#cX24Y5QJ_MQ:JijCRQU c##iK+h-6y%!>SBz-iK2YR2JvYͮrj</uXWۛ c+]*V*4t٬+rs)r0k^z!6Stxo[C_Eeo?m7_"p @[zqcNΩ:1!Gv8{쑞4p};ֽ1}ܑҕ-z:Bo>7& zy^&>983zzfKojvл+شGYpw]u⍳p*܅ W™?sOmc{YȄP:#Jd2i)_qMz43stLJoolO|'.>q?}wo{7~;lug?7ky"[8OD@M1In[NKBF!" a tdcYtY .ng nlWԌL %)q&-fٌ2It2 @s:ބRTi͌ʪ`V!,':D6RfH7kJ%arQ1r9#h%!1pȚSfL1=7}?:( :A"bt1rlǻsD UlVVJ#Q̕[(~}Ood?T~]6PKt-~1~^?ԍRaRZTu:^m*\bc1:룳>V_XF5I=@[{<[q1+I^IHQq+'.3h3%|ۖq +ƣO|nS{q&uX]Q٫'m-?g3;bwv>no h~nBԸlg9ٙ`$ z1?sQϨE9 -M0h)p{PZGV6]g|ϕ?_,}=gfu~_Js-wAIKɱ1-$&n% !.CR0<7f%vVfz}U9\51;=CJ H7Ni--Lǚ. nVPRA ZOȍ\הzFn豶kv%Ѯ';dLFe##ӑr"\–%f As3SPl# < Z&ijeZ[ZfJndjI.7cic5g^vgMm]ƅi\?kg7?=6 DžA1\]1@[уLXQFtDOe%\+<_фw 8B5AA CjF[+|Ѓh2g"y! ho<hqG@3VhlhzճA|=v-հ'i/C{SےȒa+,?p 7!A/Hg7~k|0c0acWUs{-~ Iix9t1. zX9>;Ys%@G҈1.k&+KicXۮOvvf6VWVgVfczݩtvR{ǀ@g1@ht/޳>CP7x sO:~7*,1ȯSʫ^N=L(wϕ4166F O oLFNIvkYW d'W> 9B'Ek}Co#C'C{Ц ^K/K2nݥWUr©pꄊ(W]p]WUr5<6ؽ%;wݺ{O]4nP zz`#F8Α:G29@ gǀ.@B E[tYaHc^2VO{"iO4S^ JX x䑞t+E[K"GmzX 6?ׁ N2ᢒùIC¿W֋r>O~ %{(e%9JJ_4. *ʲ)9-ZA)M .4ÍZ֞AOznhh!@Fv1ޔK;ji/%vYؙ@/XX>76=ޙhl51wRgO:Ls_k=s{q܆Rw'~[(;GQc'Íڦ=IrL@AQ1ʭ]=1; vs٘bVm̲Yr0KSؕIPgjѺB^zaC/L KSU6 eWw=g:JTKGVnh㕳U~*߁q7ҕx('r>үƥ| TQ%Q"׾ڍzw˸W҅"~(ڋ'≳pʟ'̑ P1>@kC Վ}ڱ?}NXS"sIvNy84a\[|)f[MNeZ{?_ y"wBgiL;Qj,خ"4#7[ mMZ\#GDWPd%(,e24hD8ó;#23ەXY_2ΔEa[ʮx9u5RGjh=vl8tTdUƤj\ ]Jռ\-*5]#'gq\.R7lIuyZg.Jm_7T~`tfP$4` ϔTKThd~Cٿ>]7ظM @_Aƅb| @kƋde:^k*Цp#.y],b&RL z,lH{gfO6(kKt=D3.r98pcsf\̌:bnߌC6_MTdMV>%H4iiP(sT0C5:` JB\ a?*N:HE )*!A_Y @j9g#@?XDtG5e9 Lǥ<;D{[Vp,x3IRTȑ^e;mo=1=&[1ݿ/@Z`?p 7Q)7m@`3ÑÀF1lZS\8C?hQΉC0ZyOq@+rQRJ i %e9fHjYRM9VcU\MVzRSZe<3zzny*щ%&lŦV .kkamMHD Q("fV*$WRX%vҾNJۙvӚߝ^ڝ[ښ_ܜ[؜{13ٝln5fk;ѱ?t]OգXH5ʱlKI| r׼~wt.ܑ"wMdnPM2t6 ޅoqI޸ҳ7ܱW i=@6&4z7znƟol1d)6la@~G UvhazJ#@_LAϙ-$bz]`?sjyg<'P~Op 0Z޴+[؎#gORx#w(\ W<֡;N|2NȸuQDРg{ؑ^ .41νhܧ'1(gؕ=vgjߝwлI>7uKӇa0}H 9#&{"PhdhcC:V1hSҠ? (=d|Gt»pF8FF8L6f#p$ڈ#Gp2 q |zdJ:R$0 F0;HU%"a}>NU)@g襖!e:y0{kM?KrK۸E&Fc3J[P;;Դp h*6Cf!3{AQ%2Zal Z|z-FYk욘V%saM.K Im+{riO-*V7x)C3$:lw=L [x5.5xɤ39xFYoymf >Gqlh34Jc ΂ü1@$~3/>^?#1˙$IFQh.*p syp~qܵEgVaժ^,Ī3:M,n¯ ұA@,@cC պ]5u)Tڕ=H5te8^:^:^؛^ؙƀm볻]}z ηs 8LԏcS t>3r^sr/ȸtCo`&ٻ` =kK!:'ʝ|Nv_Akгh'􌗥W󻆭dÄr?ssj+w½.tƭt|zOAh;;s04݆D^ :c=HQT lP*,RD! lVHh,e3X1PD Q 24424qVh/띞b(B%Ơw; }.zF"@@Ce.JsirI7pB':A?ȞDQ+ ^%VîI <)9-FSh93 G' 6:&c&lI1چ=!@lmBŒCG~SѶƠSxw ( zzpJe e4د׳3ֳhNRPcPu{Ӹ^Xꌛa=dEW@ h&&-C#@cCБz4 . I}~2ͽqgxf`f=b;ѝlo+;^W(a@&8 h_{Wb#qy'U|Psse#}U=mFě9nZ~^LR I64^viîlc{ġ#uL2`h'vo;wޡk~e/^ 6݉=wlggz{fgjz[28G`4<LP7 3ڕrm0'MRA uLC >}:sf!}.%.w-1#.e7!J@Yh!4GVH̸1.-"h?;'9!␡ĀeƲU2 iΐPSyS  \ɄMH Sr l͗) uQG0e $WLp-%p*[=ˌzPEy"~3d8& V܁'X`h{t@ TUf+hdbdw^U%{ZK3Ӽ4+tad>ߞLf-[M:q2RrI@zƀFV<:RʢIP9Cb]imBG^#w=hjIut!@ytC.<1g7 ~hGJ2K@%W1qP0@Ahl @'!&ZJ2tj(JC!4\&f *Ƹ<Y>P1҃}zxBg=L;~l%]\]a(抨qu4U݂$OT<&޴hG:dc@kv4q@m)"T1oj88+QON?K? }994!F8zlNKQ3ҳ[~7c@[tF@?g^E b77e+**_:%:i뱞)tE7-@@w>9h݋fb t C3$9>Q%UQгDt QFcC#Fb~\pzFy!=i7D\dWdN뙋5h$nx-yDo*x?-ao6t\Pw%L{+ҳ3@1e.٤5v*`hr&F`h2t0<'@b'%d";dlTiu ly= +!pZ 8@s cb^ /\!.&e[PC;Ǚ"] Z0T!jhpïf3dVOp4^xf+5BU)[rrlj nŒa O(LQH@F,:2"fd*B#Xr.@{M:t DР@\ N/Ob\'/ұ:cCuE|uoa!L/ aHb Pΐ.jhŽgQ(4YF:0hƴG]ɮ 7$hN>g~AA "7qB U ! Bi2 $7ȁ@t"NdJ!fPVYC¨>X~zDϚ;z&Р礓H:JLĝ,sr1'ΰdE9E)+NYu3s 1g$e$z'.xQfHG?L$=T~h@O'c&ՑM>F} @5Qt}f1ЂD4NF5k Nn@YʡQ@˒.Kfc>] B5.YpuIAg JjyXxйrq\lg=ƻ +xy=QbLS NmBLz b3lfmp~K(l -7{b jGb$֡LȜ?mW˻ŭFgqz4mdwm}5@mPA.>@C w{ȽgQKț~ @a=[˩7{0 7~ۏZ~Lշo_=On'ggsz w O㾟S!hCr1.74r31>@?gg׈ -a@'CU*ҏ@@/4z6J[ s~01PCVdI$pP:p#vE:C9qG$-G='XO785== mem6 (жpSSI[|ycx^"re57?7qf4Γ<.ߋB<tF2b4 ͣx{l2vQ!dhYODT]5PjST[4p󻁍==sYtd2!ZzF1e&J+BCc LnBtzN0͢vnDwDk|Ee@'bHZ'ٓ W]ڂ5ЇhylgjLIhB\XL0%.ߒ-:T w#gYfDgipX3R֛/,rZuFt޲%6Q}@ya7{Gycv='='[c V6wtE%Cغ[p/BX}hz cAR uܰ֞4Hƻ'7,1%\ -jL SѻrEnN-š2[r3ì *T9xΚ"[VL9S 3ɚDſumlixLUPPe*Tu+" p3O\  7\G,@#C{ulZ6H]IfN lK.+qQ7l]E@u uƯqJi?]rslK-dBG%]@Pse|+$X] "U4( rpF8*_"^p3bsXC%#XлG8F%(= /AрF'e AA -C#:p9RЃr\B#Y{<ڢn#N{I#*"N2p Zu!URws'XO2Hl)-e|6tc/4`.ph#JCO4sy21d|b*|*Im%.c1xz{]ǀOE(@# =^f57h.Nў*FbDG8%K6?)g)ZEC Nd D=1V#tFc ljBʼp-1W1WIuuЖޢӻ岻\n{Bq/Z@Gq)FH:TNqy>.5Nˇ;Ngab6engq@'sjtI@_s\kzw,]p:CNnd"$A `$﮽rɒ]%jeٻ=As'ub8wW@ύ~o MFz|`cӉ3_}:z9x:mO)ݸ =n .v <ͥR{^p L.)c/T~/&3YHGrQ&z),[#CHD( x͸rHpű7CLnPv˸bkCӘ=D[hZ[@3(ehyVY_:)1^tLk(=]i9UWYU髠jدēv)7&Ԗ)7 8V6Yz神 u%#mYj*RK1*UY#mlZClkNFq C3s11l;В GDzl֛Vy!U, _V拎 f }ذgqw?黿zvدUokBOZVjfӶZtQFFB@7^l 9/ *jAtCF@ϡw͈bTC@NP:Hx24#5y!\d"ޙ,(Am2`w->@C41/V’a/bXU+'K'k){,2 <}%h%T](yK YؘW=ptVr$ePɭ/t cn6vq3S7c 41 #-'-9IYMY` Ӛ!;ގ!5=BHŽ`hgmKm%\&nJ-KnrShbC&:e>+8 @6$ MIh<+l[f:ĴiIDAT9As zn9LMܡc]x&wҽcuxt]mKfhVLe3|Awwvky|l7l^}Ԫ>i;׿z>WW*Zޞ4{im5k&|fs Ў!гU+j.ET/p@G%rDMp|Д85gQZ :Yxh=}9bnƃ~%. !g' ɯ\z/˓y^3@|3oc?;;ʞxr="@7`o1OϤ?TO?׌ڽH zm'5耺v >[k+إ8RLݡ{T\U$|F%QTnނ` @{`U1 )=?@gwqx=1-ƶ_߂O!e7É ̽hs =44?;r1@%$h9ї9;nƢʍSд ENyA"] ωq:6pNjֱD48ɳҗvte*N(!pWnS&5uoksvcW$hM_<ĵD tHcQ=S@t@ӝn8֋zQ lr[jq,ew\mXzԮVY87k5ni/ˍre@oU-\< hGbgzZm7#-d/4Hwc^h~5ȯ堰b?$ώ ]s#\=J4[e 0I@lQd"$&'P U ZC=;YLyN g9cy^atyB̓U1Bʞ*%/3{[P03p$>Hb6,hA=I $Yqʲg(8V;'_" ̤]sz7$ڄÇCOZf57UլfU5ʪYҬnU8T&g#kFf&lJGT[ʇZHځjho<:ۏF9y}dV?mznÅͣٵt\]|X^|\\|_xAC?OξϾ@/ 7hm@LㄮIvVO#h ڳn2h,P 5h07_|Q@M͞d}yyA3y=g>өċ̇?]~V&);<3šC;763ˁ&G`^ {ϟ!sw.}̷7Tp_> 8wTGE%<¹~(}/ %]=s؂l'"eл$CG!=(G a\끀 yВ hз-.ybX|D;G1(R.GըBKiiYqC@JhYUr;!>JM13IBCw-g*,뀊( 9.R[Ŧ5T~e-0|{ uYE klK`<k #2I* .A-0tc 6Tje;Kfffյ\fne_??x!nGvjmլ/, w*|e5ߘO7d۶U >M4m3>Xղ:%ږP7/k1l+ƶπ7Oz-0ϛ!< tCL7 =h;.YȦЌЮ9$%/0#VM!z,xM(sC@k,d' *C79 +N;\K#|)́!GG^@ːstPIdPMP2,4͘iz$|(KSxHpBڹf#+_F29>}9ɐ@Ctmev =l\ϔ_#D3 Y(UZV ɳS՚Vgdnsu0@vq !&Uɬɖ@fE5*Y5 |6,-n$+Q@{gA|; ybKy$2ODH⒍ 4L/8%2fv^7+VAsp yM+@g={Cnj={LVsX~>]p-܇@( :Ёz>r@:PkMH@wzy֍sow_ZoS~2X V"wʻ)v-EJ"t%Ρe9?E΃hΟ> ?22Mg?z_/w>C6M<[LLii _nIi攲4=zk <9۠UA&YpGM(Dv-3`s ¾~(ʕCrDGÍu"h^$s7 'BN!}+뛔tHc+dl퐵J0.!CEw$R܏z3 g` !{_JߓRw!1'$D|>yD 2n;E7Ymn0 Zݠ,E.] +rTZEF\@@ s8'x&;ENvWu:zh7U*Bh W&65-:68ca"=Xc ۡAmC,|2mn3Pns|p@S DM2>l\C`'%;nXLy#_]~[ofڵ-mA^9__۵JfQ^g3vUOkVjvr x5ZôkFJjyo!ښP7xMi.Y-"=v8HB6u B=K!$@N@gQ5,4#9$D3dlÍ ox+lg wySA N+e}p$rɵC>Pjk# jBZ3 _|fm}3|v pao'ŧ=Rod9;`h z~GۧhhcΨfԻ3*Y4A?ޞVnM7/IٙVWw*;~}-J`$N |B9kB nhhEs I]uaUw/KߎnE7#]zފ[am3ޠ.+?mudCw= }?RpH}A !u'$K܂a cnYl0 :C1y5*;dd6$-SRHZ1qa- s LCr/!wSr/ I-Kku2,up-*z>mUh9iur-mCYhB8A3=ćۤƶcӊ2:Z"Bj&'<zv] YiR ;ѪZZH6hheD-j|}.(aZnź.٪XVgC8m<CayB_@dy 7Wn@83C/7 zƙ ? 6b,Φ;E7Q4UJ{ sc@b&w1tѡ$ kdY#ǚyR!s=9P T2-ὀ͓0rN{b/ra= bG+ʅ%p LLKQB h+(e3փJ4bb_+wj$XRD!s9`p֤g,9 ѠgC%e7:Oyz> $ iHߟ ŝ|>;ʟR&=MJxS>AV=mQD=; bnr?$_hδyc& =/thb,Goy9Ɋ:4*z@f|i @ܖT[ p6@ hr<|q/I!$&z&{}<ct4*/7y6xnqzZ}\}V_yVyzz5G=RE@C|6i n=E+#P<\z49viTOޮ>xr69ʀ?N>bO3?jx}dzgz<oh^zBbmoSPb;[ eBT߇\BX:Xܧn qW] w"6t (l|+@|7'WfPPnBF' {^,wv .Vpyo%nMvt3F۴Šr^b2_JHg2rHD=ݲgaN@t?+usJIjh4${֖I@q 1x3O=&x} &SgҐ΃&uM^%bl<א;-yVkMڏ7r[?}9gOڳ6~\֪ʋv>1VY)o++\$Ysś @W +ubQ+#q~C5іź04^[G=_h#z6!;8!y]DXۄPVqr9t h'T6_hQ@P*44Y0)6Դ-9Ɵ.{]"vwh$hgtJ@[7hv+^.[I-,kF#JgVoF{&S4{6h#^6_椘 @g#py,>O/H-L,Ͽ4^hWhVA'RTSiэwi~b69UHp ߇J s҇ ?J#7O&=s81 .4 ײe=! Mg?Ϥ@o})ȯe/+w|{!>ɸ5~94y-dmSa4 $򟽍zйK='oSеܗk?e>u/fqGO{%sqR'옭@G\ P?RSh k?K^T_uvwox]^{ZX{>+@/,L-L. =JͿV(o[*N;{uޱ34<#7;t|*G*f s cYE4:_}SO_d<|t{w}3=w0) ]44לA4z3iod8ȀČT^_́w) µt2 j7FP!G͘ ŕx},JZՐJ)k}#`E%pJP],s PfJߊ-y5ǚqHܦ-FtPLC7G!e=s/F4_+GzMs}9N,w5q7.wS`hU{Y1)нO%LPYQŎ&$tS:Oj\Cbf(siI@_2@Lt/圆d} ]jJ*bM+t|y3}ج+Oj~VޯTˇq z~o//gg˳KBi=_Yj'Yk$DmmϸЍx6kYv]S 8xf\_hBFN3 zr@3@OhNzzLڰh $g8fu44 tvf+FC4{r:\v9)JH %BRO%G:%kgE4ҥ) g>+K:x #A4 /ro'Uwt_DzOh/Vx5Q@'3֘3Ac:hP/dAGQFLkbЗp O+``.ZH%h6hpf54C'C[ɦx5QJ3=LOuplK%{OJ2ȮZ (z$|G:ڄoco 7 h9S]2@{dy\:13S~Vc c~`hAϏ z~L R߇kg!=DUωσGҧ@铿08t7_}cKɞT|*ae?]/Sgkٟ2_g_!_/~xӞ~吒 @eyp]I_27{pĞ;]LRv0uۏ{6Z6~&=Y[>6:}+Q&Y(y-:ͫAyy,JBCJY jAm2nP`6dPҤ P%vw3RP1-6|7hm#Qu-#j͞9CDBC=C4?K}Fe!qzQ.u,i0N{N.M,͐NTmHPGۆ2)6,n 5S\Uch\fGMbtiS@4/6Ev\ej^TBSdzדٍdbR;{< jJnpX-W+o^>92?j+Y'xmxopstӪԭR(UJYjNfZJ㒭5YD@|m7i?qs703 ?wfǺ`&om43,07+MmEF8d!,ڝfL VOpnir 흇βx#κRL,GI16Anoh\܍2Ĝ ##RϘq[MLeZB4LQgE4~,ڟX0-`"(Bzg"l抮1s5 *gŢCg7t BC_ h/ g~>+7>C;b@7~ZQ@7x v%GڎB@Ic/ =@$2kC@;o ZϭMo-uo Eйc[8 w=h&f*\!zv},8n_;}_:kS)`]lͦƝИc_95Oʶc%*hl~'wy L i8SAgq»$c| ߬r.=ŅnUJYz7!ƒ1o@am[T]'z ܰAldT P(?VG(Q#t,Ċ],P!- L)҉-KkŵVJmC6!kДں֥N93AHVZmeTѰ5]Ъy\PKyYIkbB[̒zAwG8T^mig44 2e;1@;"{/C8Sa!DX!~DHLxlQzV4J=U+_az/t$r$97Y(z@'@_f|I']h/N|>>͠__u?GOnA z@rM:պ:ġhidzmf] wp3XL"sAVs:؆ owntv Z!ٹ-V~HAϏ=~GTG@Ozh{oޫʛꍓYo缳uP} Tρ %P/+}6S2]|E 1@O@*|V8Vx aSOh'\S~?ޮ}ϾM^3^LOgpݑO}n5v|8M+wםI1ЎGL}+ ]'헶2:n^{l\]ĝt (psI$Pzz zq+!:p"ÐguJYUJ_ kI똹6A#Z~<1i9*BKܤAz S= }{1v4vĖ$Chp4@+-(!72  DφIɭ̫͂* 7UR5lU[UZIAV2RՒRe@X CyбX3FXe M'86Du!_OnӧK߿yyy\w Fv~`r_[GvV!w#YLzJ+Vj٬+ArwU7*,^|hr}@{%?`戞h44zr LJx }&  }h dC=b@cI1PoE?9d{uП h!}1@|'sжЍZ)ursJܜ>z !@_} nkf@ oLF61w\ dNF-&ˤ,=z=]6skmYxعճh\%nhG 4: pe`h~ 독G215z1{uWܫ}y~zWxeo(ȯ̮@'W@"~/V(oqD=gh;u aС'bO`s5X)Poӓ!+~V _M>O58z]'ů?a_1?{:|3eIz|X''TSBh?W:y/"h,w3Sg?͇Ѵ~0 n&gӆ k&I?ރIγ~+"zIƝ8ۼV,:W? ,(6ҍB|{^PVjSPZ" _DR Q"pMyBЋ7v.C`` &ȑ0 -|%'%rb_y?l>c>\?= EKl/,/@Ŷ( _ ԥ!6d"-97S X-6>xq7-0`77`,OwH :1 Ӏ(mal( k#.C,V"y:?(xLCHg'>tN;hR$H\ƵhB@khw AI&Y@[u7i )$|Hr?$5.bB)bs-\ϹD4ŧ(4cdxNnh5ArH*iaaE|94at2Kp ; A,s^%ޠgTqs @|ވg|Ah\?^$@^@&i?=3@;;7p:s"/#:|RX/0 uT*DKc̑X$$b")ѐMo8hyS'^"؀_Ѩ]Vyܪ2ctv=-ɮ+->h,o /FF٥3^:ܜ-OH(rl[#%I}zޏDK(Zy>VGOb]}FW)S{Ϲ  -S !B/+wc9:|R|_P>o}nU7Niy㴸.~Y=I$āo@ҩi ;iD"N={zCwh`]~?1P}!} ~t;Z6]i @?OBS/9Si<ٿ~+| >r)4e>1fC3m @;M'5~CKjF ffx'ᚼ M~eFɛ>y/]xnQ.%n͠sɣ&l}pz)=Fx݇E4{r%'l'KCFG9cA=1EU)DnseIY|PB:!Cu cTOH4ָC:j+6yΪ7\^4VSdn3s[v^M‚^(\(8l](bE⪐xq6J ϛ-I>kJ^_+>b_gZZK x\jZ.k^e(7j7YZYlYjevIjVZBŚ%64.)6MANFہOD1siClGtznO=/]=/o~q/~t'@LjB~mR-@W)ك nThKf゚s7tsD0 I0 H"0-kYʲk][~9q60Iv[]͞g?8s\q $h8FgdY:'@{,hm=B#9%Վj R: &H8B G dts+ьxuPs]vx:B@8,J} 7n,&Xi2ɏgnᰕ Y逅nSȩu~kߦ l:ڦcz֮@i]jH\F#3fL!q=߼QEϛtܥ4,;zDe@3{CCjO߸]>aOA:ч < V'@̗ڬ lE QdSК,81к^ېeZ9 sh|5t RChETfh:2. t6f˱B=ʓ-.Xm mOomO=.UnqҭLn:.Ʋ Z.SYʥr4$3lޜ߃=@ۜ,$+o)z% /j L S!Q +tfMMEw=?RY++%y1TX*es,-H'ye#~"? F1YFp;Y䃂dZ̳@+1V# h'lğg|ŰԳ'Z4C=>n wMU29%S2هoHHZ@ h 7;ji$Lw:Ӻ^[4縘PJ9)Ei;2؍vKdQE~@=[@4QA30>1]ưCbZuAд]@V1 3}Mb=@бR@?f9ވ:S 4( zhZ+fus*@+Ojzn o̅  dгʺ݇S=+F=@@+ ;܁d~ M7+C˳]yfGw]nj75M%fGnA-Co;d+6sia73;iGtIKɧХu݀zS]DVOW̳fZOᣇ.45yxx^[Tڏ ~ CpBMSfQ._e(Ϲk`|pW)dArL2h}Jy(G5(%/3x*`97,ETq0&D;b~gbooOw~g;/hg|qpfSXLlNb%'Y6ڛ@;8 `s4ۜy f|A6w.z=%s] {˴ a0.cx<~O}7/`eUzY r)Tx>GRy=-8}sO fU(@SYM6*k@9/Թ# R%AσV5 DO4%̩ [ng eݎ5  OZY".˫P/Pe*\ۀ:F7ف 0tj|W9sxsO`Nrb;>CnEF/v`pۏ\} m)탞ۀ6.t6tw:j@LǔNFUq=xk.sgzb)>;Y=!=`)ûʍa+ـ6'kT5NÂPVp6pv<&whv5' @h/+}倯s9Jh@X_h_P+l)LxnsWg%*Sd'D!$AAYZ,D2>.)QBtp6Fr}^gw.]%~Mָק5.R솟az6lub6dw!8λȍbmOv4Zt/;]Ž6,G5cx Gjjn3teqЙ:[|4d @gK0hA37>n=@gڡcIL7&1^֢qn;ͺzyn1Z~9aOhrYYcW^@^1_uG6ݴ͌o5 鬤t:[~!yN!>;( IVq @+_6W=%oiW^P ^aՍPm#T70oLqӇ0ws{̓~zf/9܍v;݀ a&w9MCLyE6Ρ+ Eznyr3HӮWA8Jx@77چ&u ]dG@dgÚ0$uu7^xk֝Sz+h/ A_ /@(Gx7 Y:Waā(?&≵mӝ?75?l&J:olRQ'0k(b&CH@|B#zݢ-Y1nW-P*@1ʋc2H|KK͉/j빑rQ^rf1?+JKyq)/=/eskwM᫿]~Z+ތ'ɡh%ICLKQbjT=YJ@t6MgT6̱,ȅ}7 Mx> hg؂O6#yw=_4 vts@Hm-l#Z1K)Ν:N}nf {@ m ʹ#1^Co^q@}~iKŘYNX*CCY>uDV6F6˽ bͤTP(:/%K"_DtC'Rf_ cںݬ2+T:R3Zt$I"L(Q( bn7DR3fȝc1*3Jef) )tFgsA~/[G#[=۹GN~SԳd Mnڕ_uV.@hfnN3af =f{ɽ^||76C(׍p [؁VF8 Y%Ί70D}֋tP0ZPV #DGs>9!ӻW_OnP{ht)JVt/9:ZN2ymº."n@f?eO>.|4ՈAySZz ^uHg49*wZv;^vu݀VR YhhO ό h_"#8p7*pTAf&[3Qn:#eR糝?;Grٝ!h,[_l<)/湻Bj&HC1d$Z(1 !F{e7n\#][ܼ#X=+Y? `1p,_$i>!p῿ś}r t~ܳZx}s7+Y'd! ,Wa-aYI"VRBA8| +Q  cZy_ӻUĠc :}u{@ DN΄vf"f^ٲ&< Dz*rK*V= MN+h~olf'4Tܸ:@q)2YK#]5=/tىtF=; gm2YM@ˊ@Ёګ@Л&: M;6zMoSsɹ~~rKL'^tTemZhqag[>VZlҹ S}:@sWIprOn>,H8)GN8euzOWp1^1H&諻W{.Cf/9 о9SÍVx2]sZu dzF@C>ОarFX3oQgG/T7us;πgt7OKP竛} u @{<lB tBLCơ׷=$7ĭayk@^O=_KyOrGpq0/Y?ynlwxOt@>T&=H̊{{v;ՕT.OsbNx,R_nMow_}DpUF(RŐ$E z<esTF@<h/3J Kѐ_ Glf3:L%SkJC㬎n@wYhk4x^o[uWr W@{/[zV'X`'&i'C"d9BvA3s`#w4i 2GF֡g0$q#Zyz:FjCcn1k_ кw_ ЊUz{Y]/Ncu@ltQINXV&D@_H ]Qz8x83ʌAOI '7ZuR@@<LelWlk*`⪧y/|m*[};9wMb(>ۏ$n'ngG(64;CeCفv@QMCwc};h; -ϾRuC:_^p𧻓;@##ЛVdW̳"=udc5C_S7M@m+7g>J%m|xpNpNa%]݀g4k2]S=@o[Hh"1tQt8P +Tg\pN 7#rM[6P_.MF >$nx͝yPggX'|:96()r'<۝q3n/y,9. xg`]93Q9[c/󒼘=sMC?SZE;|G&-.3gk _%eÒ @CQ iܫ* ,cyFJ84n?W@{<6wJr@[{Sm MH ܄ ];]@Z|0 I5>ՑX.ҿEйdg 1,5s^ڔ_Dj`h/*\uU FqfÑ1kl@[fvnGѳS@=;%gKvie e@ 5vYj<>u?oQb=~SoB0ûЎhr6Km)ZJGMC_6iD'uh\S7{";n'I/HO?3 'kC+fM}] Ob3~<&xJ*^]v%hO)Ѕ Pj:ʧYl"TJŋ|WNg+C݉>"o gFåx{}ݿ6(.EvV)I4 Tәp&!AF_ =|B/}B/jd0#Dždj^H=H?\}ϯUK\ 7,;f/yogSH4]g2X9,))A!EE 7QR-*"|Db˳p" E* "O=yF/Z5@+Vdu$h#"MJ},CV"!tnwSQ&-x+49ԡeY=ܡgx5rvCj Y!oKAhhq@v ^׬}rԬSF&]¤-3rw$@@˨gM4C*@WU zVb#VEz2@} 4vV]Uw+C/POCC=C.9MO(6{=J'fSGɣQl7[eG0.:0}MCwZ>@7 ]86NLySS @G[kjN.w+ WZvz==w}h` =zCS^!-]ʝb5ht tֹjL{k.@U̪U".E JA?T ˡP :CeeF.Fpw(&Ow$yct_7_߮LnPnk83w쏗'|W x|{Dك4FRۃWtnk[0b F(fi1G-nu,[дG|37s8d٩[>o6,4  J7<~fwS7k]tQSo/Ck&q KS]QM@; dv7MsWfkh ]FkXT(Z *x79V 1' I:xw]cxM7P"$|Vc!MS5pAj.A;w${nGܠg[|LT 9.`hU Tܥv:nb됯m wB}qd8>{?kt͞nǧ ;.; Q  WZ>Vڜй3, 3 Bк,+Hǐ.{c|_pu+7WGޒ o i= 3]f'~#7[{ǽ,pyez! zȘ,zH7rfj=}jkeqG[CsJ$гr7=k )s&s`6<y j=) BYhax; [r@x9,l7V=K}4˽_?w7ƪK?%'X?ŸriNtHLŨp[:Al>nD3tKȬ~{_6z=Rć~(Oi(l6xO`s yn"ō$X%6["%(Lse:SfJDFz\dzuHU ,c8xOSKIno,ɚ<9`MޒS6?dy~vRq|7'4Ϡ ߇6ZyjzQ$-@;Fg^$v[:kuȭ$% va6iWt3fK@' =C^{kym@bV (̎>4ô]cY{(b q7-TҸ'z׎Q1Ϊ#"?KbH%nљ =SA PSة:zfߤ A!d1FʢX/F+ٙ&yongCMu330Zv~苴z Њ;K Iuа ǰ.4wGbz|K^^m*pB;~G.Թzg5wXkBy~W ,ǂj(,(tb`APL&LF'kL_%TɤXHLN6d? !&5Jr S597v3cTf-&07fBL,[" _,:=r3>pxSC%=qJԠC=!ڤ5ȮJyǖ}ar/W]35.#eׇmA.d6 !/u/L& 5dAaVr];hcwMz%M%ԁT$bK݀"@o7BbPf==}? uW VU_m@!~Ag4fU}F@0VV&P]474G> wSvAaxޛOj|]}t8Ň.@w>@[5M"e_bW:,}лqb4>?AٓqlxD@;n 94x8 ^ h{ih]85rʩ)ڔ{cʾ6ʯ A:Kgs=I3 {:roo%7;Ч&(c<#]E@/@?%FC#;k*cbh|LP9}Ȅ3m=7@td@qj{O>$@쬙(y@;vUu#QϐgKAO1.ОG}/dA)9JA P)aV򩣩|?l٭>a!Ͻ˃_ R@KJ%+|sw{Ks?\/[dz/K-)3J'#H</F|ϲ,#| R_\싰7L&>ZϷ펔W*J5TG|̭w<_o,~sk|AJ&SxJ}QJE +iL}M؟q3Wd h,R!>X2%mN73!PKϞ?A76 !{P3?jM&H}ч jmJWܬ hx?[t~otQBUCw]Η@7|hq ڑ_w^qz6PyWFC{Aڦo'п 첣M9гљqt0e'v}j <|B@]v!tЕKF8-,tw3] ɢV褷:0M!]WһoGĿ\'S{Ϡg}z6{"I+f]~'hx=lwPσs2|6bVl h@J.@[e-@WQw=BbS=y֓rQrq~VqɥKןjXn_X^/jZ[S˥Գb|^a on fgdOns/{a~wjdQn 8Y1I^\n lkI^0]6p ?5w:rS.@3s468 F{hϚIfg,8΁s͑l ZmZ@;m -hc:!i2݁Ca{ͯ 9p_;]tVru7kn=htl'_D%uep~:1$qM?#yM<}!@BE}Ig҂Szq)@79vn yHVtW1Om[߆|߮Yv$2w{?f"3ѩqdg&z; GCGбHhg}6 iv;gЧ`!Hg:mG`h鍺n1w ]V'ы Q86'̾.@/D+#=g=%dMfG !k=@f瀉<Պ=wCֳЮ:KvTlτ$)Zz(omZNTPȄ$V@X?&LSx6xvZjJ%\N@觹\yͤ'hk.Rrk,޶8dz$'2XII%6Qdy,SP*LQ>.}.ڦ:G,Z\% 4蹡w\F74`w8 x/ =_hbhmr 5q;;H~Izo ^z΍h"R ]eot*dңWQ2G hxwBݟ &~2h*-c ͺmC#DNhsvHgW|,F}ٸOVEeVDDn$%Ng[B-l?>faRO+J%\?/Ky(RKRY%TL>/7Éd?l-z߭ӛ#ܓXԽl^.M-Hbٜ(xco>ڛ,SO '􂐺ǧ)0zV䷇J^<,=%7STz$g+HRYi(&dj4ͤdKT"r4^ DMeHp*L%h M2!^7rqN< 9owmQ VgI#&WM9A{4zm-~ׄnj=ܩg [`D v4؛ٔڋTX/Dl)HfV&~S57ko._vql -g,`"յ@:Yaih.~ƞpۗW_Z; -fMm1kL@k鉨C{R:݌X@" 5t{ J=# Mdɍ:zfgP@M ( ] ?s6nT@]Ce\ܽzv7],J"Ƨ Ў→t6]-Զ=oc5лd G3v-;{|ΜSgSvℙ<'#j; FGcБo3x8p Ш @W.]xsh _r$4){ @ sP tW~=2VO@@wbR[FWQ M>x IDAT ^ŗn]*C)} io ^f+Ԧs.l-@ڜgov v.`3κEr _5uTa hȪډv nW.؅B3^JQK$$|:$paDJl?/әL˄'+?y{ov& 3RR \ʬU YdS+zlC3<ƣ;X?{kh9_kB ث>+>^~wot|K>#9@ӸƖ+ߟ1~OLgx"=BPĺ2q$&ŹTj<M'SDW"r$^D='rLRB8Å2`:OGqxCtS)R?(?Ҵl@;yHR NQ$CqJha6G4zVZY@[*3Њrڔ1h n{ h"]nlZ[3槕TfVҬ]h@` hr-=c7l ڂf]Fw@k{@ OBg3zƹgJJ #xٗa:do -YvېyJ`hdt>Sg;ַٷ7kf5;yLѓ'tÇ b!3pm[*'h30|b*$4IDVhO7{{zotoONFz~^3H.N݈oވD_Ftu=Ȋe2q9EZ9y]zAG}@k@뱫 ֳ?Ԗr@I؂2(و7r#4FOw7X6lX<&v]}&gu+z/>[dՙM3.09f'=+c Yr8s.gʓ딳! /$+F}:BX,02+pȁD391Ql?|e} Vϊr9N gԳ&VʩWfnx|OKY鋯pͭΠ w O^~OX,$ r{ RL~gfU\l.J%Xj0+W)Wb*+4@1n"H'Ӊd|0tI3H ?qOyŀG»]lYEd3QX &Q+@=JCz Y=si;ah ł udoXKWbIwZ6 m6D͆7fClHA/;ڴ\N bL빮Oto/^@w)Z<rw*@O zE@wm9_N=/Li@ A-nj(nCҎ$n]u+&{=Y;j;;f-= MOg8t;#mC@ ]}hge#KL2UMScP"L{IhV˽"^o濁zrnd^ZM|| 3NOl' [ŗU^#'rk$FR?WxJRǞo nCw!Jlq6|%M m4@g̵=9l؟2AQH-$A !DΩ, EcĜ-'Wų?|텿Yy=WJE=RI,KHy9^/*z%]玆sgcų·g`jOV_=Σzt:]},GJ0ND\t-0D'pI~$1: 7p3 w29:|) 4Y%noX¦.m;;XeQvv."{X><ހóP7詷z55yNMB㧡1?rC_ CWZ1~lXj-C*gGk m]bgp Qoj7pY^U"/z#/[x&z @k| h]VWٰ:XGͪ5ѡku3 3kG: sй-*V  E>$Ja1eZ\#t*v?mx;}3s/ZK‹9f{gn<JƒxܤUcR50dDr$H$Dr2Fbh/"iʈTsge^dϑ:.g,Ϩbv]x k}zw= ;bR 薞@ϽsxC{Ԇt^s]&)YIۗ5겱Jn+뱲>k[#x%@_2J]|'utD ho&O oF9pC!5<$O g+Nn49K*Xvp=hN142tL!sn1_@_s IW^WN)S&~`S=љY~9h~Z@-Es[v9O4ZҶh{e^&{J>0v }oS7Гɷjux:ςGG}w?w4tV?@ }PĮ>VR@俹BvbD{Oz'߸} ^XL1.B":9ջtͽht75CL+Z3L?Z _@5 ˗fp@9fA]⭈4 lXSBk,?"ɡH|2-pwR1~2S_<,Ͼ۷?!$걗zz\-%rjZ-—zMlCш|4=Mk}4K7lgw~r{wRz]* r@g}eA`b)6Dx| h0*P.ln$PLgdb2ņ#<->*P9̡CEJzsqO>Q\Un{8fu%x3` = um~nmC7sU5z&nh1vFG34zA(שT)X?|絊ˑ vfI9#v>}3sڟЙ!nfH"ovaF=Qa98_"{IQ34>gֳC@@Z^WI+VjRYM)`'JIh1d4+gY=r8Rr@R܌%r툛߳+4v]+x_ N=L_qۼk!,йMN<`h} 1yG/c+[wPzmju7\JI,Chh _x- q)t NC#>zohP Х,W_B@sW@JƫXW+b-UjKtVfr|^ t\.)LOLS{yݹ+GS`eVW=)ʷ&ۓ;nft_}8]}8S}8[}8Wן,4Z/'ڏ{SUܿRnJ7)Å{ąjzSNA!7B/-N$NJf `qNiY9,daC6eiPĹ8{F=Wr&*r*BVml'h3~g\PD{t͓}3a#Sg[x><~Ϟ cz!  MhMzhh4Q7GXc&@(SqD hBFt|{=ۦCh hd]׭'Рg:1(={zwܭ۞oo?q t&&QϏcxdO3ZxYx97x\X<׶l5/_p37z~^x?cg  Na>rm'tD[^9,λ[$o X! յ{x笾sU9jo8TEjp //qw]GոdL?.oۄ[v6Zy2Qo٠M~]WIߏӍхlo אv޸FSiE{R=yfKvƖ8=89?b1ۄЈax;]:гG7;+N3⎭c+.~-A.ne|p]rGu4n'ٿa L̻0^sn9}%+zPC<(GWK^"_ AX . {9 @f@Q8%|:=Zr;n@‰\7*|l֭% J o9rJc{t6z~>,Ioa `hHZt^tL11B nhh )tJO -2n1),K8BײzFYO+ka8J<3I8h6ݍb:ZCƋQ0fldͳ` 5Y]7 h~t3ojn䆧yպnN w$nmr;cS~NL?<_%Vw'>ďmַ-~u_yE/9h7":vc:zv$.ltCOOMƣl7=@;@K\DȢ&@{4ΰzI]43elH!zf@3%tyg}(@^hb fv( GQx )9H9mB,6!0b\J)V`hQY0+uNea EDM<הoVޜ+ѥ]~lpxꈷ';]%=Y)oOTnOT+7[园ލndJ~e;=څk=7>\l_ds'da Χ 3)a 2dV^Ay)VdyE B?/tB'#g<{.&%X2N"2{'¡n(4`&},:9š?{ypSfcO&t4uVJ^ yۯB i BXnZ#4-OL lg㱴1_Ę:YǧqC0R>'74='®xA2w$} юftz۞#}򍡞BFT>s=C[l`-wpf.':GΛb>QLo4S1ymhLIJ R2NSC+k$ / UxCJJm+.8-· f'ͤ3] 52AF=}O7yiOjkӻ]?Ǧ!`K~i;!!>qCl-ïnC z+[| ^q/‹yh@gQ/Sq4¡3Z7 "޶UmgT_'=<{4#o@9z-yZx-IsM6 l S֌W<1̍Gek -biz.vE~7ôBvWA"&C+x%K+" nS優&rRzZmNF*:]PfqXXRx*^j)jsg?8ܫΣʽ)p3thכʵ $exSUYQv[٫̍nĿ>/Ͻژ:!_Oə\v%/,dٌwgV$͊w;)$VВTyNFhZJ.[e9VFkfv2ҍ'p/˦x]%;fq e<9"-@h|O:S /pYK%&ЦU41+\d5+M%|˥яǥ<1C|ÍbvzX%x[JHXm}#*_Ц{{s}lSkP.[45@&:iҬUZ$4e@'OE h7tpз2G;ể}Wz_;koֺgKY Wj}C\/ץmZp+<_sw?Yi.Rf9YsxO'SޏL=Yh;*2Vh:z7íDW-n _G# /C+v3 =gu`Я}77h7h,v:o \T75)^2 z~O74@7;ڎl{o3Vc#vם@gKn-~>G謿Axʞ@%@ϛ=~ܞt7\1@x^@KK=qp oj7uDsg]!'Lq^rዉ:} ^Lm6nBH Ej)ʸ#Z͑ \]12]ėX+r-Y%ZB'NVnN@WDaSV 5䛚|T,twO.KǛr^͖7;ʵxVW}W͐Y\7+ j++l˝3蛿xM5wZ8[.l B~9/|Vɳd\{#_s+jnE=ó$9a:ShzFe*9V)2\+mɍn4<χBs,;`̜0 ff3h9{hߙ;iGg6v|@e!/t[zGt$f3ޔ1+yoԡy.\Mx8bA];|^7CI+G4Lښk<4ve\rnF:tY<>A;%@Y3LB(AZZ;i H u%UZKדf3o@J' "ųQZ34ɍ:o~Ӽ]O #L34F N>s`ܫ߁k]斶[4xC /=_sfM m4衡@-{v[og:%Bw=y|x;ʖ%? xCӳx-\wn:[G41 r@瓘Љ ,6\8NJ6b1t6ڍ772ohϞ;4lS"d:~64?h2Q@Oh 衡5@ޝ l բ9.%WIs h ]ĕh ]NTʉR%VJ5.7vR&2r?'OEQYF 5p\O+zW{>7O˝z?8_X=^h问wZzr-M%uQovsŭw~ݾzRrѹ rBNϓ PXbvEή(UtnYK RIɒ=Wszk&XG&~(<˄Av`>ftF={%7 9EgC; Ў fGnzPAϿ%<'t;vq=mq !1zxQˁ34MBCtПu[Cb1h;ƣPap)"L=67 dt ]NzLNn$$mqiѼON@`$ dq5%q,K4=͕h_>͗s4| @jW<uMA>ӳgO[끋Z76|Nc7+vYy]!D)д ^x zͿa Vp z@{& FFzV@_v[guW)o٤v!!u%= mxle456ad 'چl9g#qO' [Kj`{fo/?oO^|6hо;SޕM׻Nz[+>^h윚wesm5{9dN뜅8˃4 q KRa 7*1HxTVNRj,'*BzNqxE'#=;?;Ã硞Жс P٪apvF4[Es:njЇDUT-@jOԀwWЬ&}Gԗ>8zF q(o24Ћ/BKWWDq-Q\ #s|P!|74s4@΍6AϞݍ8a?z~'^0=%|Ac7//3;~'nCd]d zYݍFi˻ѥ"2z+G=@o=4]GlH_pHwwPoj@v`궧*OmCx.@tͮmgS@=I:q|'gU[#ꊯgQmh&qiz>9_x&x/C37+[lC^54n!0t,&5ծJΡhP̗xQj\)&bR.jfFmenVei`t^-H iYWEyM7d" …mS5Uzu^9_/뵷ۧ^<>sjùſrn}w~tJGT&^(Nx\7r^ZKiQbamгȅ9Qĉ,^RKDEWj%F hLM'ەs?޾wt?߹7];W?[J+.5gK Yܔ%( JAY)˂$ ˒,V<4/YI B'/72x`1QBQGzLd:vܡ+D`Z5sKh';=~g6@̶@ء3У/P(8f9=r ^Ih_2M\:q@':Fl(y#1b.\ZǻAϩ#v$D rS7-,`v OtYghf͟g#)+4}p8}t@ӹg}6=VZJ,@9<~F=k6s'['h?ޖ򃟬|6yg{zhA<{653 /C@놎@c`[Yz'8M2Ck&vCm>VG2 :Mz6&?6]k:})=$\ӭtƏ鸳#g32QC/c=5o9=1E!z?ϛHPv4ghȏ垡;>`[``hp=s*WPQ Ue).BrB t))r%)Ւb=%4SB+]hg,HZJ4 9q>_6)|JVΩŒzQ1Y7y{1̫ӯOͼ95t{g];P\l+jTI9Yz^U+$ª*/+@%SY.*X9hdTZ|tH?B=9i̍ڔ>Nf1+A1CMճibz/OST7r@}/Kc|ƗBTțD>=fҳ f3㊌> o9oD9GXK'.s*lO! GLw\IЦgMhh]T@g}1@/[5&}Kv 4 qI4÷ @'Kˉ i/Az҆~ h[Gz#М˦=@=kP~ MlA е;4oykpO#_=dMv2C'/ xП/p|^1 `;:8FV5@C=@Gm/l4hOmhOxk6c]|l9+[6Mq\dLy4<)l} =KczM8oOߴd#IzvNrq A="@xg #v cআf:hh4t:QxVY hTS^chAJRq`&bR,%B9&T.4 tZh8q343 'E0IQ8%Ϊ⹒x,~]ik 7ܥzB-s>UJ(eV$xEVDqURVEMZ^5AaMcx-0=AjJ&+BX3ɷ\t & }YGp`E;:4oc9_}|0H]cG>гC';Eiq急fC@WKC@ h/@{ W?ОhڍDę S-Ruu   K~hj&B-i4!D@xp䉡5F9@HƇ_"㵂ُi)R/ǛS$:HF SĉPx9&CӼ4͉9K1i"{V7s3.ہˇT\%b^K (^4}MC'G3+_/ҸH4Z 7LM ֿ ־ e2=[_ Q4׮49i owh]/n۠s]uzM]͇ZGcmLqx|o(02}쾂Bݗ dthzISo[1=YZϮ VEFFvC[v.063t#0MM7ީ-_ ܓo@"tШY&KIdH#&H|P̔)p$xO|X ?-[8q$^^/^.I4F# nhEܱ^gqƑRpW޿k7EFS6cptx{II-1,ӆwpv lA$q MvڳN{i;mPɧ [8lvгy|Ȏdό/mgF㐆1?aIBS؊Oc^ҽcc8Mez,wy,C'6F)/}іF=SxݠsďS7끛)-uu#q`p^nɘeY0 ϛnDzȤ1ogA\ ҃(}~ Y|ja1+g'ہJܱ#1:f =V=6h: m:fPjyLGVa: [F(hh<&Бj"RKDkh ,yȫR(NJJ\c0bhHMiTJjZR`tJlgIK9fyA%eYVVe]6"IΔ%tpT8Qo 5VSz‘Smbq-KFC m9087nO2gǓV:h{ G7ҏ-?wCCS@} )q'v=qs4ktzpG+"fsw3i6=؂IFB̀ChM'˴Xz(T\AJx'^z);/h0k=v mA b7k^G@VއPp=»<-3sFCc-44ٲdcǪg A: Vy>V|pLyP8G3{Z}0ޅƕ6gN?c9x"Xx|mSQ@mkeS%7؂,KE@֛~ѾL˘i!WG;@-`9#41eh 0 c`2jFBhA .xh1Uspo$D"9&*ɀ"z'AG=0ΎCf@ >@|0 ~@)֣r'CD?(+0)@@Ghtvy/ 4#g, /y7yq5?+t5=!4mC;lU4Z{,w4Z@sGtT^.i^LYzG~Cڤ-[T ־cWV"FCׯ0LCUwC~|85= qGϞIgt=suCEC;o L  {v}!>B:0}&/ 1@3t}^g{xDZcW1C}ڰ.w _">,{v,{v<}Ξ:K|l8J p[!,x6MF9Hf[Hp ~@~4 t6wƂM% -j@hC0OR4T%tCX&Zq]ЁL:.:c̩rR䨬De`hNƔz\'fZŋ sj7 TA$i%YZQ5U]WuYٔ9 p\OHqS 岵Z$mQP6n Zg~ַa fc􁗤\4rewA<&n^ 4] 6n7I@㶷~SEC5Й!c$xơgrmU5s|njp;t4[xc,b& mw[mv}x፿/ͿUh'vCp{ZpN>2fst MhbxhxxXNJƊNj#-#c]pc<}<պnly,wz*sXX Y{F=;\ɓHg3n3]^( }]QgYk۝?Zoq1e3؋5R*F.[HeGn8uw Vi`ςkl kp5̖l1.q".)dXMLDET)^-J ThIRLQb%/\ -EJW1(6fʖN8S'sj//O奙4Wi ʋB[|_l[|  eCʪ,ԅLq*Sj+l*K1\җqE=shʏCv ƝwIh뻃{cV(g ip_"ԣk8MO9" ޟtП=~|g'pC$I,w'q!O4F\PJFƠvԖR7G+/ qgBB?$N4Ky&"̈́%9 zV!^]b`e\W 1Hӳn< M.FP;o`ꡀ7 F=mW=S@jH謟=?#z~ ZНgΉ.sk9}vw_'_7ݭ`of]fCh!_Ŭ3K>C@k衡h.f$fSkmW_y`x߮h NnP=˞*{Xxjg8Hzv%⛮؆7VѾ;Θlh88gܤvGs͑Ӵ ޏzT85?φtF=~Llrt;(h'4y@Cf@On4f7ȬYρ|nh}36344DHǠ/hгc+?@JCG@+@e$A]_eO}99:ܠC=ougl_6FoK1hÎf1&: _oq!3v 4l4&Z8F"^cP5@ e-Fá 0J|HRb:BrŔlTrVW$LO՘RJ(ZKr;[ȗn8Y=Ƭ 䁀˒")L"{60|M*Iu))O(rnSέ9p'2_(NgʓR+Y-%R|=zn0Yz3nyOW M:=MAjqf(g%B2Mw6=G4#?ƛ "%g΋Nm)y2z8vg%ʉ=m8&LwزïA ?ҁ6y@aC!uϑb}@g L@+EY4Wj\57H7Afwqݼi!%w30C4hn'ݝHmx[k VX+ߒ6ٿj37@C@})@oW_U^~4چ84E^ͱQ爞"s$44=S=󡀞wsd~1b6D68_mlT:8h~oZnhfh(KIQHƻW+ 8dG( !gNOpy5zIؗa2sٚE}>?@gk jg<$2NEQ4Sł7S044S3S 2U_HPGg"(|P8Y%ʉ c)lTG'xي&rb+_KSBqZPq DyIW$iMΛ)$oQɯbvY)׊M5&WԢs0'f\X%QHg>FEw 0$H01礜;;:;${f}wEʲq9kDSryZ@!m10!\7hym7h)sU7܆'fk0uIq1%oK6|udZQ*fZ_IA3U6 It +C:yfsϣ& މh>K.cl@;>03N@}< h@@'xNHO]v[Š`g ª:bJji-TZ+}X7 T^U6•pe*fU)uV2{:tZ"NѴi|b>X^Łxev /WXm.=#ٰ>kG7uGHn^Cv:@8Ln& t{۽M{Sݒz>tG&utAA:e"fm4nH1' ߱BDB@}i8zʋ } Gǁ'ԕco}WY v >0 =LӤϿE|q9;z4#oM|/_so lkv+vK`3ړ}ϓ}b20l*¤/Al"($!q=BH~ґߖ[A-+Ҟ8Θ֖|d!g[Jd*hy҂HZ gns6Q( >7 D#hƋ͜B[ɽ<9q9<}jhs@oM3]nVgA h2-#8"V. -MmFx aAI:PHmFԚDjLB5=TCxG*I ZrZK֚F+d\kPhKsb}X#-x1!MX;WsҹjLb*Й9s.έϕ|kSJw4m1-"˾*.?tYm}[J0M4r.IjaLI',p!w HI~o ג| Ѩϒi 9P7zVV|>s+b9KPh9B (i3dtPNdcX8mS6 +3Rt (lF3h1jA@t$j$Br,(>1K|B{m3<.)s~w~Do䦥9֌@(iθ[q9fX.ű@%o'Cf2J3|#`^nG6:s-O̗_UwBs롹5<ޮ"aTڈ6Ѐf zƽ(v4z( !CF;kishi!Vg(޼o\V/CU 7 S(CZ;;׌ (/I9`线=:l+Ӂw߻uo{;mwGK+37FB'3EBx7ׇÇCyZce<@^,>K!#{'姾]Ʝ'oN#xA>?gw&)'}ygOS6wSe x ֟zמxWpx㩼M Oŧ.7B!fng石˧\~aD͟=_<_9/lg#wֿ8bjwv}nh[B&5_y_b_/=O>arxyҐ4Q~u@!R~Լ%+0 B]eҒ fldF3q46ZpX7Dza) !v:tӑ"&CD֤kZ V4 WZ5c^뵹xWzʴ;v/:qFZokۥrT~jSZLx;nΜ+gϕrgK3yT,VKA~!Mx#b(jˁ 9&bpSmA1_1>=c7cBo5p,kZSW2^B @'"#uE-Rә)'b}؜B@ϛxs䕎DT4II(79%;vFDŽ DH֩φmEe͑&aQQAB4G#B4,A)0vSsu `%D1%бx b6Kʲl~`4grg<<3ob<X|X~ygK-!wBȜGT^&Q<\]vgMa$'!M=\6 My,г TFv:>Gmy(V{[ CB6@yhg+Oh;〾K=4vbMLmG@< fM h.?wG^ߓ6`灀>I mbOe8q(@?9}@3EG\ a/.@~2 m~o;v8Woq _+1S-~3F/zf3@L ATH mEle^msNFy{x|eɗ}Ţ) $z~I_=lĥP\<8'NF+;䠺&3"J^b`uYC&-@x/ h,@/=  0r2j ^$tF=Vmv}K"Ԗ6et3R! |3TjU4tJ x5S10t=7rF!(&dj7ӭNEC0W5%bչ,7rs8Y,WNU*e(t;=Wܙ+lFq%_dn<բ}\{6 (в h!\ovv %* GYrG@+;W̿h>;VsH~m=qcWA=/mmL͙=Q\}ȴ3hg'ߏUD[MOn s_z }nzמs\~N/f]i>oEnK93y顒WzMU{n@;cz>*ɍ= -BـF/1![ gn&6@8[`KT`C3lTTZA(^҈GIb (7sf!,%ЭfJw omvbXkkFUj;Rd|W|,OΕv BesV,*Z'l{ES8<'7CKrht-7Wube:r, sK\bz ̭A:wty%l@w ЖhGNب 6AQ^\=g7c4u!:4He[+&2:R;3Y(ptqeq%R i5ANpPh JVM,,5=%9k uiAϽb᠛1l1t(@<%ie ]~:cן6y=xYC+;g<^hqs_ؓ8Q [h2 h~a_xfyg=qs=OlŶ]{fЏNTk7AUDs/N??1w݃BL=K7fE t>$β>tS5iom9e$JB7KUY+-$7-@[bl @;rڑ/4܀@Њ:)pm> ݷ)/i&?S zm2v\͇Z@hgĴjyd+aa"f$҈jM=Cz;wN.'D Nf#jf-`t͵y4c,eYgp.h5"4H3M?iCfϲ$)1<qP1-Jvi(k%邴}Myۑ6PVى(ҸhRq:R;z~'|@Ud􁀦gugҙt oz;o}o.y@L ~xA]4yѬCTwDzzeC}i?Nf`hdMz.n>6pdm_^C4Q@f> 4Z>[#@=cxl{ThwIzq[O$})^?Q\C:0Y<\䌝ǒg&qܜ8i'hL gfyʋ5v=@#5 h9ܷ@V݀vd<<i>i>h?LPGR;P'#]5 CZ;֊iXCv\o'lKtN!);xhWSZUOэ 9#۽|o|d sNWuJn>KyM[ EV58㋬-4\{B$rͣ690ovcbvڹlXwv7v=В+ hcQXIDFw@XzX|,!Nrh^\~\ ~]vlU(_Ђ0Xx~Q@|@;o<@bx  MMפf5q4@!Voyc?pzt1D6M9{Ͻ;|쀛IgHKm)nKseLZ݇^І{{\{*=&B3V=xhݷL[OΉ 6 nx*_z_xJ{JיgƠs#&tɽso 9ss/p\ |K#).A>41>Uc<21&fI|r-KҗNJ$G8&zlÝ{_,@ ӽ#hnA@~t@`ޱeWb-#Y, _􂑞uCZ7u[h(mcv,։{x/el EC'НrSN+v5ݮLrv廃lw LkrNvL~! :'A, z^T#+/W^u=Kƙ c^3G8+мo6]W՗4fm=a)!iHg ו]hgUUQ .2>~Y>Ў hs~8C N75yE;@ MVU_qkWZh;33=ƙPByѨq)ܸn\%nCh=+4s:_S孿n=[ F?|Oco&Stfw zNTnc_1gl ;df l#zf@xF"g8@ЧI6ã&MDǚG )n%kC3$@/<=Iv p[̐#@x8ҽr@6@G vjKL|/S@k}UrmНH{1N%]\6 ݝwIlRJCFSIgLC3v6F#۩g{tyW 4m,˾.9K52x޳z\bZck1蠁Cz|=;@;G8,=ӑh-S=AS I#@GTƁDǩ]x]AVq%}O\`~3v=7N$/q21sOh,x,vh=O43VH CРg G@݀ MevyOx*0܀6l$ʠgkڮgiO м`g"L 2P.}zn?Z83k"Рgg=-S驂oUS?>=l]:̐e.{\D=37I %NqS\4<%v6oi:chb\vҀ\\vG<ݛl@3Ʈݶ"na1@ h t \gr;]Kẅ́y>ñ~H#юk]b~ڮg;NQ@{kr I9LΒ2>9=NO+N")TxHI)fGЂcY2X4e%hӻGɍ}#ّжSd@yzf,}rNF4s[] åHV9E+J;΄G8"8l~1\]EPW̨-:Ot7~ZbkjPcH@3zC|'"Mt!^  oo{{[J^wwb.d^@ԧ'@Ae ׸|gzUH_3y>}AϤS\PUMxpsg h22*[z4Wy[JలDh5tx:$38[{y3~)1).uwqVHLT`@eUh٥ cq9SF'!DN14M M %H.9>ϭ+PaU/A²on_\qUGx\]ml< /fe9CZH Oۀt-88}$'V2/Ab|Er(O_`cKIdQK{>K^Q^+DHopu"c WI_)Hf}MOۅ=tO!NE;j43$5ﰾk&I+ע̢@TApJ4UE֏iIhDvSfX}|66Cr@GlVjUyhF[O jaY_( |>mQVȊ^CkxYc634 m2 &YecL#4wǂLZp3A7B.ǭLl^=1_C!nll4*Y$o]oYQp`xFnb^lGe HL*FHW#%NsI:qcfI ǝXPOzŨ,h |cO# \L]밯 Grˌ#FxUHdwh"y !.a F(mi>?'<|Q[>w&'Yq-@KscU:6^2=J #@s9lz9< Шgg f{h{y{.@_ !&4VhгDDbvhJw ÞΤr{o6LL $=o Lm虧zv347 ʋHĦ}qDm$/ )@ChbhQ3ƟͿ^:' O!qT\$&8dbza3=?{}4C:Crތj~ڏg-z%oqx%7җL9W?> OG|C>} W2xK_Sgltk h^'Ė!QCW /h䩀8)-C4gDj@;QeF }߸3E0=KD:H;u,=; [szAhUxVJ _Lw,"Y"k"fޏ}@{-C[/ hNn'08EЊN*+SIgG~Sv@:c I)'7 }bOgQx! Ivsّ%IY3h-C:M{e6|. +t~W;/뙌m)~ .K".=jhyq_^سZCkseh'л^|ƛz戞\!~{\w04$nak_:3Y{櫠D7xr#7S…gOsx-|?bB]!y\2W.s\4A hjh{b| lo&~51Q3]\v6/ȉ*s):gZ{GV!hᨡ)0tt>b@[xo㝲ޅХDs^^$A,4 E$ABxUCkh4hǎ@|ph|-G3-x :A6^в7ƮA, c343O3:" 1r3' W8z+h&G,Dƾr5 Dh>qut#xC)H-U@YG z 4@[z6;V@7Fz~aWʎQv@ӇehgKʾ <:nWh4?kM=37C~o\כinW3&7n D_AN9Sf6!Ug>B,/ BƉg>u'ǀk$vI[;n@;"heCzIM:C]6ԙa8ٝKÎ;Gkzl~â3=kr- )zt葡=s6:ź9ۅxovQTJ V^oeL ~88 .+ZQhzwB#t 虣n@;=}$@ަV!R#Z3܆)q6_@g !l o|b+)- OQ:[z-'SY4[\hn #=o;=Ыvd-!-S\v~@ڙ'r:Jgڳh&7i";F:蜎P.Kc^.IDGP_ г/ nʡ UIo @z~{Dϯ ЦD3m+4,4b>!uYK. 13:;9 EЬy=VfM Q.#=XqZ\١!mo.(T=ksy(]"#=M[X=CP.@I5ռk6 37N{&zzm3 @Q=h_ @&Lsz:h>?|FO@@wZ5v2ހ 3i90Zs A4 zbd '-,# @C-:vP+JM6*:_)-(m@y֣\hv'^YT\B1tむn4or)>2m'}]xA~gBODy \PZή@tEYɓc7-WVlP> fF.:'!U|2P>m/X9ճPvN VCjBv1bHU.WHWC1:G֡u为%g<ߌ>B{˦-@:;rTG y&kTJҽoY=+r@=#2|P}(Ht':z>(S4aq_ zF.?WCs:M7 :!?7[=MlŭF` v'gX=;}gIΪ‚?q:=Yx|W)=sfr% Yr-c U>]&\RY3=Hm+21-ij; s$4thƶB_K/1C؊c_sr'X/yQ-,Ԓm12=3݁>h3k P[4[Qrm 5oh/ zÓ혁Fh5yfAV_SP! ܐR`KˤM$-CS[M3snn3 9xD}kcsfOlG[\6WWor\kW \i n3Wx˿e\ OfE\(( cDǚ6ewn1/_=;n4$mޝ [o@| wD>Qv@L#cHgZ|й W vFogLчi.@dA /Jꂠ.2 %)hݯ L 7u;goKya@ }t@zHQmA6ϰC@b-@c".H+bLA/9 \S9 ‚{ Oc~H(x 5~'g6wl[Uno2%;:3Bgr`}.S tοYr`撐mB<»!;C:-Nɓ|rOnmz!s 5pK3Wg{"BW;~Ks j=v hΨgmkxdTP!AiMdl.ڒ^򅖕вn^f^X6 ];֘L`4occ"-=3xUQ Mhs3ذux]`h'6r6MY N@1# @K\L`#z 1ЎmE7z.10My B+O_9еA tr1X+_aӇ'd.g.E hAVv]֟Ic'h<47x*_!ty?1P'3mށ-~`_3/-:{J2O=5OO}O=O&6ʐUg!{@A)@3<&ϒX$Lu:ot6|Q. =p bs0z6Wn&5l=.@ Y ߢqnCzqZ7K"4s:͏gЙ3t{ 3s7dzWv~$2 Xx57=.#qB];^+|`R@z>+ДˬJl.Bï"_w̘fξ!Tόˢ͛ =v@ J$L@5n:4vhЇ1!q-%h]bㅨB =9Mr}NF@!]FykCC:ӽPCZ̯uV(WUH))uoW _aboiW5_y[^W}5_YU|+?T=9`x jxlw.ZV\~&;5?Ww-кOCOCBunWйnFġ/[8ܿMS:Щe2/9q`{ Oy0lZGϭH<|q.~+ J'z&ף6?p]-׸5oa\W%S133'U6w^f!sY>åNCZ7kv3OoaR_E?< -J꒤. U>Ʃv be#p[ÌOZc*.n\[c\Pp:X >:#(P&W;!NiAdIGx pTHeA)Ҩ̑WZ^Rr7k嘁W6L{OJ"~$a)UJen+ⱽ9^ פSxtBg+DiJIK4 \rz['vbNc3x,{Ԏ?@;0%Y>Y@xr3]6Vb%t _rWnRCI{?nz՞\\ =qM =оzU4@ʚR^! } N@>i2uztԳ hzG䬺ςσ6&}2lԽ-oi7c'a3aPg0OG!@ޤ+ʓ| .{Ih[m=޾ vC#<ޟޥzp'C{_lqO|{57Ms3W 1]co{`L2kv=mml;em?q4侦+% C+6E@X4a@@z6JBu7c$PG  Z4)@[ v"c @w`ǯvBxs0k@&Q8hOְ.vRsv27-MVSA2#ڢ/Xzf0TuXY <^zF@zsץg*N :S=о:t043h9ع)J`@~4&z&96%ڡg o7ـ ʛ< x=ӁY{Gxޛtr hvKt> #=\hD }414Ί`;Z *{bw+#;93Nk䫸տb͵/ls\x:3;t2:w6q #g6y7&ڕS̯о˱@;4|,yM.;F\ⵂQx b^B#8kD76t+memRn6Ǵ~*KF{ G5 -ȡ%! vYybh{bf+XL`ndڳМh&@%-h4h;h=s G= J9vӲn4@O .7qUWm.oS(|i3M&S:fJ_@iK'Գ3gLK>W?gz@t! [:eOso7?]v*_q/Q̕S)–>fy>d3)X tN.1$g.sK_Ձ/8PCM(W??yVբ?o  -w҄@ϜL:MCC {>9>ЊBOKB RP1}&xoQ@ԕpy6yvDq::^ 7zF@s< '5e'o~@mҳڱgٳ$m;΍ vdt~_z'ں;ܹ:9>;O} }|oP{V / &Q@K1#퀖?Kß/_o³hJj+<|p#h lWN茹7\=sxZXz-<O.vg>4B;>7Vj||PB^* BCW|Sx#W@xF K4E,w9}7:Ǔ DG괐8E:)$v 9l-E"J(N_׃=%gwGְәЍ@Y 91JN9-KV==39]ݨjt)Qu/&|]ɱMB'kj!bP)ΆmD1 EL4`d+4_*)Y -}g8L ϓnVp fV.~BSoPƈ h`scP*UƆ+X6OClᕑ!yW ֭lݟ]dAkxF7=,NVCOwz&;hy _g6`5'V}_WWJ?&cAH祻l6[D:kl*4_F7^&0AMgiktbDdJC6p޳yБ}@;5A@#Hygφl:R:n;#-ԅcCẒ#";˵աZ:PXϯ⸺z2u;p OkV37qҳ8$I13Ŭ7vК?~LJ ú("l"0tdLϤ. @GzQhhs&S hβ+fSШOhsǧto ¡o5Hj?:Ʊkګb+毴3%՟K"QzW|BK3[:b75:]bsEktHf/@t>KЩSeH<}N@Cq7t=>@nu'h4ƽmFmCMnVo7 F0s~6$ =2Ɣ1nBbham>t`a#SH6 ;svvb Oƅg3Y.ڬ7@Z1ָ, .Iĝ"+x6lGw-p.\gsWep3=OgAͨg:sΜcg4G;2zV h-:.>层BsQn%@w{&BCV+bsnh5X[b=燪Chp}T-4D=>܂gF Çt~3Ytxn6U' gx`ʀ8{w#hx;}ϊrJ5>);d;En/+صe 5'9h;P,MҪsBl(AOhN'>RhT!<ܖ5j77_`ݨ]@kШg{|kjz) gQ$ B '|7o@W~O~GO;[vWkV~IAK{]ZKn :ߤ752g/J+3d,FY>zf`t8DNYӧ):%fJ&`41fhM XaA@˽=8qh\ԝF2+] h9г#-?h tÝgWh@ڑ#CC_燾6SM'w<(P"{כ]=8-5Zs FZ3~CDM8@kkxpw퀕B3ż3Vl7Z9P4@@"3{4MP.- M> C mymsߋ$qGb]jHfN߀cJGP4}uxzdfT3Sҩ~QF4P:_vkLC:>7|~x~t!S)_Tdx.3x^A\ Tok=3@MT[蜩#oԟ 47ϓƋ#<&9v /nۯD?+?7vݒ>@v[.µ;9lgkv;[İ*0V@T=(4X8h U[2lft%O#oC8;[ k|+P7ᡆ5NhbpфG. #W J˯ekLv-5.]:X $rd4h"/p5NV9tU+G2g<M-Q~bieP"]Yj$]&L >&r)dN#pX|Vo(^uiь<%)[BIL@ |6D'rI35BJaHp$קsi 6lQ)z1@$=ZLQ>crp ļxsN}16|}C a|2ұM@gn@,W oʳG32'D֩oq:œ1Nˁ2ӁEϲ~s_@3fLN D!@ǢzttẲtY+J'֛X'%gkLbi˺x"$\BNFoj\F@'V9(gN7 %ס >M ͚8]bb>ʕ:=#jaо!0=OHvO^WU(9N ?E-(vrD֎Z|CMv<P Nr 4 XIC5`*"@㔺LӹAϭJ&܌hEC V `wyvC*4\hV<a,ཌxK;=Q&<f߰o #3޲f8ԇǦ Uu5ڿLƍƌNHaվt%XUlK$UT$Aux~{h1gZiړgq?d*y/L@yf?(J!';l4|As@`4Y.<,Q2-:>?%2:p0A1wl\mn bUihcX;iw hihI]0\6t@gE9ŹvG9R=|@54l%kRW^W@Fc_ К(ljOb+RW9!AHgy+d? t_yVGU_dd-> mp,\Y W.9tx}@GY:5h\x $}Ez@,8ͫ`^{my.%}=K@ 5}Fy6Jd^Y✔*-@]Xz=jt}@#Ii7i&_]`?5sOs?/wKrkʀnϬI%-HK?3^|,<{l.! l\%bYL%|;73}@@z huȝs?:X~NJm~A=T;_o -Q;1@~ ̷܊] }@>)yfʗđW mF(t&VHC+t DYtUR RWި -HH\7jhDe90J4ݬ?,Z&gV`Voh'A,?'ﲹ;> [ >{]eW%6s\s2(={ƚtH-S[e6gy3ene],|Ahqsa]<6V>'kVD<8˭CϯB,Js$F$Ir>1ky6ܴ"#hg7Wnxa'Lm~/0}˧6zХj(`Y ;t3u%"sjyA@ϡts@υy83%: Zh϶=I5l::BT-ZVE+YoXހ8%[K!dia׀Vn-[rV~r_Lb2ߢeݧ{RIgIYKb+Zn=u q6 1:u[ChOh bhwops'%X8Y>t=AMϨ39Y/,U*7T IW!V=I%dHg\h-|C zk#841 ĝV=ڎn0iK@CVgH^bZϤoX5E4dW_s^zʋy#QU6s͞jO_gdEd|@0oг蓉IS8i>I@L76v*z4?&0>& $3vXOZgHZY#-ˡ8vB])bW @GeZ Gmlej l"|=\0J[<jg xԟ~`\I+ⰕN@|K kCy֟_p3n0_O`2 I=wmXF0|H;0ѿeNbfeΠ[#]b=jUy}F[5Ng_-WTn=[wĪ`MJ׳ Mk%u1]m\[7 XKOވt@ϐD @M=GPrD[~F.0C C mys4;[Zi!>UPR.Ɇ߃TQXzS̩q#e{At+nD+1K%䏝PoT%p+='C{龽x^o٫tЙO_Y bmïho3; @-Գ{ݚQtPϟ H@xKvY:G&OSM"v bE9&fDI5hrlJ@gL@|]+2)8 Z_f}4h;:y`mj;<"{0aCYH /H"= 1Zf)3-Y2l-oLT|^fCsAp-ONU.kHaGǡYtK/O#^d%/'Edp974.]4GyzSC#jh'S=zdMZ{vKZHRC@ⅆJ% $N;u0-ʊ>|1:رo'|*HpiX-ߴ-k\g6ZN00,[ILNB6hilm= h췚ɯq7lȜnAn@,5Eo KΪI@{a hm98O9E ڿ2JGb;sR mt;2Dtv뤬p0HRҹUeN%ee,44<&DL}-%,y`EY-"㜌bs̞,g=E)Lʳ=i9 8g 1m{nǽϻeƇ1& MÖhDT+Z\6K>0e|e֘[744-*$ۗY">I{W1=kKkh#aUK p,(x< żpB:Y: /s''TdXRet|Ft=g*3KedS x\ ֨ܔͩdSTe ~Tscĩ=Ig~N)?fǼn>x?c3/8*C֛d|49^?dKK_ ڿɽb6lWvv~k%Z[pX^/?'+5~gMUgY992,IIҙT^sVzFOi14/?NAt-ܥw-g=^!ӗsY2}`jt$}͝zBr;a7bq.G$i *#A7ukNgoKxѱl8=FGt֏~CG94p3Y]ZoRmu-\wYQa]ݚhFb\64&m\iN cMh%g cXCJ2vHÜ1Vw]8s@ZCu-f}dDKRbT/ 7&BΩKF5$V](oQ.J:OFF[n_ @.ƿ -=hE2= hW2 З2iTr7@{4ٯD:͛@ =K@;^{M?g/V irx<;z@8@w5M5!l(Eh%t&sRB:#a@ t.&s72f/ -W1Κah8ښ9 h5Ю\1Jblѳ] uzF`h6.9W\(^- V_ô"&&mxz^OgW)=9EgOYcHY 9M|<2"*-֘;ƎѣlgZ6X@ bk؅Xk3Sb@˂Nk."t_N@ە`&JLb__wEg)s׳`L-zbãR6hz)&?Ob& C4x>\9 lN,?0 1@{kϢ!A9yR3.f-Sz޾P@7.: h:3|i|RH(,7|@NV\.v@k im_g`)}=o}Y|ksDVVDMI SlXշXKZ^~SOc*>$Rt.:o52{\"Ӏ3ziw1x=NN@. ҹc~12~ȸb'Qz_2[cm+Gu1k%TTd[9h mt.z^m5:SM5y@JJ$NH yvnb} ̓; ɩ5l 0ft:ݲRm+~,EB6HwWh t5b}c: +Y >$n6N]o_0}=:tY: tTH%ok qFC; =oP3ɵ s "xc,²h@KCzG_~tЮ,Oh][߬9hrhL:DjhdSttE,] X6 Z{Nh1nNY4 \=({l @!E.B_УkH+ ӻj; hsЦu@;5t:mv.]Rkju5s]aWn:[N厘UZi #mcw*yr{ WGuX`v t gkk I* 3w tz-&K@gp йˠg:sLĔGЇ2&f'(A"{n_$!CmZ4ߔu'xAe \|;3~HMs+4*cHdyu'NvwHG$%G'ʙJh-$|A7Vg8nc ȫd9vÆC4lZ 0@bsJ9B.ԗhDg@SDmw E6{f8ZgZ3e㌍sh;0t@udX:6fM@b5}sw>zHUKE@|'w#df9y`PϗR%,;Y-`;L+*n[vK)ŬM?zu%wWAd}FwVk3h+_1%ZzI?*Kx!w t.]:o7_Xs(v΢2y C9W^ul/;k[&"{>?v^g={Q#IUޢг5gwf=+7$?횻k3Y܀sgz@kzF@b"^ k ̸gc9_zi)P@3󱠞?@tDt/ֹlfYcЏ)о;;u\6Z~_hf1Ķ a 9дt*E{A*,{֮Ym'Q,~Cfǝ~b5<@x K1a#'Ŝ;oZ7kΗKEkGMЉ@C-?dt@4΀Sl``ЗW4[bT+-}% kblvo"#8v@5"B,݌t @_IgsS}K7iYӳ}p}?򈃘.'~Mkd_Ojv|4߉;:߇Z5/Ѫ;KRrQٽK^x-=(zj)tk^EXtz4y:@_" k朅tF=9)S-/B"{q'u:cqw=%l-?㙅2lyc73Ep!֕䑁R3ksg,o'Gp)ڟm׽5{d5:gfFiAl{tA uRBCی7b&ٖVyxeC!v$Ľ}$Y(mCϭ,ίCp!q::7a|`E-9hnhlI0JyAuVV)} ~+FsH> suYJ^*CLVEuI+HԬt;Pp3虦Z̋GjٝCFuqgI}ɊbNY`hosgs\ie/%}eh6'IQfu)ѤhI 24j 8JGxS䄟\h$"p x%|lS̷-A@$zir/kz%joL;Ƃlj^ ]߂KYqo4e{!sG#r9hz>,/@ fЗkޜ4۽,C7@uss0@oxV9΄R]7 :( h,T=Etfd6Y52Y,нyɑs8Y>3sz{t4虎}#ކ% 耞h"hp 9Yɶ/@@sn}@+hrljtSM?$ h%5C[tճh1'։I[4aUZIbZ{a# tM4 }C^Oe3H,H :[f?{LUQT^Pг8v*A=?'%{t"91wo֞[-|CރVC ʡm FX{@ #;V_ :hc⨔Zo+@Fdk#Y: uY5>沙 h3MfoEB]ݾտ}@OW{=zz;hZ.zX Hnj\vfݭ2B ,@ɝef%Zz%$A=x,zAPWW d74~}@v@ =@F oZk8h@xb ==oږ vSM;h{+{q_ϴ7@S: 522]'z;-}߫ -fй# .a.e@/uUk[)zί!ܞm ÷f=YK%Igtsbnbd-^ xנ7rb5{^sbʿepw-E1>.%Qßк{4 o @+Zh;Mpe݁]@{ ~7Ip}@+'u/cqsh;Z%oLTwhq| o / ;zvy5phARPv3<}O2PV mj6Ɋ iPF=Z*V}1+y'DiV~^h;hp3*?1/ѿe\`lwhr'3)='@yLGftz 7l6c *t]J^=o Кլ r-8C͜u} hih3: p3鼃=PZ 6 zF@; b'<@nh3^X|:h>h47#2ͼ_<@n3ŬElhh+ap nI@db^4e?B.b˼eLGs,5NrBOꞳܓSmpAPwsM1{#24K"k sz6pSԳ*qHdB2,gE>$.a`f h!h;7>ǒwR&Ztq/Pc hayK К]ZKwiƞBhx6M> Z4q{f%;6RtrƳ8$R: ^=A5{11w>1{oJC~wZ&ڳg >{ mZsCwh}[hWhh_*=Z*Yt@X|zmRpx+MV.eO@sN~җs1hW*M14WVM%G$z $0NtSIS{А{P 9l7@7hy$P,&CC2ge?L+Rϻ衯}W5ͿNtb9 q-1^:-|OUq.9D?@G6w}TW^?B VឍU:@'sfvbKM@3ͽx b v rG^3zn @[*(4;h3]Q@L{3߲O!hm/⋧©`'(@O>*83e/UеGcZ{\:+jY,QA˪>RcЮ(n TfG{~ҭ{t6]%B: =³sbtfp1wAY.ϓ::@B@XÏ&]Qdh|dW˧B'}!Yt$}s0&n\g hG}0I4@O 4Dݔ6l}a{C+P88ã4&"zZ tG5*l&pOz,nV~C]{M }d}.2.k+qXwohB@o*V0tJ3Ѽ ^'u4YRXryf̵2i3߲O!{ Г^}`/꘱Q5t^>t^< 9KgKg79x1]:t.^Q ^in9\k1Y\{1otz!Y $GᅼONVU77 ˪k]zJpsZȹgVi'2@'/OgV~Jh!)>j@d|^EwkEmx]]ebjjV=m |":qַc^G1t74zH;Iq7fNAlt0zIN#d;'tH\ 5z.5i!N͡qh.6DZ *r"=FV5{Li=MU2ؽbEb]䛐|R^[w-i +vV#W$X#Nƥ,z-&9NDsR\I+_}V k4 (:cQY+gakPb5X ^fᴻN`k@ĀNdqu^W6$Kd}(E`r?-U FKVXR%? ,<0P:dً$u \W 勌-3'u)" BfÏ8`0||ND9пЮ[!ؘ\$(4j̜1BA8^Z2 t~\ Zcw Mㄸ\` v}J塙467gM",/KҶ=Z-9KhU@WvЏ_a&J'7ict9wj|Vu{_w</1޺Ӏ=1qpoy=si &'BlW#vhP|hFF=o1o(@zF@i]s]hH@{[G{uI.juN9z=Лg?@Y-ht2+1[Wm-m\(ѯ㸗T@4c@eJ~)֒ Zs8 hpe=RIAA=T<EMNPͪì}9/d:>sF½Z&MX@Mvf{ޭUrGڝfyˀ.D+0IDATۦY'M"nL!fAm:o`Um h+H%w 1YOtʓS VļkV7p߳s0:@Ƹ`ti~_d&5=yt>ɗNȅ^-|Y@y@nnm-tE̻} 7T(fF(P bfJ܉Ǡqθ={V}/\ f?oy/S̻ h1%4G4vjh(r hz=<=+@hihSрVM lH:d7Ckhк<|1wP4ɋ$! rA4^(YP:+@[ih ܉hx@s9̵gSR5jKbYh1c Zs4zk=6:Z*|@K/22o4_cKMݝg͌oE @IC  ? ah(Shyon%-$B+^Ht+ߤ[~r[˟^:.v(=V3MQ8[P{x1|$a]؋hh~ܳm@>́tѡKѐ h7?6=v;mFa--v` zt`s} h?IN G=Јu1NcKoh+Jd-Er熕oȭwh&̻Yk$fzjAʉt6{qshVJS=C!ဖ,G@1;lR>C9rL4h)oy-},Ze MX~eKKNHm5@vY9A;_CLq2nmm@/\6Q,٧A@^聽|^q,mp+$5x5"{|betZw/?{z2ݗk%rbVt~ʯ:)l ܹqr>-n}4;6 )cMϻhj=gEf̰)}@zyA@ӝA[]ǤȪ-?KŇl9CFr_c/߂kC6L@˝pF@dl,9~_> #R Zn}_hm--" t˶J J :P*7MoUS}-5ʡ}v@@;hy_砞4/)^L=34_}ɀ>772M,mX@_]{#f\v] %-&gl ~Af/zmt>}=_7_ <[8GBd $ExMff {ЁwCSo(CC@o)nЪ?;_[Eh|wWʁj_a [ D@M@{)ܛbZs€r"M2 t]_{tŸkܚCtvmwmy'>hZl$>C3# v_ 5{fi)>=g/@| \,]/:%^H@Y._KWY ċWy]K7ps6D#GNv+Y@ţxHk*kގ\JHmWHjL.;)P\ܵp8ܷM{;[ʻ1|aNA6z֛]4GP5nk}bV37oy>-vd)Gy)a1<:;?ܻ#M^k͜a `h/1\>у߳Ӄߊθl ƿcz;Aj3vbpiM@4Hp/{6fA M4zQ>)x0`-q }+lyr 4r:&<-IRiGA+ f7× \4dhL<І(4@tgq!<\aȿPkԭ*#)bTVd#^d$ W;Q8nI IYR%- "q@ jĞW,թc7iQz0:LsIbS |,2#(jcޖ1Ig:)mƤ^k)>'#{w6-zys%UI6)! `0' ݧ;Sҙ!CݻJ*W-K1,CZ[Uv&@W)@vn2 ɧ= /_Xϩ oD|j7w鬒S/i''(h~$ p]g}$_D| oalh?vd$6Їcgbv#D-';=Ég5,)ܬxę6sCy[9$r%D9X>@wͷ\UvVoj[.Mʹ~bE~w#B ͎ynN6}/@r^ M׹I1({٥ֳ\oAmR9 -ts<[;ΛvJS3'vĎ]iHghoWbⱜS[&O|No_`4~ 璸m~ľ)ƹ l ZvbL=HA_ _N+)@U4gh4`Q|3r_T:tR@\wJC_@;)e9У77K77c@Ҁ&P.  =2&S4 @{L̗m7J-Tr V(إ_xb肥h8t Waw'i~o fNDpwqM&zT = ~`:11h@_~m98I\Vr4b&~A%q1mo䆉shsS|-t+ЂM M.3zVj>[\Ѓ_6^(C@]C@C@S5~Յ?4'Hd=ݩ4 x  n7Wۍ=-;?ztm }nԀfb:;Lb|q.Rmk>5i6 At)\``Wn~ID0f9X;:ۮF>t;nb݅C'kopma+kLslb:uҮjO,cj<v7@Ã`@x;oܯg2pT: h{O{O츏sM[q@8 [4݅sVp=c#$*Xj>x02M.?1kL%1㜆ư7K77!|:Ơsl:)fv&᮳]@/EDžʩ7ݸ8XF5S,G6v 4?7긏s  3-Iwk4'T5%sIhҍ/@O[*Ǡ4g+(S[~\xvu; h PoM/?MWn@{<R"ˠgMfڌsz #I Ua>*# NPsg_ )y-Z?:p1vda1[$_Dy|^97㴂NFGi4` b^^}Z/ @-  }8 O<MN±GPݷ&mocw_O<+])ˈf; hut5! nuإd=#:%@ת<[@s=gzWZ.h=ۀ~E~߇gc@[Gͬ rĺ7 hT2n+813ciw = ]btv43t/2cb>'@߻q7b}sZH [hg~ :{We?Ɓhoe?MN(o@C=#lRzG,~e ͟NhhC $h~;$+$; '& ݾ/5M!Ū>N &m.'8zV.hFCƀ蓴Udm:&sK&4;iX{S~'-Ꞛc%+_D_$n6.Fs`z49n{&rD .mKg+3ڶ5J3+>;pgΛ&z&#pf7?* -NVx6.>4 &@1L𫰂&UI'|ir Cj%<{ws#? 8CR(̆/m`؆F<Ӭ;oըF]nȋּ0<^5?\CG+e <{YP 2|@jNS $/4[yj3qo}8g;q>PIG D9K޹Y,yv#>JVCGgz#kc m@ǩ3KY)>&?)sCXFx}ȥ&l^肤 59E8oIcžZ/H94nQ{A/Fg%瞊'vm;qwvg2|9Rz $nEפBuB4ýz;o{;xO?R=-Z0ۓ`ꙝ~nא;-fi 9lL>S ^{*)p{2{ґ)d ف%j`q]gD(^fNZE:GKvA愪^j(àa R.D}ccuO!5 :)%쒌"&&<d;vwvAgw;@pxs/z~6^g3n.hG4>ɾjj~:o }V3xI;^/Rh.fTcv~'@CR`nggqvbb,#:A кx3*K谊vjK ގ\ műˢf퐽;p:@ hېc 4sa@!)PPnB޷:nT nzm{} 59 w[?IFC@: .w""G%C0>k`'gȹ#o \]X@Gˇv<"nmV[j`2) N4t8vYTtyMǀ&\nzlJ4=V0|;fHwr@H=.59|sOxw˛;ɨ _0qpjoa8;܊c$vOT70M놀t:kh?_zFc n:0(&sJ'WC@_!@ӕ]j!v-poy ~] |tk~4n`n}m5҆4۩P8r,Z*ioAݾ1gޓD hю5H7pt*^b怖$45hi?Z:l/통1p=ܥUIe4psW\IvZ?D2! 7X&hMgҋgzB34y8mMi@gldtG l=8rN]Snƍ2szR6>hF[>yq "fiǪH,  ɪֳ pO 3V1¡)>"2!J?l Рk;7$ Oh~?-Ɏy/J4~MŻq3#gtyt@QݙZ9>[f7/v|əq /Sm/EՋhn|@3.;;v[>-ȟ܄<ܐƸtp|?; hv:1cayRa hRvh/`hfvlM/߉CgoOZD_Ϣ+HCvQ MR$̎m%26^6Iqߕո{ "3^<Wą솀ή@. 8Y|,3w~L3L˼\@ߗ77cͤ eZrjAHt:s] ~eѳ6)yC@* so[!v̔4bCS:ḵ3y GTC@g ˋru./'$s.hK hc€642/p|#;CmcpU"4zN0^QH] ɂ$uTJq熀ڹy24͉ߟ>K8%8֘ 1zҎ@,ꟂG;d7tQ@zրwh@GKUMC@(qBS;xRgJ3l[t8N?˩-92G@w~T0j٥ hhMZm2YBG. ' }0W8PVDk@eP`oU.j+7?Ak|'>͏!"~AUe8-1{c1dC+bҨuTckT!f(c;8#;=l5ZYS6'h#SuWk!* X{oA*S6421ZsevƈwhF@؀\@V}+FQ#/ԴƋUL.4/調Azs@CMJ3IZjOua 3 B=w>ޑ=LWy11[O7 ǂ-w6OqS$>)3ۑM13Lr@K̺l Ft+²tWJ +2thQ̺ [OckX%]7|JZR.Gr YD-9p\ Њ@@{<{O 쪁,|Sr³hWh蒶+3eL)!3ʠ4@wkh qӺ}u]O?g֡ Gè{5EQDz sZmפ#~Uji[uTi}Q}Uqa%;YŠe#@ [GW?)A~0eiqF~}FAZ`̂kf'V혞ڡ`Z`@j?=y]*9JppuyMeMFd֡@ϻ]uOLU <%L ߃E Hmb<s=3:Wb&f[Ve3gw?=f{BeBa3O9´^ʙ_B޶^3fY.gLrf׏3Ħ g[r:^Eƹz~fMz |$>@$tr: IGqʹeH],rOV$=mdH+*42|clآn#>A\Sm7{"DH-%.&US2Z3&\|j0xwF>`.ɹz^DK?zO8F[Iu\V`Mg<bapmPaT-ǦQވ7gMi[FrG3 N2p #fQVMۑ"6[Ȑ24.HgdNH.0l WK=zWozόP+=C{g^ f٘*9|@f33ghJz6# T84@;7BvzhZi|TG*U]\UZc]|]-Ic hD͈IVr߻เfbݩȢ. hmgʩzׂ)sa@3AgL@|-ygh5I/?z085qZ֏ r7ZpY"h}Gs.v6#Bphe^>Ry UVKR*Fˋe3䕫Dgh2Z:Q6 |9!hxoWn} Uڟ*vEst摉Lkb&ɦ(l|%b  JIhf٩ W-h2,{4<|=q{6x2xռhEg?:@y о]!iL'59hG}:lፆpsk,GQ].j~Kcb>@w[` .ht./hC@_@9@oq=gsw.&zȀV7¯+An `Zh `hBfn6E?˭ntf|&kü2x77rBܸ.u$.>#SzY[9\{'1{'Vp=(\ v'5 i@GIn‘\ڋ7K_[i@-y}!)@bIl~d~>MC5[ yuDұDwq.۩6mH?̖b1TL?f%j 4Iځ!9eљ2z lLT7}먧':\b&ƔSm3:u$ lFvu2\Qd(*-33Dg6\bNry|љ:// v=%/Eh&< Q=C8SG5$λ±9Si:xn6q@y+wgě5qF+~ w6Ew֟nTЮ{rj1@Gt9(}yhc~1Y|ꀦzfVڻ$]sq@G:nYz*kNy8Рgh,tRZZ.Sm3:L*@mȀWj@S+wKL} ސ3ֆ%碀20:QY<ـֆכ[Ĺf\"Z Cj@R֤,h殀 72@Ehg h[\Q~Dm ?]9К@ȇ^ hٗm*y莞/:yιV:1@G6E-5ѡo8E(Chk}!US]?BE}[ɛ͗yL4v`={J^st5R4 ^sW[ujSv3]}d]f?Vn}$?\$ɸgʵ}g'VwrN^z-:} {I ʩ ݉|h:˽zC[vma\.+'q-鈿C4[7ɏcBCP^$咚؍2W? a}ߎxrX^y2\^^˪ -f }?MeV6q y֎\M4<@3^r$xq@4 ;zczډ|h:zD8h7gSqG\@Wn6?7?t r]^j!tzhR|wy/@.i!{o pH܈IENDB`Miriway-Miriway-854d43d/example-configs/000077500000000000000000000000001521360756500202065ustar00rootroot00000000000000Miriway-Miriway-854d43d/example-configs/miriway-config-Budgie.bash000077500000000000000000000054321521360756500251750ustar00rootroot00000000000000#!/bin/bash set -e if [ ! -e ~/.config ]; then mkdir ~/.config; fi shell_components="budgie-panel budgie-run-dialog /usr/libexec/budgie-desktop/budgie-polkit-dialog tilix grim swaylock swaync swaybg" shell_packages="budgie-desktop-environment budgie-wallpapers tilix grim swaylock sway-notification-center swaybg" miriway_config="${XDG_CONFIG_HOME:-$HOME/.config}/miriway-shell.config" miriway_settings="${XDG_CONFIG_HOME:-$HOME/.config}/miriway-shell.settings" unset need_install for component in $shell_components do if ! command -v "$component" > /dev/null then echo May need to install "$component" need_install=1 fi done if [ -e "${miriway_config}" ]; then echo WARNING Overwriting "${miriway_config}" fi if [ -e "${miriway_settings}" ]; then echo WARNING Overwriting "${miriway_settings}" fi read -p"OK to proceed? [y/n] " yn case $yn in [Yy] ) echo Proceeding...;; [Nn] ) exit 1;; esac if [ -n "$need_install" ] then if command -v apt > /dev/null then sudo apt install $shell_packages elif command -v dnf > /dev/null then sudo dnf install $shell_packages elif command -v apk > /dev/null then sudo apk add $shell_packages else echo ERROR: I cannot find an install tool for this system fi fi # Ensure we have a config file with the fixed options cat < "${miriway_config}" x11-window-title=Budgie/Miriway idle-timeout=600 app-env-amend=XDG_SESSION_TYPE=wayland:GTK_USE_PORTAL=0:XDG_CURRENT_DESKTOP=Budgie:GTK_A11Y=none:-GTK_IM_MODULE:SSH_AUTH_SOCK=/run/user/$(id -u)/keyring/ssh lockscreen-app=miriway-unsnap swaylock -i /usr/share/backgrounds/budgie/ubuntu_budgie_wallpaper1.jpg shell-component=systemd-run --user --scope --slice=background.slice swaybg --mode fill --output '*' --image /usr/share/backgrounds/budgie/ubuntu_budgie_wallpaper1.jpg shell-component=systemd-run --user --scope --slice=background.slice swaync shell-component=systemd-run --user --scope --slice=background.slice budgie-panel shell-component=miriway-unsnap systemd-run --user --scope --slice=background.slice gnome-keyring-daemon --foreground shell-component=miriway-unsnap systemd-run --user --scope --slice=background.slice /usr/libexec/budgie-desktop/budgie-polkit-dialog EOT cat < "${miriway_settings}" command_ctrl_alt=t:miriway-unsnap tilix command_shell_meta=a:miriway-unsnap budgie-run-dialog command_meta=Print:miriway-unsnap sh -c "grim ~/Pictures/screenshot-\$(date --iso-8601=seconds).png" command_shell_ctrl_alt=l:miriway-unsnap loginctl lock-session command_ctrl_alt=Up:@toggle-always-on-top command_meta=Left:@dock-left command_meta=Right:@dock-right command_meta=Space:@toggle-maximized command_meta=Home:@workspace-begin command_meta=End:@workspace-end command_meta=Page_Up:@workspace-up command_meta=Page_Down:@workspace-down command_ctrl_alt=BackSpace:@exit EOT Miriway-Miriway-854d43d/example-configs/miriway-config-LXQt.bash000077500000000000000000000046061521360756500246300ustar00rootroot00000000000000#!/bin/bash set -e if [ ! -e ~/.config ]; then mkdir ~/.config; fi shell_components="lxqt-policykit-agent qterminal lxqt-runner lxqt-panel swaybg lxqt-notificationd" shell_packages="lxqt-policykit qterminal lxqt-runner lxqt-panel lubuntu-artwork swaybg lxqt-notificationd" miriway_config="${XDG_CONFIG_HOME:-$HOME/.config}/miriway-shell.config" miriway_settings="${XDG_CONFIG_HOME:-$HOME/.config}/miriway-shell.settings" unset need_install for component in $shell_components do if ! command -v "$component" > /dev/null then echo May need to install "$component" need_install=1 fi done if [ -e "${miriway_config}" ]; then echo WARNING Overwriting "${miriway_config}" fi if [ -e "${miriway_settings}" ]; then echo WARNING Overwriting "${miriway_settings}" fi read -p"OK to proceed? [y/n] " yn case $yn in [Yy] ) echo Proceeding...;; [Nn] ) exit 1;; esac if [ -n "$need_install" ] then if command -v apt > /dev/null then sudo apt install $shell_packages fonts-font-awesome lxqt-branding-debian elif command -v dnf > /dev/null then sudo dnf install $shell_packages fontawesome-fonts elif command -v apk > /dev/null then sudo apk add $shell_packages font-awesome else echo ERROR: I cannot find an install tool for this system fi fi # Ensure we have a config file with the fixed options cat < "${miriway_config}" x11-window-title=LXQt/Miriway idle-timeout=600 env-hacks=MIR_ANCHOR_RECTANGLE_UNCONSTRAINED=1 app-env-amend=XDG_SESSION_TYPE=wayland:GTK_USE_PORTAL=0:XDG_CURRENT_DESKTOP=LXQt:GTK_A11Y=none shell-component=swaybg --mode fill --output '*' --image /usr/share/lubuntu/wallpapers/lubuntu-default-wallpaper.jpg shell-component=miriway-unsnap lxqt-notificationd shell-component=miriway-unsnap lxqt-policykit-agent shell-component=miriway-unsnap lxqt-panel EOT cat < "${miriway_settings}" command_ctrl_alt=t:miriway-unsnap qterminal command_shell_meta=a:miriway-unsnap lxqt-runner command_shell_plain=F12:miriway-unsnap qterminal -d command_plain=XF86MonBrightnessUp:miriway-unsnap lxqt-config-brightness -i command_plain=XF86MonBrightnessDown:miriway-unsnap lxqt-config-brightness -d command_meta=Left:@dock-left command_meta=Right:@dock-right command_meta=Space:@toggle-maximized command_meta=Home:@workspace-begin command_meta=End:@workspace-end command_meta=Page_Up:@workspace-up command_meta=Page_Down:@workspace-down command_ctrl_alt=BackSpace:@exit EOT Miriway-Miriway-854d43d/example-configs/miriway-config-MATE.bash000077500000000000000000000072321521360756500245240ustar00rootroot00000000000000#!/bin/bash set -e if [ ! -e ~/.config ]; then mkdir ~/.config; fi if [ -e "/usr/libexec/mate-polkit/polkit-mate-authentication-agent-1" ]; then polkit_agent="/usr/libexec/mate-polkit/polkit-mate-authentication-agent-1" else polkit_agent="/usr/libexec/polkit-mate-authentication-agent-1" fi shell_components="mate-panel mate-terminal /usr/libexec/mate-notification-daemon/mate-notification-daemon ${polkit_agent} swaybg" shell_packages="mate-panel mate-terminal mate-notification-daemon mate-polkit mate-backgrounds swaybg" miriway_config="${XDG_CONFIG_HOME:-$HOME/.config}/miriway-shell.config" miriway_settings="${XDG_CONFIG_HOME:-$HOME/.config}/miriway-shell.settings" for component in $shell_components do if ! command -v "$component" > /dev/null then echo Need to install "$component" need_install=1 fi done if [ -e "${miriway_config}" ]; then echo WARNING Overwriting "${miriway_config}" fi if [ -e "${miriway_settings}" ]; then echo WARNING Overwriting "${miriway_settings}" fi read -p"OK to proceed? [y/n] " yn case $yn in [Yy] ) echo Proceeding...;; [Nn] ) exit 1;; esac if [ -n "$need_install" ] then if command -v apt > /dev/null then sudo apt install $shell_packages fonts-font-awesome elif command -v dnf > /dev/null then sudo dnf install $shell_packages fontawesome-fonts elif command -v apk > /dev/null then sudo apk add $shell_packages font-awesome else echo ERROR: I cannot find an install tool for this system fi fi if [ -e "/usr/libexec/mate-polkit/polkit-mate-authentication-agent-1" ]; then polkit_agent="/usr/libexec/mate-polkit/polkit-mate-authentication-agent-1" elif [ -e "/usr/libexec/polkit-mate-authentication-agent-1" ]; then polkit_agent="/usr/libexec/polkit-mate-authentication-agent-1" else polkit_agent="$(find /usr/lib* -name polkit-*-agent-1 | tail -n 1)" fi if [ -e "/usr/share/backgrounds/ubuntu-mate-common/Green-Wall-Logo.png" ]; then # Try Ubuntu MATE wallpaper (from ubuntu-mate-wallpapers-common) background="/usr/share/backgrounds/ubuntu-mate-common/Green-Wall-Logo.png" elif [ -e "/usr/share/backgrounds/mate/desktop/GreenTraditional.jpg" ]; then # Try Ubuntu MATE wallpaper (from mate-backgrounds) background="/usr/share/backgrounds/mate/desktop/GreenTraditional.jpg" elif [ -e "/usr/share/backgrounds/warty-final-ubuntu.png" ]; then # fall back to Ubuntu default background="/usr/share/backgrounds/warty-final-ubuntu.png" else # fall back to anything we can find background="$(find /usr/share/backgrounds/ -type f | tail -n 1)" fi # Ensure we have a config file with the fixed options cat < "${miriway_config}" x11-window-title=MATE/Miriway idle-timeout=600 app-env-amend=XDG_SESSION_TYPE=wayland:GTK_USE_PORTAL=0:XDG_CURRENT_DESKTOP=MATE:GTK_A11Y=none shell-component=miriway-unsnap /usr/libexec/mate-notification-daemon/mate-notification-daemon shell-component=systemd-run --user --scope --slice=background.slice swaybg --mode fill --output '*' --image '${background}' shell-component=miriway-unsnap ${polkit_agent} shell-component=miriway-unsnap mate-panel EOT cat < "${miriway_settings}" command_shell_meta=a:miriway-unsnap mate-panel --run-dialog command_ctrl_alt=t:miriway-unsnap mate-terminal # This hack to work with X11 #command_shell_meta=a:miriway-unsnap sh -c "exec mate-panel --run-dialog --display \$DISPLAY" #command_ctrl_alt=t:miriway-unsnap sh -c "exec mate-terminal --display \$DISPLAY" command_meta=Left:@dock-left command_meta=Right:@dock-right command_meta=Space:@toggle-maximized command_meta=Home:@workspace-begin command_meta=End:@workspace-end command_meta=Page_Up:@workspace-up command_meta=Page_Down:@workspace-down command_ctrl_alt=BackSpace:@exit EOT Miriway-Miriway-854d43d/example-configs/miriway-config-SWAY.bash000077500000000000000000000156351521360756500245670ustar00rootroot00000000000000#!/bin/bash set -e if [ ! -e ~/.config ]; then mkdir ~/.config; fi shell_components="waybar wofi kgx swaybg swaylock swaync" shell_packages="waybar wofi gnome-console swaybg swaylock sway-notification-center sway-backgrounds" miriway_config="${XDG_CONFIG_HOME:-$HOME/.config}/miriway-shell.config" miriway_settings="${XDG_CONFIG_HOME:-$HOME/.config}/miriway-shell.settings" waybar_config="${XDG_CONFIG_HOME:-$HOME/.config}/waybar/config" waybar_style="${XDG_CONFIG_HOME:-$HOME/.config}/waybar/style.css" unset need_install for component in $shell_components do if ! command -v "$component" > /dev/null then echo Need to install "$component" need_install=1 fi done if [ -e "${miriway_config}" ]; then echo WARNING Overwriting "${miriway_config}" fi if [ -e "${miriway_settings}" ]; then echo WARNING Overwriting "${miriway_settings}" fi if [ -e "${waybar_config}" ]; then echo WARNING Overwriting "${waybar_config}" fi if [ -e "${waybar_style}" ]; then echo WARNING Overwriting "${waybar_style}" fi read -p"OK to proceed? [y/n] " yn case $yn in [Yy] ) echo Proceeding...;; [Nn] ) exit 1;; esac if [ -n "$need_install" ] then if command -v apt > /dev/null then sudo apt install $shell_packages fonts-font-awesome elif command -v dnf > /dev/null then sudo dnf install $shell_packages fontawesome-fonts elif command -v apk > /dev/null then sudo apk add $shell_packages font-awesome else echo ERROR: I cannot find an install tool for this system fi fi if [ -e "/usr/share/backgrounds/sway/Sway_Wallpaper_Blue_2048x1536.png" ]; then # Try SWAY wallpaper (from sway-backgrounds) background="/usr/share/backgrounds/sway/Sway_Wallpaper_Blue_2048x1536.png" elif [ -e "/usr/share/backgrounds/sway/Sway_Wallpaper_Blue_1920x1080.png" ]; then # Try SWAY wallpaper (from sway-backgrounds) background="/usr/share/backgrounds/sway/Sway_Wallpaper_Blue_1920x1080.png" elif [ -e "/usr/share/backgrounds/warty-final-ubuntu.png" ]; then # fall back to Ubuntu default background="/usr/share/backgrounds/warty-final-ubuntu.png" else # fall back to anything we can find background="$(find /usr/share/backgrounds/ -type f | tail -n 1)" fi # Ensure we have a config file with the fixed options cat < "${miriway_config}" x11-window-title=Sway/Miriway idle-timeout=600 app-env-amend=XDG_SESSION_TYPE=wayland:GTK_USE_PORTAL=0:XDG_CURRENT_DESKTOP=Sway:GTK_A11Y=none lockscreen-app=miriway-unsnap swaylock -i ${background} shell-component=systemd-run --user --scope --slice=background.slice swaybg --mode fill --output '*' --image ${background} shell-component=systemd-run --user --scope --slice=background.slice swaync shell-component=miriway-unsnap waybar EOT cat < "${miriway_settings}" command_ctrl_alt=t:miriway-unsnap kgx command_shell_meta=a:miriway-unsnap wofi --show drun --location top_left command_shell_ctrl_alt=l:miriway-unsnap loginctl lock-session command_meta=Left:@dock-left command_meta=Right:@dock-right command_meta=Space:@toggle-maximized command_meta=Home:@workspace-begin command_meta=End:@workspace-end command_meta=Page_Up:@workspace-up command_meta=Page_Down:@workspace-down command_ctrl_alt=BackSpace:@exit EOT # Ensure we have a config file with the fixed options mkdir -p ~/.config/waybar/ cat < "${waybar_config}" { "layer": "bottom", // Waybar at top layer "height": 30, // Waybar height (to be removed for auto height) "modules-left": ["network"], "modules-center": ["clock"], "modules-right": ["cpu", "memory", "temperature", "battery"], "tray": { // "icon-size": 21, "spacing": 10 }, "clock": { "format": "{:%y-%m-%d %H:%M}", "tooltip-format": "{:%y-%m-%d | %H:%M}", "format-alt": "{:%H:%M}" }, "cpu": { "format": "CPU: {usage}%", "tooltip": false }, "memory": { "format": "Mem: {}%" }, "temperature": { // "thermal-zone": 2, // "hwmon-path": "/sys/class/hwmon/hwmon2/temp1_input", "critical-threshold": 80, // "format-critical": "{temperatureC}°C {icon}", "format": "{temperatureC}°C", "format-icons": ["", "", ""] }, "battery": { "states": { // "good": 95, "warning": 30, "critical": 15 }, "format-alt": "{capacity}% {icon}", "format-charging": "{capacity}% ", "format-plugged": "{capacity}% ", "format": "{time} ({capacity}%)", // "format-good": "", // An empty format will hide the module // "format-full": "", "format-icons": ["", "", "", "", ""] }, "network": { // "interface": "wlp2*", // (Optional) To force the use of this interface "format-wifi": "{essid} ({signalStrength}%)", "format-ethernet": "{ifname}: {ipaddr}/{cidr} ", "format-linked": "{ifname} (No IP) ", "format-disconnected": "Disconnected ⚠", "format-alt": "{ifname}: {ipaddr}/{cidr}" } } EOT cat < "${waybar_style}" * { border: none; border-radius: 0; /* 'otf-font-awesome' is required to be installed for icons */ font-family: Roboto, Helvetica, Arial, sans-serif; font-size: 13px; min-height: 0; } window#waybar { /*background-color: rgba(43, 48, 59, 0.5); border-bottom: 3px solid rgba(100, 114, 125, 0.5);*/ background-color: rgba(146, 0, 106, 0.3); border-bottom: 3px solid rgba(73, 0, 53, 0.3); color: #ffffff; transition-property: background-color; transition-duration: .5s; } window#waybar.hidden { opacity: 0.2; } window#waybar.termite { background-color: #3F3F3F; } window#waybar.chromium { background-color: #000000; border: none; } #mode { background-color: #64727D; border-bottom: 3px solid #ffffff; } #clock, #battery, #cpu, #memory, #temperature, #backlight, #network, #pulseaudio, #custom-media, #tray, #mode, #idle_inhibitor, #mpd { padding: 0 10px; margin: 0 4px; color: #ffffff; } #clock { background-color: #64727D; } #battery { background-color: #ffffff; color: #000000; } #battery.charging { color: #ffffff; background-color: #26A65B; } @keyframes blink { to { background-color: #ffffff; color: #000000; } } #battery.critical:not(.charging) { background-color: #f53c3c; color: #ffffff; animation-name: blink; animation-duration: 0.5s; animation-timing-function: linear; animation-iteration-count: infinite; animation-direction: alternate; } label:focus { background-color: #000000; } #cpu { background-color: #2ecc71; color: #000000; } #memory { background-color: #9b59b6; } #backlight { background-color: #90b1b1; } #network { background-color: #2980b9; } #network.disconnected { background-color: #f53c3c; } #temperature { background-color: #f0932b; } #temperature.critical { background-color: #eb4d4b; } #tray { background-color: #2980b9; } EOT Miriway-Miriway-854d43d/example-configs/miriway-config-XFCE.bash000077500000000000000000000042431521360756500245220ustar00rootroot00000000000000#!/bin/bash set -e if [ ! -e ~/.config ]; then mkdir ~/.config; fi shell_components="xfce4-terminal xfce4-appfinder xfce4-panel xfdesktop /usr/lib/x86_64-linux-gnu/xfce4/notifyd/xfce4-notifyd /usr/libexec/xfce-polkit" shell_packages="xfce4-terminal xfce4-appfinder xfce4-panel swaybg xfdesktop4 xfce4-notifyd xfce-polkit" miriway_config="${XDG_CONFIG_HOME:-$HOME/.config}/miriway-shell.config" miriway_settings="${XDG_CONFIG_HOME:-$HOME/.config}/miriway-shell.settings" unset need_install for component in $shell_components do if ! command -v "$component" > /dev/null then echo May need to install "$component" need_install=1 fi done if [ -e "${miriway_config}" ]; then echo WARNING Overwriting "${miriway_config}" fi if [ -e "${miriway_settings}" ]; then echo WARNING Overwriting "${miriway_settings}" fi read -p"OK to proceed? [y/n] " yn case $yn in [Yy] ) echo Proceeding...;; [Nn] ) exit 1;; esac if [ -n "$need_install" ] then if command -v apt > /dev/null then sudo apt install $shell_packages fonts-font-awesome elif command -v dnf > /dev/null then sudo dnf install $shell_packages fontawesome-fonts elif command -v apk > /dev/null then sudo apk add $shell_packages font-awesome else echo ERROR: I cannot find an install tool for this system fi fi # Ensure we have a config file with the fixed options cat < "${miriway_config}" x11-window-title=XFCE/Miriway idle-timeout=600 app-env-amend=XDG_SESSION_TYPE=wayland:GTK_USE_PORTAL=0:XDG_CURRENT_DESKTOP=XFCE:GTK_A11Y=none shell-component=miriway-unsnap xfdesktop shell-component=miriway-unsnap /usr/lib/$(uname -m)-linux-gnu/xfce4/notifyd/xfce4-notifyd shell-component=miriway-unsnap /usr/libexec/xfce-polkit shell-component=miriway-unsnap xfce4-panel EOT cat < "${miriway_settings}" command_shell_meta=a:miriway-unsnap xfce4-appfinder --disable-server command_ctrl_alt=t:miriway-unsnap xfce4-terminal command_meta=Left:@dock-left command_meta=Right:@dock-right command_meta=Space:@toggle-maximized command_meta=Home:@workspace-begin command_meta=End:@workspace-end command_meta=Page_Up:@workspace-up command_meta=Page_Down:@workspace-down command_ctrl_alt=BackSpace:@exit EOT Miriway-Miriway-854d43d/example-configs/miriway-config-alan_g.bash000077500000000000000000000221111521360756500252100ustar00rootroot00000000000000#!/bin/bash set -e if [ ! -e ~/.config ]; then mkdir ~/.config; fi if [ -e "/usr/libexec/mate-polkit/polkit-mate-authentication-agent-1" ]; then polkit_agent="/usr/libexec/mate-polkit/polkit-mate-authentication-agent-1" else polkit_agent="/usr/libexec/polkit-mate-authentication-agent-1" fi shell_components="synapse swaync swaybg swaylock kgx grim gnome-keyring-daemon ${polkit_agent}" shell_packages="synapse sway-notification-center swaybg swaylock gnome-console grim gnome-keyring mate-polkit" miriway_config="${XDG_CONFIG_HOME:-$HOME/.config}/miriway-shell.config" miriway_settings="${XDG_CONFIG_HOME:-$HOME/.config}/miriway-shell.settings" yambar_config="${XDG_CONFIG_HOME:-$HOME/.config}/yambar/config.yml" unset need_install for component in $shell_components do if ! command -v "$component" > /dev/null then echo Need to install "$component" need_install=1 fi done if [ -e "${miriway_config}" ]; then echo WARNING Overwriting "${miriway_config}" fi if [ -e "${miriway_settings}" ]; then echo WARNING Overwriting "${miriway_settings}" fi if [ -e "${yambar_config}" ]; then echo WARNING Overwriting "${yambar_config}" fi read -p"OK to proceed/configure only? [y/n/c] " yn case $yn in [Yy] ) echo Proceeding...;; [Cc] ) echo Skippling install...; unset need_install;; [Nn] ) exit 1;; esac if [ -n "$need_install" ] then if command -v apt > /dev/null then sudo apt install $shell_packages fonts-font-awesome elif command -v dnf > /dev/null then sudo dnf install $shell_packages fontawesome-fonts elif command -v apk > /dev/null then sudo apk add $shell_packages font-awesome else echo ERROR: I cannot find an install tool for this system fi fi mkdir "$(dirname "${yambar_config}")" -p -m 700 if [ -e "/usr/libexec/mate-polkit/polkit-mate-authentication-agent-1" ]; then polkit_agent="/usr/libexec/mate-polkit/polkit-mate-authentication-agent-1" elif [ -e "/usr/libexec/polkit-mate-authentication-agent-1" ]; then polkit_agent="/usr/libexec/polkit-mate-authentication-agent-1" else polkit_agent="$(find /usr/lib* -name polkit-*-agent-1 | tail -n 1)" fi miriway_display="${miriway_config/%config/display}" if [ -e "/home/${USER}/Pictures/202109-Norfolk/IMG_5949.JPG" ]; then background="/home/${USER}/Pictures/202109-Norfolk/IMG_5949.JPG" elif [ -e "/usr/share/backgrounds/warty-final-ubuntu.png" ]; then # fall back to Ubuntu default background="/usr/share/backgrounds/warty-final-ubuntu.png" else # fall back to anything we can find background="$(find /usr/share/backgrounds/ -type f | tail -n 1)" fi # Ensure we have a config file with the fixed options cat < "${miriway_config}" x11-window-title=Miriway idle-timeout=600 app-env-amend=XDG_SESSION_TYPE=wayland:GTK_USE_PORTAL=0:XDG_CURRENT_DESKTOP=Miriway:GTK_A11Y=none:-GTK_IM_MODULE:SSH_AUTH_SOCK=/run/user/$(id -u)/keyring/ssh display-config=static=${miriway_display} lockscreen-app=miriway-unsnap swaylock -i ${background} shell-component=miriway-unsnap systemd-run --user --scope --slice=background.slice synapse --startup shell-component=systemd-run --user --scope --slice=background.slice swaybg --mode fill --output '*' --image ${background} shell-component=systemd-run --user --scope --slice=background.slice swaync shell-component=systemd-run --user --scope --slice=background.slice yambar shell-component=miriway-unsnap systemd-run --user --scope --slice=background.slice gnome-keyring-daemon --foreground shell-component=miriway-unsnap systemd-run --user --scope --slice=background.slice ${polkit_agent} EOT cat < "${miriway_settings}" touchpad_tap_to_click=true command_ctrl_alt=t:miriway-unsnap kgx command_shell_meta=a:miriway-unsnap synapse command_meta=Print:miriway-unsnap sh -c "grim ~/Pictures/screenshot-\$(date --iso-8601=seconds).png" command_shell_ctrl_alt=l:miriway-unsnap loginctl lock-session command_ctrl_alt=d:cp ${miriway_display}~docked ${miriway_display} command_ctrl_alt=u:cp ${miriway_display}~undocked ${miriway_display} command_ctrl_alt=s:miriway-swap command_ctrl_alt=k:miriway-unsnap lock-and-suspend.sh command_ctrl_alt=Up:@toggle-always-on-top command_shell_ctrl_alt=y:systemd-run --user --scope --slice=background.slice yambar command_meta=Left:@dock-left command_meta=Right:@dock-right command_meta=Space:@toggle-maximized command_meta=Home:@workspace-begin command_meta=End:@workspace-end command_meta=Page_Up:@workspace-up command_meta=Page_Down:@workspace-down command_ctrl_alt=BackSpace:@exit EOT # Ensure we have a config file with the fixed options cat < "${yambar_config}" awesome: &awesome Font Awesome 6 Free:style=solid:pixelsize=14 ubuntu: &ubuntu Font Ubuntu 6 Free:style=solid:pixelsize=14 bar: location: top height: 21 background: 282828ff font: *ubuntu left: - cpu: content: map: deco: &greybg background: color: 3f3f3fff conditions: id >= 0: - ramp: tag: cpu items: - string: {text: ▁, foreground: 00ff00ff} - string: {text: ▂, foreground: 00ff00ff} - string: {text: ▃, foreground: 00ff00ff} - string: {text: ▄} - string: {text: ▅} - string: {text: ▆, foreground: ffa600ff} - string: {text: ▇, foreground: ffa600ff} - string: {text: █, foreground: ff0000ff} - mem: content: - string: margin: 5 text: "mem: {percent_used}%" deco: *greybg center: - clock: content: - string: margin: 5 text: "{date} {time}" deco: *greybg right: EOT for wificard in /sys/class/net/wl* do cat <> "${yambar_config}" - network: name: $(basename "$wificard") content: map: deco: *greybg margin: 5 default: {string: {text: , font: *awesome}} conditions: state == down: {string: {text: , font: *awesome}} state == up: map: default: - string: {text: , font: *awesome, deco: *greybg} # - string: {text: "{ssid} {dl-speed:mb}/{ul-speed:mb} Mb/s" } conditions: ipv4 == "": - string: {text: , font: *awesome} # - string: {text: "{ssid} {dl-speed:mb}/{ul-speed:mb} Mb/s"} EOT done for battery in /sys/class/power_supply/BAT* do cat <> "${yambar_config}" - battery: name: $(basename "$battery") anchors: discharging: &discharging list: items: - ramp: tag: capacity items: - string: {text: , foreground: ff0000ff, font: *awesome} - string: {text: , foreground: ffa600ff, font: *awesome} - string: {text: , font: *awesome} - string: {text: , font: *awesome} - string: {text: , font: *awesome} - string: {text: , font: *awesome} - string: {text: , font: *awesome} - string: {text: , font: *awesome} - string: {text: , font: *awesome} - string: {text: , foreground: 00ff00ff, font: *awesome} - string: {text: "{capacity}% {estimate}"} content: map: deco: *greybg margin: 5 conditions: state == unknown: <<: *discharging state == discharging: <<: *discharging state == charging: - string: {text: , foreground: 00ff00ff, font: *awesome} - string: {text: "{capacity}% {estimate}"} state == full: - string: {text: , foreground: 00ff00ff, font: *awesome} - string: {text: "{capacity}% full"} state == "not charging": - ramp: tag: capacity items: - string: {text:  , foreground: ff0000ff, font: *awesome} - string: {text:  , foreground: ffa600ff, font: *awesome} - string: {text:  , foreground: 00ff00ff, font: *awesome} - string: {text:  , foreground: 00ff00ff, font: *awesome} - string: {text:  , foreground: 00ff00ff, font: *awesome} - string: {text:  , foreground: 00ff00ff, font: *awesome} - string: {text:  , foreground: 00ff00ff, font: *awesome} - string: {text:  , foreground: 00ff00ff, font: *awesome} - string: {text:  , foreground: 00ff00ff, font: *awesome} - string: {text:  , foreground: 00ff00ff, font: *awesome} - string: {text: "{capacity}%"} EOT done Miriway-Miriway-854d43d/miriway000077500000000000000000000026551521360756500165440ustar00rootroot00000000000000#! /bin/sh set -e bindir=$(dirname "$0") if [ "${bindir}" != "" ]; then bindir="${bindir}/"; fi if [ -n "${XDG_CURRENT_DESKTOP+x}" ] then unset MIRIWAY_SESSION_STARTUP MIRIWAY_SESSION_SHUTDOWN if [ -n "${DISPLAY+x}" ] then echo "Info: X11 server '${DISPLAY}' already exists, using it as host" export MIR_SERVER_PLATFORM_DISPLAY_LIBS=mir:x11 unset WAYLAND_DISPLAY elif [ -n "${WAYLAND_DISPLAY}" ] && [ -O "${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY}" ] then echo "Info: wayland endpoint '${WAYLAND_DISPLAY}' already exists, using it as host" export MIR_SERVER_PLATFORM_DISPLAY_LIBS=mir:wayland export MIR_SERVER_WAYLAND_HOST="${WAYLAND_DISPLAY}" unset WAYLAND_DISPLAY unset DISPLAY fi fi if [ ! -d "${XDG_RUNTIME_DIR}" ] then echo "Error: XDG_RUNTIME_DIR '${XDG_RUNTIME_DIR}' does not exists" exit 1 fi if [ -e "/etc/xdg/xdg-miriway" ] && [ "${XDG_CONFIG_DIRS#*/etc/xdg/xdg-miriway}" = "${XDG_CONFIG_DIRS}" ] then export XDG_CONFIG_DIRS="/etc/xdg/xdg-miriway:${XDG_CONFIG_DIRS:-/etc/xdg}" fi if [ -e "/usr/local/etc/xdg/xdg-miriway" ] && [ "${XDG_CONFIG_DIRS#*/usr/local/etc/xdg/xdg-miriway}" = "${XDG_CONFIG_DIRS}" ] then export XDG_CONFIG_DIRS="/usr/local/etc/xdg/xdg-miriway:${XDG_CONFIG_DIRS:-/etc/xdg}" fi if command -v Xwayland > /dev/null then export MIR_SERVER_ENABLE_X11=1 MIR_SERVER_XWAYLAND_PATH=$(which Xwayland) export MIR_SERVER_XWAYLAND_PATH fi exec "${bindir}"miriway-shell "$@"Miriway-Miriway-854d43d/miriway-background000077500000000000000000000005041521360756500206500ustar00rootroot00000000000000#! /bin/bash set -e bindir=$(dirname $0) if [ -e "$1" ]; then exec swaybg --image "$1" --mode fill --output '*' elif [ -e "${bindir}/../share/backgrounds/miriway.png" ]; then exec swaybg --image "${bindir}/../share/backgrounds/miriway.png" --mode fill --output '*' else exec swaybg --color '#3f3f3f' --output '*' fi Miriway-Miriway-854d43d/miriway-run000077500000000000000000000015101521360756500173330ustar00rootroot00000000000000#!/bin/bash bindir=$(dirname "$0") if [ "${bindir}" != "" ]; then bindir="${bindir}/"; fi unset WAYLAND_DISPLAY port=0 while [ -e "${XDG_RUNTIME_DIR}/wayland-${port}" ]; do let port+=1 done wayland_display=wayland-${port} WAYLAND_DISPLAY=${wayland_display} MIR_SERVER_DISPLAY_AUTOSCALE=1200 "${bindir}"miriway-run-shell& miriway_pid=$! # Wait until the server starts until [ -O "${XDG_RUNTIME_DIR}/${wayland_display}" ] do if ! kill -0 ${miriway_pid} &> /dev/null then echo "ERROR: miriway-run-shell [pid=${miriway_pid}] is not running" exit 1 fi inotifywait -qq --timeout 5 --event create "$(dirname "${XDG_RUNTIME_DIR}/${wayland_display}")" done XDG_SESSION_TYPE=mir GDK_BACKEND=wayland,x11 QT_QPA_PLATFORM=wayland SDL_VIDEODRIVER=wayland WAYLAND_DISPLAY=${wayland_display} NO_AT_BRIDGE=1 "$@" kill $miriway_pid Miriway-Miriway-854d43d/miriway-run-shell.cpp000066400000000000000000000067561521360756500212370ustar00rootroot00000000000000/* * Copyright © 2024 Octopull Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Alan Griffiths */ #include #include #include #include #include #include #include #include using namespace miral; using namespace miral::toolkit; namespace { class MiralRunWM : public MinimalWindowManager { public: using MinimalWindowManager::MinimalWindowManager; void handle_request_move(WindowInfo& /*window_info*/, MirInputEvent const* /*input_event*/) override { // prevent window move } void handle_request_resize(WindowInfo& /*window_info*/, MirInputEvent const* /*input_event*/, MirResizeEdge /*edge*/) override { // prevent window resize } bool handle_pointer_event(MirPointerEvent const* event) override { // Override default handle_pointer_event() to ensure we don't allow dragging windows if (mir_pointer_event_action(event) == mir_pointer_action_button_down) { Point const cursor{ mir_pointer_event_axis_value(event, mir_pointer_axis_x), mir_pointer_event_axis_value(event, mir_pointer_axis_y)}; tools.select_active_window(tools.window_at(cursor)); } return false; } // Keep main window centered void handle_modify_window(WindowInfo& window_info, const WindowSpecification& new_modifications) override { if (new_modifications.size() && (window_info.type() == mir_window_type_normal || window_info.type() == mir_window_type_freestyle) && !window_info.parent() && new_modifications.state().value_or(window_info.state()) == mir_window_state_restored) { auto modifications = new_modifications; auto const output = tools.active_output(); modifications.top_left() = Point{ output.left() + (output.size.width - modifications.size().value().width)/2, output.top() + (output.size.height - modifications.size().value().height)/2}; MinimalWindowManager::handle_modify_window(window_info, modifications); } else { MinimalWindowManager::handle_modify_window(window_info, new_modifications); } } }; } int main(int argc, char const* argv[]) { MirRunner runner{argc, argv}; // Change the default Wayland extensions to enable everything miral::WaylandExtensions wayland_extensions; for (auto const& ext : wayland_extensions.all_supported()) wayland_extensions.enable(ext); return runner.run_with( { set_window_management_policy(), X11Support{}, wayland_extensions, display_configuration_options, Keymap{}, }); } Miriway-Miriway-854d43d/miriway-session.in000077500000000000000000000003561521360756500206260ustar00rootroot00000000000000#!/bin/bash -l exec systemd-cat --identifier=miriway env MIRIWAY_SESSION_STARTUP="@CMAKE_INSTALL_FULL_LIBEXECDIR@/miriway-session-startup" MIRIWAY_SESSION_SHUTDOWN="@CMAKE_INSTALL_FULL_LIBEXECDIR@/miriway-session-shutdown" miriway "$@" Miriway-Miriway-854d43d/miriway-shell.config000066400000000000000000000006551521360756500211100ustar00rootroot00000000000000x11-window-title=Miriway idle-timeout=600 ctrl-alt=t:miriway-terminal # Default "terminal emulator finder" app-env-amend=XDG_SESSION_TYPE=wayland:GTK_USE_PORTAL=0:XDG_CURRENT_DESKTOP=Miriway:GTK_A11Y=none:-GTK_IM_MODULE meta=Left:@dock-left meta=Right:@dock-right meta=Space:@toggle-maximized meta=Home:@workspace-begin meta=End:@workspace-end meta=Page_Up:@workspace-up meta=Page_Down:@workspace-down ctrl-alt=BackSpace:@exit Miriway-Miriway-854d43d/miriway-terminal000077500000000000000000000030561521360756500203510ustar00rootroot00000000000000#!/bin/sh set -xe for terminal in x-terminal-emulator xdg-terminal weston-terminal gnome-terminal do if terminal_command=$(command -v $terminal); then break; fi done case $(realpath "$terminal_command") in *gnome-terminal*) # gnome-terminal tries to run a single `gnome-terminal-server` process and any attempt # to launch a second instance appears on the desktop that owns the first terminal. # # What we do is launch the gnome-terminal-server with a distinct --app-id and, # after waiting for it to start, launch gnome-terminal with the same --app-id. # On Ubuntu 16.04 and 18.04 gnome-terminal-server is in /usr/lib/gnome-terminal # On Fedora and Ubuntu 20.04 gnome-terminal-server is in /usr/libexec/ # On Arch gnome-terminal-server is in /usr/lib/ for terminal_server in /usr/libexec/gnome-terminal-server /usr/lib/gnome-terminal/gnome-terminal-server /usr/lib/gnome-terminal-server do if [ -x "$terminal_server" ]; then break; fi done if ! gdbus introspect --session --dest io.mirserver.miriwayTerminal --object-path /io/mirserver/Terminal > /dev/null 2>&1 then $terminal_server --app-id io.mirserver.miriwayTerminal& gdbus wait --session io.mirserver.miriwayTerminal fi if command -v gnome-terminal.real > /dev/null 2>&1 then terminal=gnome-terminal.real else terminal=gnome-terminal fi exec $terminal --app-id io.mirserver.miriwayTerminal "$@";; *) # Other terminals default to running as a separate process, which suits us. exec $terminal "$@" esac Miriway-Miriway-854d43d/miriway-unsnap000077500000000000000000000004451521360756500200410ustar00rootroot00000000000000#! /bin/bash set -e if [ "$SNAP_NAME" == "miriway" ]; then unset __EGL_VENDOR_LIBRARY_DIRS unset GBM_BACKENDS_PATH unset LIBGL_DRIVERS_PATH unset LIBINPUT_QUIRKS_DIR unset DRIRC_CONFIGDIR unset XDG_DESKTOP_PORTAL_DIR PATH="$(echo "$PATH" | sed "s#$SNAP[^:]*:##g")" fi exec "$@" Miriway-Miriway-854d43d/miriway.cpp000066400000000000000000000617641521360756500173300ustar00rootroot00000000000000/* * Copyright © 2022 Octopull Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Alan Griffiths */ #include "miriway_app_switcher.h" #include "miriway_child_control.h" #include "miriway_commands.h" #include "miriway_documenting_store.h" #include "miriway_magnifier.h" #include "miriway_policy.h" #include "miriway_ext_workspace_v1.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace miral; using namespace miriway; namespace { auto to_key(std::string_view as_string) -> xkb_keysym_t { if (auto const result = xkb_keysym_from_name(as_string.data(), XKB_KEYSYM_CASE_INSENSITIVE); result != XKB_KEY_NoSymbol) { return result; } throw mir::AbnormalExit((std::string{ "Unrecognised key in config: "} + as_string.data()).c_str()); } std::map const wm_command = { { "dock-left", [](ShellCommands* sc, bool shift) { sc->dock_active_window_left(shift); } }, { "dock-right", [](ShellCommands* sc, bool shift) { sc->dock_active_window_right(shift); } }, { "toggle-maximized", [](ShellCommands* sc, bool shift) { sc->toggle_maximized_restored(shift); } }, { "toggle-always-on-top", [](ShellCommands* sc, bool shift) { sc->toggle_always_on_top(shift); } }, { "workspace-begin", [](ShellCommands* sc, bool shift) { sc->workspace_begin(shift); } }, { "workspace-end", [](ShellCommands* sc, bool shift) { sc->workspace_end(shift); } }, { "workspace-up", [](ShellCommands* sc, bool shift) { sc->workspace_up(shift); } }, { "workspace-down", [](ShellCommands* sc, bool shift) { sc->workspace_down(shift); } }, { "exit", [](ShellCommands* sc, bool shift) { sc->exit(shift); } }, }; // Build a list of shell components from "" values and launch them all after startup struct ShellComponents { explicit ShellComponents(std::function const& command_line)> launch) : launch{std::move(launch)}{} void populate(std::vector const& cmds) { std::transform(begin(cmds), end(cmds), back_inserter(commands), ExternalClientLauncher::split_command); } void launch_all() const { for (auto const& command : commands) { launch(command); } } private: std::function const& command_line)> const launch; std::vector> commands; }; class LockScreen { public: explicit LockScreen( std::function const& command_line)> launch, std::function const& conditionally_enable) : launch{std::move(launch)}, lockscreen_option{[this](mir::optional_value const& app) { if (app.is_set()) { lockscreen_app = ExternalClientLauncher::split_command(app.value()); } }, "lockscreen-app", "Lockscreen app to be triggered when the compositor session is locked" }, lockscreen_on_idle{[this](bool on) { if (on) idle_listener.on_off([this]() { launch_lockscreen(); }); }, "lockscreen-on-idle", "Trigger lockscreen on idle timeout", true } { conditionally_enable(WaylandExtensions::ext_session_lock_manager_v1); } void operator()(mir::Server& server) const { lockscreen_option(server); session_locker(server); lockscreen_on_idle(server); idle_listener(server); } private: void launch_lockscreen() const { if (lockscreen_app) launch(lockscreen_app.value()); } std::function const& command_line)> const launch; ConfigurationOption const lockscreen_option; SessionLockListener const session_locker{ [this]{ launch_lockscreen(); }, [] {} }; std::optional> lockscreen_app; ConfigurationOption const lockscreen_on_idle; IdleListener idle_listener; }; // Build an index of commands from ":" values and launch them by (if found) class CommandIndex { public: CommandIndex( live_config::Store& store, std::string const& option, std::string const& description, std::function const&)> launch) : launch{std::move(launch)} { auto settings_key = option; std::replace(settings_key.begin(), settings_key.end(), '-', '_'); store.add_strings_attribute( live_config::Key{{"command", settings_key}}, "command " + description, [this](live_config::Key const&, std::optional> value) { commands.clear(); if (value) populate(std::vector(value->begin(), value->end())); }); } bool try_command_for(xkb_keysym_t key_code, bool with_shift, ShellCommands* cmd) const { auto const i = commands.find(xkb_keysym_to_lower(key_code)); bool const found = i != end(commands); if (found) i->second(cmd, with_shift); return found; } private: std::function const& command_line)> const launch; mutable std::map commands; void populate(std::vector const& config_cmds) const { for (auto const& command : config_cmds) { if (auto const split = command.find(':'); split >= 1 && split+1 < command.size()) { auto const key = xkb_keysym_to_lower(to_key(command.substr(0, split))); if (command[split+1] != '@') { commands[key] = [this, argv = ExternalClientLauncher::split_command(command.substr(split+1))](miriway::ShellCommands*, bool) { launch(argv); }; } else { if (auto const lookup = wm_command.find(command.substr(split+2)); lookup != std::end(wm_command)) { commands[key] = lookup->second; } } } else { mir::fatal_error("Invalid command option: %s", command.c_str()); } } } }; inline auto config_path(std::filesystem::path path) { auto const basename = path.filename() += ".config"; auto const miriway_shell = getenv("MIRIWAY_CONFIG_DIR"); return miriway_shell ? std::filesystem::path(miriway_shell) / basename : basename; } // Migrate options from .config to .settings if not already present. void migrate_config_to_settings(std::filesystem::path const& config_file_path, std::filesystem::path const& settings_file_path) { static std::pair const options[] = { {"shell-meta", "command_shell_meta"}, {"shell-ctrl-alt", "command_shell_ctrl_alt"}, {"shell-alt", "command_shell_alt"}, {"meta", "command_meta"}, {"ctrl-alt", "command_ctrl_alt"}, {"alt", "command_alt"}, {"shell-plain", "command_shell_plain"}, {"plain", "command_plain"}, {"cursor-scale", "cursor_scale"}, {"keymap", "keymap"}, {"key-repeat-rate", "keyboard_repeat_rate"}, {"key-repeat-delay", "keyboard_repeat_delay"}, {"mouse-handedness", "pointer_handedness"}, {"mouse-cursor-acceleration", "pointer_acceleration"}, {"mouse-cursor-acceleration-bias", "pointer_acceleration_bias"}, {"mouse-scroll-speed", "pointer_vertical_scroll_speed"}, {"mouse-horizontal-scroll-speed-override", "pointer_horizontal_scroll_speed"}, {"mouse-vertical-scroll-speed-override", "pointer_vertical_scroll_speed"}, {"touchpad-disable-while-typing", "touchpad_disable_while_typing"}, {"touchpad-disable-with-external-mouse", "touchpad_disable_with_external_mouse"}, {"touchpad-tap-to-click", "touchpad_tap_to_click"}, {"touchpad-cursor-acceleration", "touchpad_acceleration"}, {"touchpad-cursor-acceleration-bias", "touchpad_acceleration_bias"}, {"touchpad-scroll-speed", "touchpad_vertical_scroll_speed"}, {"touchpad-horizontal-scroll-speed-override","touchpad_horizontal_scroll_speed"}, {"touchpad-vertical-scroll-speed-override", "touchpad_vertical_scroll_speed"}, {"touchpad-scroll-mode", "touchpad_scroll_mode"}, {"touchpad-click-mode", "touchpad_click_mode"}, {"touchpad-middle-mouse-button-emulation", "touchpad_middle_mouse_button_emulation"}, }; // Read the settings file into memory, collecting active keys as we go std::vector settings_lines; std::set existing_keys; if (std::ifstream settings{settings_file_path}) { std::string line; while (std::getline(settings, line)) { settings_lines.push_back(line); if (!line.empty() && line[0] != '#') { if (auto const eq = line.find('='); eq != std::string::npos) existing_keys.insert(line.substr(0, eq)); } } } // Collect values from .config for keys absent from .settings std::map> to_migrate; if (std::ifstream config{config_file_path}) { std::string line; while (std::getline(config, line)) { for (auto const& [config_name, settings_name] : options) { if (existing_keys.count(settings_name)) continue; if (line.rfind(config_name + "=", 0) == 0) { auto value = line.substr(config_name.size() + 1); // .config supports # comments; IniFile does not — strip any inline comment if (auto const comment = value.find('#'); comment != std::string::npos) value.erase(comment); // trim trailing whitespace left after comment removal if (auto const end = value.find_last_not_of(" \t"); end != std::string::npos) value.erase(end + 1); else value.clear(); if (!value.empty()) to_migrate[settings_name].push_back(std::move(value)); } } } } if (to_migrate.empty()) return; // For each entry to migrate, look for a commented-out placeholder "#=" in the // settings lines and insert the value(s) immediately after it. Entries without a // placeholder are collected separately and appended at the end. std::map> to_append; for (auto const& [settings_name, values] : to_migrate) { std::string const placeholder = "#" + settings_name + "="; bool inserted = false; for (std::size_t i = 0; i < settings_lines.size(); ++i) { if (settings_lines[i].rfind(placeholder, 0) == 0) { for (std::size_t j = 0; j < values.size(); ++j) settings_lines.insert(settings_lines.begin() + static_cast(i + 1 + j), settings_name + "=" + values[j]); inserted = true; break; } } if (!inserted) to_append[settings_name] = values; } if (!to_append.empty()) { settings_lines.push_back(""); settings_lines.push_back("# Migrated from " + config_file_path.filename().string()); for (auto const& [settings_name, values] : to_append) for (auto const& value : values) settings_lines.push_back(settings_name + "=" + value); } if (std::ofstream settings{settings_file_path}) { for (auto const& line : settings_lines) settings << line << "\n"; } } auto const config_home = []() -> std::filesystem::path { if (auto config_home = getenv("XDG_CONFIG_HOME")) { return config_home; } else if (auto home = getenv("HOME")) { return std::filesystem::path(home) / ".config"; } return "/dev/null"; }(); auto find_config_file(std::string const& config_file_name) -> std::optional { if (auto const miriway_config_dir = getenv("MIRIWAY_CONFIG_DIR")) { auto const path = std::filesystem::path{miriway_config_dir} / config_file_name; if (std::filesystem::exists(path)) return path; } auto const home_path = config_home / config_file_name; if (std::filesystem::exists(home_path)) return home_path; char const* xdg_config_dirs = getenv("XDG_CONFIG_DIRS"); std::string const config_dirs = xdg_config_dirs ? xdg_config_dirs : "/etc/xdg"; std::stringstream ss(config_dirs); std::string dir; while (std::getline(ss, dir, ':')) { if (dir.empty()) continue; auto const path = std::filesystem::path{dir} / config_file_name; std::error_code ec; if (std::filesystem::exists(path, ec)) return path; } return std::nullopt; } auto getenv_decorations() { if (auto const strategy = getenv("MIRIWAY_DECORATIONS")) { if (strcmp(strategy, "always-ssd") == 0) return Decorations::always_ssd(); if (strcmp(strategy, "prefer-ssd") == 0) return Decorations::prefer_ssd(); if (strcmp(strategy, "always-csd") == 0) return Decorations::always_csd(); if (strcmp(strategy, "prefer-csd") == 0) return Decorations::prefer_csd(); mir::log_warning("Miriway [Warning]: Unknown decoration strategy: %s, using prefer-csd", strategy); } return Decorations::prefer_csd(); } } int main(int argc, char const* argv[]) { MirRunner runner{argc, argv, config_path(argv[0]).c_str()}; // Change the default Wayland extensions to: // 1. to enable screen capture; and, // 2. to allow pointer confinement (used by, for example, games) // Because we prioritise `user_preference()` these can be disabled by the configuration WaylandExtensions extensions; for (auto const& protocol : { WaylandExtensions::zwlr_screencopy_manager_v1, WaylandExtensions::zxdg_output_manager_v1, "zwp_idle_inhibit_manager_v1", "zwp_pointer_constraints_v1", "zwp_relative_pointer_manager_v1"}) { extensions.conditionally_enable(protocol, [&](WaylandExtensions::EnableInfo const& info) { return info.user_preference().value_or(true); }); } // Workaround for Firefox C&P failing if the (unrelated) wp-primary-selection isn't enabled // https://bugzilla.mozilla.org/show_bug.cgi?id=1791417 extensions.conditionally_enable("zwp_primary_selection_device_manager_v1", [&](WaylandExtensions::EnableInfo const& info) { if (std::ifstream cmdline{"/proc/" + std::to_string(miral::pid_of(info.app())) + "/cmdline"}) { std::filesystem::path const path{std::istreambuf_iterator{cmdline}, std::istreambuf_iterator{}}; auto filename = path.filename().string(); if (auto const eos = filename.find('\0'); eos != std::string::npos) { filename.erase(eos); return info.user_preference().value_or(filename == "firefox"); } } return info.user_preference().value_or(false); }); ChildControl child_control(runner); WaylandTools wltools; extensions.add_extension_disabled_by_default(build_ext_workspace_v1_global(wltools)); child_control.enable_for_shell(extensions, ext_workspace_v1_name()); // Protocols we're reserving for shell components_option for (auto const& protocol : { WaylandExtensions::zwlr_layer_shell_v1, WaylandExtensions::zwlr_foreign_toplevel_manager_v1}) { child_control.enable_for_shell(extensions, protocol); } auto const enable_shell_extensions = [&](std::vector const& protocols) { for (auto const& protocol : protocols) child_control.enable_for_shell(extensions, protocol); }; ConfigurationOption shell_extension{ enable_shell_extensions, "shell-add-wayland-extension", "Additional Wayland extension to allow shell processes (may be specified multiple times)"}; ShellComponents shell_components{[&child_control](auto const& cmd) { child_control.launch_shell(cmd); }}; runner.add_start_callback([&]{ shell_components.launch_all(); }); ConfigurationOption components_option{ [&](std::vector const& apps) { shell_components.populate(apps); }, "shell-component", "Shell component to launch on startup (may be specified multiple times)"}; using miriway::Magnifier; // We want our Magnifier not the miral Magnifier auto const settings_file = std::filesystem::path{runner.config_file()}.replace_extension("settings"); // Migrate any shell command settings from .config to .settings before registering if (auto const config_file_path = find_config_file(runner.config_file())) { migrate_config_to_settings(config_file_path.value(), config_home / settings_file); } live_config::IniFile config_store; auto settings_store = std::make_unique(config_store, config_home / settings_file); CursorScale cursor_scale{*settings_store}; OutputFilter output_filter{*settings_store}; Magnifier magnifier{*settings_store}; InputConfiguration input_configuration{*settings_store}; BounceKeys bounce_keys{*settings_store}; SlowKeys slow_keys{*settings_store}; StickyKeys sticky_keys{*settings_store}; HoverClick hover_click{*settings_store}; // Register shell command options with the settings store // corresponding configuration options. These processes are added to `shell_pids` CommandIndex shell_meta{ *settings_store, "shell-meta", "meta : shortcut with shell privileges (may be specified multiple times)", [&child_control](auto cmd) { child_control.run_shell(cmd); }}; CommandIndex shell_ctrl_alt{ *settings_store, "shell-ctrl-alt", "ctrl-alt : shortcut with shell privileges (may be specified multiple times)", [&child_control](auto cmd) { child_control.run_shell(cmd); }}; CommandIndex shell_alt{ *settings_store, "shell-alt", "alt : shortcut with shell privileges (may be specified multiple times)", [&child_control](auto cmd) { child_control.run_shell(cmd); }}; // `meta`, `alt` and `ctrl_alt` provide a lookup to execute the commands configured by the corresponding // configuration options. These processes are NOT added to `shell_pids` CommandIndex meta{ *settings_store, "meta", "meta : shortcut (may be specified multiple times)", [&](auto cmd) { child_control.run_app(cmd); }}; CommandIndex ctrl_alt{ *settings_store, "ctrl-alt", "ctrl-alt : shortcut (may be specified multiple times)", [&](auto cmd) { child_control.run_app(cmd); }}; CommandIndex alt{ *settings_store, "alt", "alt : shortcut (may be specified multiple times)", [&](auto cmd) { child_control.run_app(cmd); }}; CommandIndex shell_plain{ *settings_store, "shell-plain", "unmodified : shortcut with shell privileges (may be specified multiple times)", [&child_control](auto cmd) { child_control.run_shell(cmd); }}; CommandIndex plain{ *settings_store, "plain", "unmodified : shortcut (may be specified multiple times)", [&](auto cmd) { child_control.run_app(cmd); }}; Keymap keymap = getenv("MIRIWAY_SYSTEM_LOCALE1_KEYMAP") ? Keymap::system_locale1() : Keymap{*settings_store}; settings_store.reset(); ConfigFile config_file{ runner, settings_file, ConfigFile::Mode::reload_on_change, [&config_store](auto&... args){ config_store.load_file(args...); }}; // Process input events to identifies commands Miriway needs to handle ShellCommands commands{ runner, [&] (xkb_keysym_t c, bool s, ShellCommands* cmd) { return shell_meta.try_command_for(c, s, cmd) || meta.try_command_for(c, s, cmd); }, [&] (xkb_keysym_t c, bool s, ShellCommands* cmd) { return shell_ctrl_alt.try_command_for(c, s, cmd) || ctrl_alt.try_command_for(c, s, cmd); }, [&] (xkb_keysym_t c, bool s, ShellCommands* cmd) { return shell_alt.try_command_for(c, s, cmd) || alt.try_command_for(c, s, cmd); }, [&] (xkb_keysym_t c, bool s, ShellCommands* cmd) { return shell_plain.try_command_for(c, s, cmd) || plain.try_command_for(c, s, cmd); }}; #ifdef MIRIWAY_USE_APP_SWITCHER AppSwitcher app_switcher; #endif std::atomic is_locked = false; LockScreen lockscreen( [&child_control, &is_locked](auto const& cmd) { child_control.launch_shell(cmd, [&is_locked]() { return is_locked.load(); }); }, [&extensions, &child_control](auto protocol) { child_control.enable_for_shell(extensions, protocol); }); runner.add_start_callback([&child_control] { if (auto const miriway_session_startup = getenv("MIRIWAY_SESSION_STARTUP")) { child_control.run_app({miriway_session_startup}); } }); runner.add_stop_callback([&child_control] { if (auto const miriway_session_shutdown = getenv("MIRIWAY_SESSION_SHUTDOWN")) { child_control.run_app({miriway_session_shutdown}); } }); return runner.run_with( { X11Support{}, pre_init(shell_extension), extensions, display_configuration_options, child_control, components_option, keymap, AppendEventFilter{[&](MirEvent const* e) { if (is_locked) return false; #ifdef MIRIWAY_USE_APP_SWITCHER if (commands.shell_keyboard_enabled() && app_switcher.process_event(e)) return true; #endif return commands.input_event(e); }}, SessionLockListener( [&] { is_locked = true; }, [&] { is_locked = false; }), set_window_management_policy(commands), lockscreen, getenv_decorations(), CursorTheme{"default"}, wltools, cursor_scale, output_filter, input_configuration, bounce_keys, slow_keys, sticky_keys, hover_click, magnifier, #ifdef MIRIWAY_USE_APP_SWITCHER app_switcher, #endif }); } Miriway-Miriway-854d43d/miriway.desktop000066400000000000000000000002021521360756500201730ustar00rootroot00000000000000[Desktop Entry] Name=Miriway Comment=Mir/Wayland desktop environment Exec=miriway-session Type=Application TryExec=miriway-sessionMiriway-Miriway-854d43d/miriway_app_switcher.cpp000066400000000000000000000140431521360756500220640ustar00rootroot00000000000000/* * Copyright © 2024 Octopull Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Alan Griffiths */ #include "miriway_app_switcher.h" #include #include #include #include #include #include using namespace miral::toolkit; class miriway::AppSwitcher::Self { public: struct KeybindConfiguration { /// This is the modifier that must be held for any application switcher /// action to begin. /// /// Defaults to #mir_input_event_modifier_alt. MirInputEventModifier primary_modifier = mir_input_event_modifier_alt; /// This is the modifier that must be held alongside the primary modifier /// in order to reverse the direction of an action being run. For example, /// holding the primary modifier and hitting the application key will select /// the next application, while holding both the primary and reverse modifiers /// and hitting the application will select the previous application. /// /// Defaults to #mir_input_event_modifier_shift. MirInputEventModifier reverse_modifier = mir_input_event_modifier_shift; /// This is the key that must be clicked in order to trigger either /// #ApplicationSwitcher::next_app or #ApplicationSwitcher::prev_app, /// depending on the modifiers that are currently being held. /// /// Defaults to KEY_TAB. int application_key = KEY_TAB; /// This is the key that must be clicked in order to trigger either /// #ApplicationSwitcher::next_window or #ApplicationSwitcher::prev_window, /// depending on the modifiers that are currently being held. /// /// Defaults to KEY_GRAVE. int window_key = KEY_GRAVE; /// This is the key that must be clicked in order cancel the ///#ApplicationSwitcher /// /// Defaults to KEY_ESC. int escape_key = KEY_ESC; }; explicit Self(KeybindConfiguration const& keybind_configuration) : keybind_configuration{keybind_configuration}, startup_internal_client{switcher, switcher, [switcher=switcher] { switcher.stop(); }} { } void operator()(mir::Server& server) { startup_internal_client(server); } bool process_event(MirEvent const* event) { if (mir_event_get_type(event) != mir_event_type_input) return false; auto const* input_event = mir_event_get_input_event(event); if (mir_input_event_get_type(input_event) != mir_input_event_type_key) return false; auto const key_event = mir_input_event_get_keyboard_event(input_event); auto const modifiers = mir_keyboard_event_modifiers(key_event); if (mir_keyboard_event_action(key_event) == mir_keyboard_action_down) { auto const scancode = mir_keyboard_event_scan_code(key_event); if (is_running && scancode == keybind_configuration.escape_key) { switcher.cancel(); is_running = false; return true; } if (modifiers & keybind_configuration.primary_modifier) { if (modifiers & keybind_configuration.reverse_modifier) { if (scancode == keybind_configuration.application_key) { switcher.prev_app(); is_running = true; return true; } else if (scancode == keybind_configuration.window_key) { switcher.prev_window(); is_running = true; return true; } } else { if (scancode == keybind_configuration.application_key) { switcher.next_app(); is_running = true; return true; } else if (scancode == keybind_configuration.window_key) { switcher.next_window(); is_running = true; return true; } } } } else if (is_running && miral::toolkit::mir_keyboard_event_action(key_event) == mir_keyboard_action_up) { if (!(modifiers & keybind_configuration.primary_modifier)) { switcher.confirm(); is_running = false; return true; } } return false; } const KeybindConfiguration keybind_configuration; miral::ApplicationSwitcher switcher; miral::StartupInternalClient startup_internal_client; std::atomic is_running = false; }; miriway::AppSwitcher::AppSwitcher() : self{std::make_shared(Self::KeybindConfiguration{ .primary_modifier = mir_input_event_modifier_alt, .reverse_modifier = mir_input_event_modifier_shift, .application_key = KEY_TAB, .window_key = KEY_GRAVE, .escape_key = KEY_ESC })} { } void miriway::AppSwitcher::operator()(mir::Server& server) { self->operator()(server); } bool miriway::AppSwitcher::process_event(MirEvent const* event) { return self->process_event(event); } Miriway-Miriway-854d43d/miriway_app_switcher.h000066400000000000000000000020541521360756500215300ustar00rootroot00000000000000/* * Copyright © 2024 Octopull Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Alan Griffiths */ #ifndef MIRIWAY_APP_SWITCHER_H #define MIRIWAY_APP_SWITCHER_H #include struct MirEvent; namespace mir { class Server; } namespace miriway { class AppSwitcher { public: AppSwitcher(); void operator()(mir::Server& server); bool process_event(MirEvent const* event); private: class Self; std::shared_ptr self; }; } #endif //MIRIWAY_APP_SWITCHER_H Miriway-Miriway-854d43d/miriway_child_control.cpp000066400000000000000000000227711521360756500222260ustar00rootroot00000000000000/* * Copyright © 2024 Octopull Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Alan Griffiths */ #include "miriway_child_control.h" #include #include #include #include #include #include #include #include #include #include #include class miriway::ChildControl::Self { public: explicit Self(MirRunner& runner) : runner{runner}, shell_pids{runner} { runner.add_stop_callback([this]{ shell_pids.shutdown(); }); } void enable_for_shell(WaylandExtensions& extensions, std::string const& protocol) { extensions.conditionally_enable(protocol, enable_for_shell_pids); } struct ShellComponentRunInfo { ShellComponentRunInfo() : ShellComponentRunInfo{[]() { return true; }} {} explicit ShellComponentRunInfo(std::function const should_restart_predicate) : should_restart_predicate{std::move(should_restart_predicate)} {} time_t last_run_time = 0; int runs_in_quick_succession = 0; std::unique_ptr handle = nullptr; std::function const should_restart_predicate; }; // Keep track of interesting "shell" child processes and call the corresponding // `on_reap` if they fail. Note that it will "reap" all child processes not just // the ones of interest. (But that's useful as it avoids "zombie" child processes.) struct ShellPids { ShellPids(MirRunner& runner) { runner.add_start_callback([&] { runner.register_signal_handler({SIGCHLD}, [this](int) { reap(); }); }); } using OnReap = std::function; void insert(pid_t pid, OnReap on_reap = [](){}) { std::lock_guard lock{shell_component_mutex}; shell_component_pids.insert(std::pair(pid, on_reap)); }; bool is_found(pid_t pid) const { std::lock_guard lock{shell_component_mutex}; return shell_component_pids.find(pid) != end(shell_component_pids); } void shutdown() { std::lock_guard lock{shell_component_mutex}; for (auto [pid, _] : shell_component_pids) { kill(pid, SIGTERM); } shell_component_pids.clear(); } private: std::mutex mutable shell_component_mutex; std::map shell_component_pids; void reap() { int status = 0; while (true) { auto const pid = waitpid(-1, &status, WNOHANG); if (pid > 0) { OnReap on_reap = [](){}; { std::lock_guard lock{shell_component_mutex}; if (auto it = shell_component_pids.find(pid); it != shell_component_pids.end()) { if ((WIFEXITED(status) && WEXITSTATUS(status)) || (WIFSIGNALED(status) && WTERMSIG(status))) { on_reap = it->second; } shell_component_pids.erase(pid); } } on_reap(); } else { break; } } } }; MirRunner& runner; // To support docks, onscreen keyboards, launchers and the like; enable a number of protocol extensions, // but, because they have security implications only for those applications found in `shell_pids`. // We'll use `shell_pids` to track "shell-*" processes. // We also check `user_preference()` so these can be enabled by the configuration ShellPids shell_pids; ExternalClientLauncher client_launcher; std::function const enable_for_shell_pids = [this](WaylandExtensions::EnableInfo const& info) { pid_t const pid = pid_of(info.app()); return shell_pids.is_found(pid) || info.user_preference().value_or(false); }; // A configuration option to start applications when compositor starts and record them in `shell_pids`. // Because of the previous section, this allows them some extra Wayland extensions std::function const&, std::shared_ptr)> shell_launch = [&](std::vector const& cmd, std::shared_ptr info) { static int constexpr min_time_seconds_allowed_between_runs = 3; static int constexpr time_seconds_wait_foreach_run = 3; static int const max_too_short_reruns_in_a_row = 3; static auto const get_cmd_string = [](std::vector const& cmd) { return std::accumulate(std::begin(cmd), std::end(cmd), std::string(), [](std::string const& current, std::string const& next) { return current.empty() ? next : current + " " + next; }); }; time_t const now = std::time(nullptr); auto const time_elapsed_since_last_run = now - info->last_run_time; if (time_elapsed_since_last_run <= min_time_seconds_allowed_between_runs) { // The command is trying to restart too soon, so we throttle it. For every premature // death that it has in a row, we increasingly throttle its restart time. // After max_too_short_reruns_in_a_row is hit, we stop trying to rerun if (info->runs_in_quick_succession >= max_too_short_reruns_in_a_row) { mir::log_warning("No longer restarting app: %s", get_cmd_string(cmd).c_str()); return; } auto const time_to_wait = time_seconds_wait_foreach_run * (info->runs_in_quick_succession + 1); auto const timer_fd = timerfd_create(CLOCK_REALTIME, 0); if (timer_fd == -1) { mir::log_error("timerfd_create failed, unable to restart application: %s", get_cmd_string(cmd).c_str()); return; } auto const spec = itimerspec { { 0, 0 }, // Timer interval { time_to_wait, 0 } // Initial expiration }; if (timerfd_settime(timer_fd, 0, &spec, NULL) == -1) { mir::log_error("timerfd_settime failed, unable to restart application: %s", get_cmd_string(cmd).c_str()); return; } info->handle = runner.register_fd_handler(mir::Fd{timer_fd}, [info, this, &cmd](int){ // While waiting for the timer, the predicate could have a different value if (!info->should_restart_predicate()) return; info->handle.reset(); info->runs_in_quick_succession++; info->last_run_time = std::time(nullptr); shell_pids.insert(client_launcher.launch(cmd), [this, info, &cmd] { if (info->should_restart_predicate()) shell_launch(cmd, info); }); }); return; } else { info->runs_in_quick_succession = 0; info->last_run_time = now; shell_pids.insert(client_launcher.launch(cmd), [this, info, &cmd] { if (info->should_restart_predicate()) shell_launch(cmd, info); }); } }; }; miriway::ChildControl::ChildControl(MirRunner& runner) : self{std::make_shared(runner)} { } void miriway::ChildControl::operator()(mir::Server& server) { self->client_launcher(server); } void miriway::ChildControl::launch_shell(std::vector const& cmd) { self->shell_launch(cmd, std::make_shared()); } void miriway::ChildControl::launch_shell(std::vector const& cmd, std::function const should_restart_predicate) { self->shell_launch(cmd, std::make_shared(should_restart_predicate)); } void miriway::ChildControl::run_shell(std::vector const& cmd) { self->shell_pids.insert(self->client_launcher.launch(cmd)); } void miriway::ChildControl::run_app(std::vector const& cmd) { self->client_launcher.launch(cmd); } void miriway::ChildControl::enable_for_shell(WaylandExtensions& extensions, std::string const& protocol) { extensions.conditionally_enable(protocol, self->enable_for_shell_pids); } Miriway-Miriway-854d43d/miriway_child_control.h000066400000000000000000000030211521360756500216560ustar00rootroot00000000000000/* * Copyright © 2024 Octopull Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Alan Griffiths */ #ifndef MIRIWAY_CHILD_CONTROL_H #define MIRIWAY_CHILD_CONTROL_H #include #include #include #include namespace mir { class Server; } namespace miral { class MirRunner; class WaylandExtensions; } namespace miriway { using namespace miral; class ChildControl { public: explicit ChildControl(MirRunner& runner); void operator()(mir::Server& server); void launch_shell(std::vector const& cmd); void launch_shell(std::vector const& cmd, std::function const should_restart_predicate); void run_shell(std::vector const& cmd); void run_app(std::vector const& cmd); void enable_for_shell(WaylandExtensions& extensions, std::string const& protocol); private: class Self; std::shared_ptr self; }; } #endif //MIRIWAY_CHILD_CONTROL_H Miriway-Miriway-854d43d/miriway_commands.cpp000066400000000000000000000115451521360756500212010ustar00rootroot00000000000000/* * Copyright © 2022 Octopull Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Alan Griffiths */ #include "miriway_commands.h" #include "miriway_policy.h" #include #include #include #include miriway::ShellCommands::ShellCommands( MirRunner& runner, CommandFunctor meta_command, CommandFunctor ctrl_alt_command, CommandFunctor alt_command, CommandFunctor key_command) : runner{runner}, meta_command{std::move(meta_command)}, ctrl_alt_command{std::move(ctrl_alt_command)}, alt_command{std::move(alt_command)}, key_command{std::move(key_command)} { } void miriway::ShellCommands::advise_new_window_for(miral::Application const& /*app*/) { std::lock_guard lock{mutex}; ++app_windows; } void miriway::ShellCommands::advise_delete_window_for(miral::Application const& /*app*/) { std::lock_guard lock{mutex}; --app_windows; } auto miriway::ShellCommands::keyboard_shortcuts(MirKeyboardEvent const* kev) -> bool { if (mir_keyboard_event_action(kev) == mir_keyboard_action_up) return false; auto const mods = mir_keyboard_event_modifiers(kev); auto const key_code = mir_keyboard_event_keysym(kev); auto const ctrl_alt = mir_input_event_modifier_alt | mir_input_event_modifier_ctrl; if ((mods & ctrl_alt) == ctrl_alt) { if (key_code == XKB_KEY_Delete && mir_keyboard_event_action(kev) == mir_keyboard_action_down) { shell_commands_active = !shell_commands_active; return true; } } if (!shell_commands_active) return false; if (mir_keyboard_event_action(kev) == mir_keyboard_action_down) { if ((mods & ctrl_alt) == ctrl_alt) { return ctrl_alt_command(key_code, mods & mir_input_event_modifier_shift, this); } if ((mods & mir_input_event_modifier_meta) == mir_input_event_modifier_meta) { return meta_command(key_code, mods & mir_input_event_modifier_shift, this); } if ((mods & mir_input_event_modifier_alt) == mir_input_event_modifier_alt) { return alt_command(key_code, mods & mir_input_event_modifier_shift, this); } auto const real_mods = mir_input_event_modifier_alt | mir_input_event_modifier_shift | mir_input_event_modifier_ctrl | mir_input_event_modifier_meta; if (!(mods & real_mods)) { return key_command(key_code, false, this); } } return false; } auto miriway::ShellCommands::touch_shortcuts(MirTouchEvent const* /*tev*/) -> bool { return false; } auto miriway::ShellCommands::input_event(MirEvent const* event) -> bool { if (mir_event_get_type(event) != mir_event_type_input) return false; auto const* input_event = mir_event_get_input_event(event); switch (mir_input_event_get_type(input_event)) { case mir_input_event_type_touch: return touch_shortcuts(mir_input_event_get_touch_event(input_event)); case mir_input_event_type_key: return keyboard_shortcuts(mir_input_event_get_keyboard_event(input_event)); default: return false; } } void miriway::ShellCommands::init_window_manager(WindowManagerPolicy* wm) { this->wm = wm; } void miriway::ShellCommands::dock_active_window_left(bool shift) const { wm->dock_active_window_left(shift); } void miriway::ShellCommands::dock_active_window_right(bool shift) const { wm->dock_active_window_right(shift); } void miriway::ShellCommands::toggle_maximized_restored(bool) const { wm->toggle_maximized_restored(); } void miriway::ShellCommands::toggle_always_on_top(bool) const { wm->toggle_always_on_top(); } void miriway::ShellCommands::workspace_begin(bool shift) const { wm->workspace_begin(shift); } void miriway::ShellCommands::workspace_end(bool shift) const { wm->workspace_end(shift); } void miriway::ShellCommands::workspace_up(bool shift) const { wm->workspace_up(shift); } void miriway::ShellCommands::workspace_down(bool shift) const { wm->workspace_down(shift); } void miriway::ShellCommands::exit(bool shift) const { std::lock_guard lock{mutex}; if (app_windows == 0 || shift) { runner.stop(); } } Miriway-Miriway-854d43d/miriway_commands.h000066400000000000000000000054211521360756500206420ustar00rootroot00000000000000/* * Copyright © 2022 Octopull Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Alan Griffiths */ #ifndef MIRIWAY_COMMANDS_H #define MIRIWAY_COMMANDS_H #include #include #include #include #include #include #include using namespace miral::toolkit; namespace miral { class MirRunner; class ExternalClientLauncher; } namespace miriway { using namespace miral; class WindowManagerPolicy; // Process `input_event()` to identify commands Miriway needs to handle. // Commands will be routed to MirRunner, the WindowManagerPolicy, or a CommandFunctor as appropriate class ShellCommands { public: using CommandFunctor = std::function; ShellCommands(MirRunner& runner, CommandFunctor meta_command, CommandFunctor ctrl_alt_command, CommandFunctor alt_command, CommandFunctor key_command); void init_window_manager(WindowManagerPolicy* wm); void advise_new_window_for(Application const& app); void advise_delete_window_for(Application const& app); auto input_event(MirEvent const* event) -> bool; [[nodiscard]] auto shell_keyboard_enabled() const -> bool { return shell_commands_active; } using CmdFunctor = std::function; void dock_active_window_left(bool shift) const; void dock_active_window_right(bool shift) const; void toggle_maximized_restored(bool shift) const; void toggle_always_on_top(bool shift) const; void workspace_begin(bool shift) const; void workspace_end(bool shift) const; void workspace_up(bool shift) const; void workspace_down(bool shift) const; void exit(bool shift) const; private: auto keyboard_shortcuts(MirKeyboardEvent const* kev) -> bool; auto touch_shortcuts(MirTouchEvent const* tev) -> bool; MirRunner& runner; CommandFunctor meta_command; CommandFunctor ctrl_alt_command; CommandFunctor alt_command; CommandFunctor key_command; WindowManagerPolicy* wm = nullptr; std::atomic shell_commands_active = true; std::mutex mutable mutex; int app_windows = 0; }; } #endif //MIRIWAY_COMMANDS_H Miriway-Miriway-854d43d/miriway_documenting_store.cpp000066400000000000000000000170131521360756500231240ustar00rootroot00000000000000/* * Copyright © Alan Griffiths * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Alan Griffiths */ #include "miriway_documenting_store.h" #include miriway::DocumentingStore::DocumentingStore(Store& underlying, std::filesystem::path target) : underlying{underlying} { if (std::ifstream settings{target}) { std::string line; while (std::getline(settings, line)) { if (line.empty()) continue; if (line[0] != '#') { if (auto const eq = line.find('='); eq != std::string::npos) existing_keys.insert(line.substr(0, eq)); } else { // Also track commented out keys to avoid duplicating them auto const content = line.substr(1); if (auto const eq = content.find('='); eq != std::string::npos) { existing_keys.insert(content.substr(0, eq)); } } } doc.open(target, std::ios::app); } else { doc.open(target); } } void miriway::DocumentingStore::add_int_attribute(const live_config::Key& key, std::string_view description, HandleInt handler) { if (!existing_keys.count(key.to_string())) { doc << "# int: " << description << '\n'; doc << "#" << key.to_string() << "=\n\n"; doc.flush(); } underlying.add_int_attribute(key, description, handler); } void miriway::DocumentingStore::add_ints_attribute(const live_config::Key& key, std::string_view description, HandleInts handler) { if (!existing_keys.count(key.to_string())) { doc << "# int[]: " << description << '\n'; doc << "#" << key.to_string() << "=\n\n"; doc.flush(); } underlying.add_ints_attribute(key, description, handler); } void miriway::DocumentingStore::add_bool_attribute(const live_config::Key& key, std::string_view description, HandleBool handler) { if (!existing_keys.count(key.to_string())) { doc << "# bool: " << description << '\n'; doc << "#" << key.to_string() << "=\n\n"; doc.flush(); } underlying.add_bool_attribute(key, description, handler); } void miriway::DocumentingStore::add_float_attribute(const live_config::Key& key, std::string_view description, HandleFloat handler) { if (!existing_keys.count(key.to_string())) { doc << "# float: " << description << '\n'; doc << "#" << key.to_string() << "=\n\n"; doc.flush(); } underlying.add_float_attribute(key, description, handler); } void miriway::DocumentingStore::add_floats_attribute(const live_config::Key& key, std::string_view description, HandleFloats handler) { if (!existing_keys.count(key.to_string())) { doc << "# float[]: " << description << '\n'; doc << "#" << key.to_string() << "=\n\n"; doc.flush(); } underlying.add_floats_attribute(key, description, handler); } void miriway::DocumentingStore::add_string_attribute(const live_config::Key& key, std::string_view description, HandleString handler) { if (!existing_keys.count(key.to_string())) { doc << "# string: " << description << '\n'; doc << "#" << key.to_string() << "=\n\n"; doc.flush(); } underlying.add_string_attribute(key, description, handler); } void miriway::DocumentingStore::add_strings_attribute(const live_config::Key& key, std::string_view description, HandleStrings handler) { if (!existing_keys.count(key.to_string())) { doc << "# string[]: " << description << '\n'; doc << "#" << key.to_string() << "=\n\n"; doc.flush(); } underlying.add_strings_attribute(key, description, handler); } void miriway::DocumentingStore::add_int_attribute(const live_config::Key& key, std::string_view description, int preset, HandleInt handler) { if (!existing_keys.count(key.to_string())) { doc << "# int: " << description << '\n'; doc << "#" << key.to_string() << '=' << preset << "\n\n"; doc.flush(); } underlying.add_int_attribute(key, description, handler); } void miriway::DocumentingStore::add_ints_attribute(const live_config::Key& key, std::string_view description, std::span preset, HandleInts handler) { if (!existing_keys.count(key.to_string())) { doc << "# int[]: " << description << '\n'; for (auto const& p : preset) doc << "#" << key.to_string() << '=' << p << '\n'; doc << '\n'; doc.flush(); } underlying.add_ints_attribute(key, description, preset, handler); } void miriway::DocumentingStore::add_bool_attribute(const live_config::Key& key, std::string_view description, bool preset, HandleBool handler) { if (!existing_keys.count(key.to_string())) { doc << "# bool: " << description << '\n'; doc << "#" << key.to_string() << '=' << (preset ? "true" : "false") << "\n\n"; doc.flush(); } underlying.add_bool_attribute(key, description, preset, handler); } void miriway::DocumentingStore::add_float_attribute(const live_config::Key& key, std::string_view description, float preset, HandleFloat handler) { if (!existing_keys.count(key.to_string())) { doc << "# float: " << description << '\n'; doc << "#" << key.to_string() << '=' << preset << "\n\n"; doc.flush(); } underlying.add_float_attribute(key, description, preset, handler); } void miriway::DocumentingStore::add_floats_attribute(const live_config::Key& key, std::string_view description, std::span preset, HandleFloats handler) { if (!existing_keys.count(key.to_string())) { doc << "# float[]: " << description << '\n'; for (auto const& p : preset) doc << "#" << key.to_string() << '=' << p << '\n'; doc << '\n'; doc.flush(); } underlying.add_floats_attribute(key, description, preset, handler); } void miriway::DocumentingStore::add_string_attribute(const live_config::Key& key, std::string_view description, std::string_view preset, HandleString handler) { if (!existing_keys.count(key.to_string())) { doc << "# string: " << description << '\n'; doc << "#" << key.to_string() << '=' << preset << "\n\n"; doc.flush(); } underlying.add_string_attribute(key, description, preset, handler); } void miriway::DocumentingStore::add_strings_attribute(const live_config::Key& key, std::string_view description, std::span preset, HandleStrings handler) { if (!existing_keys.count(key.to_string())) { doc << "# string[]: " << description << '\n'; for (auto const& p : preset) doc << "#" << key.to_string() << '=' << p << '\n'; doc << '\n'; doc.flush(); } underlying.add_strings_attribute(key, description, preset, handler); } void miriway::DocumentingStore::on_done(HandleDone handler) { underlying.on_done(handler); } Miriway-Miriway-854d43d/miriway_documenting_store.h000066400000000000000000000062001521360756500225650ustar00rootroot00000000000000/* * Copyright © Alan Griffiths * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Alan Griffiths */ #ifndef MIRIWAY_MIRIWAY_DOCUMENTING_STORE_H #define MIRIWAY_MIRIWAY_DOCUMENTING_STORE_H #include #include #include #include namespace miriway { using namespace miral; /// Documents the available options class DocumentingStore : public live_config::Store { public: explicit DocumentingStore(Store& underlying, std::filesystem::path target); void add_int_attribute(const live_config::Key& key, std::string_view description, HandleInt handler) override; void add_ints_attribute(const live_config::Key& key, std::string_view description, HandleInts handler) override; void add_bool_attribute(const live_config::Key& key, std::string_view description, HandleBool handler) override; void add_float_attribute(const live_config::Key& key, std::string_view description, HandleFloat handler) override; void add_floats_attribute(const live_config::Key& key, std::string_view description, HandleFloats handler) override; void add_string_attribute(const live_config::Key& key, std::string_view description, HandleString handler) override; void add_strings_attribute(const live_config::Key& key, std::string_view description, HandleStrings handler) override; void add_int_attribute(const live_config::Key& key, std::string_view description, int preset, HandleInt handler) override; void add_ints_attribute(const live_config::Key& key, std::string_view description, std::span preset, HandleInts handler) override; void add_bool_attribute(const live_config::Key& key, std::string_view description, bool preset, HandleBool handler) override; void add_float_attribute(const live_config::Key& key, std::string_view description, float preset, HandleFloat handler) override; void add_floats_attribute(const live_config::Key& key, std::string_view description, std::span preset, HandleFloats handler) override; void add_string_attribute(const live_config::Key& key, std::string_view description, std::string_view preset, HandleString handler) override; void add_strings_attribute(const live_config::Key& key, std::string_view description, std::span preset, HandleStrings handler) override; void on_done(HandleDone handler) override; private: Store& underlying; std::ofstream doc; std::set> existing_keys; }; } #endif //MIRIWAY_MIRIWAY_DOCUMENTING_STORE_HMiriway-Miriway-854d43d/miriway_ext_workspace_v1.cpp000066400000000000000000000400741521360756500226630ustar00rootroot00000000000000/* * Copyright © 2025 Octopull Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Alan Griffiths */ #include "miriway_ext_workspace_v1.h" #include "wayland-generated/ext-workspace-v1_wrapper.h" #include #include #include #include #include #include #include #include #include using miral::Workspace; namespace miriway { class ExtWorkspaceGroupHandleV1; class ExtWorkspaceHandleV1; class ExtWorkspaceManagerV1 : public mir::wayland::ExtWorkspaceManagerV1 { public: explicit ExtWorkspaceManagerV1(wl_resource* new_ext_workspace_manager_v1); void commit() override; void stop() override; void output_added(miral::WaylandTools* wltools, miral::Output const& output); void output_deleted(miral::WaylandTools* wltools, miral::Output const& output); void workspace_created(std::weak_ptr const& wksp); void workspace_activated(std::weak_ptr const& wksp); void workspace_deactivated(std::weak_ptr const& wksp); void workspace_destroyed(std::weak_ptr const& wksp); void on_activate(ExtWorkspaceHandleV1* wh); void on_destroy(ExtWorkspaceHandleV1* wh); class Global; private: void update_workspace_info(ExtWorkspaceHandleV1 const* wh, unsigned int i) const; ExtWorkspaceGroupHandleV1* const the_workspace_group; std::list, ExtWorkspaceHandleV1*>> workspaces; }; class ExtWorkspaceManagerV1::Global : public mir::wayland::ExtWorkspaceManagerV1::Global { public: Global(miral::WaylandExtensions::Context const* context, miral::WaylandTools& wltools); ~Global(); void bind(wl_resource* new_ext_workspace_manager_v1) override; void output_added(miral::Output const& output); void output_removed(const miral::Output &output); void workspace_created(std::shared_ptr const& wksp); void workspace_activated(std::shared_ptr const& wksp); void workspace_deactivated(std::shared_ptr const& wksp); void workspace_destroyed(std::shared_ptr const& wksp); private: miral::WaylandExtensions::Context const* const context; std::vector> the_workspace_managers; miral::WaylandTools* const wltools; }; class ExtWorkspaceGroupHandleV1 : public mir::wayland::ExtWorkspaceGroupHandleV1 { public: explicit ExtWorkspaceGroupHandleV1(ExtWorkspaceManagerV1& manager); private: void create_workspace(std::string const& workspace) override; void destroy() override; }; class ExtWorkspaceHandleV1 : public mir::wayland::ExtWorkspaceHandleV1 { public: explicit ExtWorkspaceHandleV1(ExtWorkspaceManagerV1& parent); void destroy() override; void activate() override; void deactivate() override; void assign(wl_resource* workspace_group) override; void remove() override; private: miriway::ExtWorkspaceManagerV1& parent; }; } namespace { // There will be one global for each connection (client) only updated on Wayland thread, but read by "server side" std::mutex all_the_globals_mutex; std::set all_the_globals; // The output list is maintained "server side" and accessed "frontend side" std::mutex all_the_outputs_mutex; std::set all_the_outputs; // The workspace list is maintained "server side" and accessed "frontend side" std::mutex all_the_workspaces_mutex; enum class WkspState { active, hidden }; std::map, WkspState> all_the_workspaces; std::function const& wksp)> activate = [](auto const&){}; } void miriway::ExtWorkspaceV1::on_workspace_create(std::shared_ptr const& wksp) { { std::lock_guard lock(all_the_workspaces_mutex); all_the_workspaces.emplace(wksp, WkspState::hidden); } std::lock_guard lock{all_the_globals_mutex}; for (auto const& global : all_the_globals) global->workspace_created(wksp); } void miriway::ExtWorkspaceV1::on_workspace_activate(std::shared_ptr const& wksp) { std::unique_lock lock(all_the_workspaces_mutex); if (auto const i = all_the_workspaces.find(wksp); i != all_the_workspaces.end()) { i->second = WkspState::active; lock.unlock(); std::lock_guard lock_g{all_the_globals_mutex}; for (auto const &global: all_the_globals) global->workspace_activated(wksp); } } void miriway::ExtWorkspaceV1::on_workspace_deactivate(std::shared_ptr const& wksp) { std::unique_lock lock(all_the_workspaces_mutex); if (auto const i = all_the_workspaces.find(wksp); i != all_the_workspaces.end()) { i->second = WkspState::hidden; lock.unlock(); std::lock_guard lock_g{all_the_globals_mutex}; for (auto const &global: all_the_globals) global->workspace_deactivated(wksp); } } void miriway::ExtWorkspaceV1::on_workspace_destroy(std::shared_ptr const& wksp) { { std::lock_guard lock(all_the_workspaces_mutex); all_the_workspaces.erase(wksp); } std::lock_guard lock_g{all_the_globals_mutex}; for (auto const &global: all_the_globals) global->workspace_destroyed(wksp); } void miriway::ExtWorkspaceV1::on_output_create(const Output& output) { { std:: lock_guard lock(all_the_outputs_mutex); all_the_outputs.insert(output); } std::lock_guard lock{all_the_globals_mutex}; for (auto const& global : all_the_globals) global->output_added(output); } void miriway::ExtWorkspaceV1::on_output_destroy(const Output& output) { { std:: lock_guard lock(all_the_outputs_mutex); all_the_outputs.erase(output); } std::lock_guard lock{all_the_globals_mutex}; for (auto const& global : all_the_globals) global->output_removed(output); } void miriway::ExtWorkspaceV1::set_workspace_activator_callback(std::function const& wksp)> f) { activate = std::move(f); } miriway::ExtWorkspaceManagerV1::ExtWorkspaceManagerV1(wl_resource* new_ext_workspace_manager_v1) : mir::wayland::ExtWorkspaceManagerV1{new_ext_workspace_manager_v1, Version<1>{}}, the_workspace_group{new ExtWorkspaceGroupHandleV1{*this}} { send_workspace_group_event(the_workspace_group->resource); the_workspace_group->send_capabilities_event(0); } void miriway::ExtWorkspaceManagerV1::commit() { } void miriway::ExtWorkspaceManagerV1::stop() { } void miriway::ExtWorkspaceManagerV1::output_added(miral::WaylandTools* wltools, miral::Output const& output) { wltools->for_each_binding(client, output, [this](wl_resource* the_output) { the_workspace_group->send_output_enter_event(the_output); }); } void miriway::ExtWorkspaceManagerV1::Global::output_removed(const miral::Output &output) { context->run_on_wayland_mainloop([this, output] { for (auto const& the_workspace_manager : the_workspace_managers) { if (the_workspace_manager) { the_workspace_manager.value().output_deleted(wltools, output); the_workspace_manager.value().send_done_event(); } } }); } void miriway::ExtWorkspaceManagerV1::output_deleted(miral::WaylandTools* wltools, miral::Output const& output) { wltools->for_each_binding(client, output, [this](wl_resource* the_output) { the_workspace_group->send_output_leave_event(the_output); }); } void miriway::ExtWorkspaceManagerV1::workspace_created(std::weak_ptr const& wksp) { auto const wh = new ExtWorkspaceHandleV1{*this}; workspaces.emplace_back(wksp, wh); send_workspace_event(wh->resource); wh->send_capabilities_event(ExtWorkspaceHandleV1::WorkspaceCapabilities::activate); update_workspace_info(wh, workspaces.size()); the_workspace_group->send_workspace_enter_event(wh->resource); } void miriway::ExtWorkspaceManagerV1::update_workspace_info(ExtWorkspaceHandleV1 const* wh, unsigned int i) const { wh->send_name_event(std::format("Wksp {}", i)); uint32_t const source[2] = {i, 0}; wl_array coordinates; wl_array_init(&coordinates); auto target = wl_array_add(&coordinates, sizeof(source)); memcpy(target, source, sizeof(source)); wh->send_coordinates_event(&coordinates); wl_array_release(&coordinates); } void miriway::ExtWorkspaceManagerV1::workspace_activated(std::weak_ptr const& wksp) { for (auto const& [_, wh]: workspaces) { if (!_.owner_before(wksp) && !wksp.owner_before(_)) { wh->send_state_event(ExtWorkspaceHandleV1::State::active); break; } } } void miriway::ExtWorkspaceManagerV1::workspace_deactivated(std::weak_ptr const& wksp) { for (auto const& [_, wh]: workspaces) { if (!_.owner_before(wksp) && !wksp.owner_before(_)) { wh->send_state_event(ExtWorkspaceHandleV1::State::hidden); break; } } } void miriway::ExtWorkspaceManagerV1::workspace_destroyed(std::weak_ptr const& wksp) { auto searching = true; unsigned int i = 0; for (auto it = workspaces.begin(); it != workspaces.end();) { if (!it->first.owner_before(wksp) && !wksp.owner_before(it->first)) { the_workspace_group->send_workspace_leave_event(it->second->resource); it->second->send_removed_event(); it = workspaces.erase(it); searching = false; } else { ++i; if (!searching) { update_workspace_info(it->second, i); } ++it; } } } void miriway::ExtWorkspaceManagerV1::on_destroy(miriway::ExtWorkspaceHandleV1* wh) { auto p = std::find_if(workspaces.begin(), workspaces.end(), [wh](auto const& wksp_pair) { return wksp_pair.second == wh; }); if (p != workspaces.end()) workspaces.erase(p); } void miriway::ExtWorkspaceManagerV1::on_activate(miriway::ExtWorkspaceHandleV1* wh) { auto p = std::find_if(workspaces.begin(), workspaces.end(), [wh](auto const& e) { return e.second == wh; }); if (p != workspaces.end()) { if (auto const wksp = p->first.lock()) { ::activate(wksp); } } } miriway::ExtWorkspaceManagerV1::Global::Global(miral::WaylandExtensions::Context const* context, miral::WaylandTools& wltools) : mir::wayland::ExtWorkspaceManagerV1::Global{context->display(), Version<1>{}}, context{context}, the_workspace_managers{}, wltools{&wltools} { std::lock_guard lock{all_the_globals_mutex}; all_the_globals.insert(this); } miriway::ExtWorkspaceManagerV1::Global::~Global() { std::lock_guard lock{all_the_globals_mutex}; all_the_globals.erase(this); } void miriway::ExtWorkspaceManagerV1::Global::bind(wl_resource* new_ext_workspace_manager_v1) { auto const the_workspace_manager = new ExtWorkspaceManagerV1{new_ext_workspace_manager_v1}; the_workspace_managers.emplace_back(the_workspace_manager); { std::lock_guard lock(all_the_outputs_mutex); for (auto const &output: all_the_outputs) { the_workspace_manager->output_added(wltools, output); } } { std::lock_guard lock(all_the_workspaces_mutex); for (auto const& [wksp, state]: all_the_workspaces) { the_workspace_manager->workspace_created(wksp); if (state == WkspState::active) the_workspace_manager->workspace_activated(wksp); else the_workspace_manager->workspace_deactivated(wksp); } } the_workspace_manager->send_done_event(); } void miriway::ExtWorkspaceManagerV1::Global::output_added(miral::Output const& output) { context->run_on_wayland_mainloop([this, output] { for (auto const& the_workspace_manager : the_workspace_managers) { if (the_workspace_manager) { the_workspace_manager.value().output_added(wltools, output); the_workspace_manager.value().send_done_event(); } } }); } void miriway::ExtWorkspaceManagerV1::Global::workspace_destroyed(std::shared_ptr const& wksp) { context->run_on_wayland_mainloop([this, wksp=std::weak_ptr{wksp}] { for (auto const& the_workspace_manager : the_workspace_managers) { if (the_workspace_manager) { the_workspace_manager.value().workspace_destroyed(wksp); the_workspace_manager.value().send_done_event(); } } }); } void miriway::ExtWorkspaceManagerV1::Global::workspace_deactivated(std::shared_ptr const& wksp) { context->run_on_wayland_mainloop([this, wksp] { for (auto const& the_workspace_manager : the_workspace_managers) { if (the_workspace_manager) { the_workspace_manager.value().workspace_deactivated(wksp); the_workspace_manager.value().send_done_event(); } } }); } void miriway::ExtWorkspaceManagerV1::Global::workspace_activated(std::shared_ptr const& wksp) { context->run_on_wayland_mainloop([this, wksp] { for (auto const& the_workspace_manager : the_workspace_managers) { if (the_workspace_manager) { the_workspace_manager.value().workspace_activated(wksp); the_workspace_manager.value().send_done_event(); } } }); } void miriway::ExtWorkspaceManagerV1::Global::workspace_created(std::shared_ptr const& wksp) { context->run_on_wayland_mainloop([this, wksp] { for (auto const& the_workspace_manager : the_workspace_managers) { if (the_workspace_manager) { the_workspace_manager.value().workspace_created(wksp); the_workspace_manager.value().send_done_event(); } } }); } miriway::ExtWorkspaceGroupHandleV1::ExtWorkspaceGroupHandleV1(ExtWorkspaceManagerV1& manager) : mir::wayland::ExtWorkspaceGroupHandleV1{manager} { } void miriway::ExtWorkspaceGroupHandleV1::create_workspace(std::string const& workspace) { (void)workspace; } void miriway::ExtWorkspaceGroupHandleV1::destroy() { } void miriway::ExtWorkspaceHandleV1::destroy() { parent.on_destroy(this); } void miriway::ExtWorkspaceHandleV1::activate() { parent.on_activate(this); } void miriway::ExtWorkspaceHandleV1::deactivate() { } void miriway::ExtWorkspaceHandleV1::assign(wl_resource* workspace_group) { (void)workspace_group; } void miriway::ExtWorkspaceHandleV1::remove() { } miriway::ExtWorkspaceHandleV1::ExtWorkspaceHandleV1(miriway::ExtWorkspaceManagerV1& parent) : mir::wayland::ExtWorkspaceHandleV1::ExtWorkspaceHandleV1{parent}, parent{parent} { } auto miriway::build_ext_workspace_v1_global(miral::WaylandTools& wltools) -> miral::WaylandExtensions::Builder { return miral::WaylandExtensions::Builder { .name = ExtWorkspaceManagerV1::interface_name, .build = [&](auto* context) { return std::make_shared(context, wltools); } }; } auto miriway::ext_workspace_v1_name() -> char const* { return ExtWorkspaceManagerV1::interface_name; }Miriway-Miriway-854d43d/miriway_ext_workspace_v1.h000066400000000000000000000032661521360756500223320ustar00rootroot00000000000000/* * Copyright © 2025 Octopull Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Alan Griffiths */ #ifndef MIRIWAY_EXT_WORKSPACE_V1_H #define MIRIWAY_EXT_WORKSPACE_V1_H #include "miriway_workspace_hooks.h" #include namespace miral { class Output; class WaylandTools; } namespace miriway { class ExtWorkspaceV1 : public WorkspaceHooks { public: void on_workspace_create(std::shared_ptr const& wksp) override; void on_workspace_activate(std::shared_ptr const& wksp) override; void on_workspace_deactivate(std::shared_ptr const& wksp) override; void on_workspace_destroy(std::shared_ptr const& wksp) override; void on_output_create(Output const& output) override; void on_output_destroy(Output const& output) override; void set_workspace_activator_callback(std::function const& wksp)> f) override; }; auto ext_workspace_v1_name() -> char const*; auto build_ext_workspace_v1_global(miral::WaylandTools& wltools) -> miral::WaylandExtensions::Builder; } // miriway #endif //MIRIWAY_EXT_WORKSPACE_V1_H Miriway-Miriway-854d43d/miriway_magnifier.cpp000066400000000000000000000030451521360756500213350ustar00rootroot00000000000000/* * Copyright © 2025 Octopull Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Alan Griffiths */ #include "miriway_magnifier.h" #include using namespace miral::toolkit; bool miriway::Magnifier::check_on_off(MirKeyboardEvent const* key_event) { if (mir_keyboard_event_action(key_event) != mir_keyboard_action_down) return false; if (mir_keyboard_event_modifiers(key_event) & mir_input_event_modifier_meta) { // Turn on/off the magnifier Meta+{Plus,Equal}/Meta+Escape switch (mir_keyboard_event_keysym(key_event)) { case XKB_KEY_plus: case XKB_KEY_equal: enable(true); return true; case XKB_KEY_Escape: enable(false); return true; default: return false; } } return false; } void miriway::Magnifier::operator()(mir::Server& server) { miral::Magnifier::operator()(server); magnifier_filter(server); } Miriway-Miriway-854d43d/miriway_magnifier.h000066400000000000000000000022521521360756500210010ustar00rootroot00000000000000/* * Copyright © 2025 Octopull Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Alan Griffiths */ #ifndef MIRIWAY_MIRIWAY_MAGNIFIER_H #define MIRIWAY_MIRIWAY_MAGNIFIER_H #include #include namespace miriway { class Magnifier : miral::Magnifier { miral::AppendKeyboardEventFilter magnifier_filter{[this](auto... args) { return check_on_off(args...); }}; bool check_on_off(MirKeyboardEvent const* key_event); public: using miral::Magnifier::Magnifier; void operator()(mir::Server& server); }; } #endif //MIRIWAY_MIRIWAY_MAGNIFIER_HMiriway-Miriway-854d43d/miriway_policy.cpp000066400000000000000000000324651521360756500207030ustar00rootroot00000000000000/* * Copyright © 2022 Octopull Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Alan Griffiths */ #include "miriway_policy.h" #include "miriway_commands.h" #include #include #include #include #include using namespace mir::geometry; using namespace miral; miriway::WindowManagerPolicy::WindowManagerPolicy(WindowManagerTools const& tools, ShellCommands& commands) : WorkspaceWMStrategy{tools}, commands{&commands} { commands.init_window_manager(this); } miral::WindowSpecification miriway::WindowManagerPolicy::place_new_window( miral::ApplicationInfo const& app_info, miral::WindowSpecification const& request_parameters) { auto result = WorkspaceWMStrategy::place_new_window(app_info, request_parameters); result.userdata() = make_workspace_info(); return result; } void miriway::WindowManagerPolicy::advise_new_window(const miral::WindowInfo &window_info) { WorkspaceWMStrategy::advise_new_window(window_info); if (is_application(window_info.depth_layer())) { commands->advise_new_window_for(window_info.window().application()); } } void miriway::WindowManagerPolicy::advise_delete_window(const miral::WindowInfo &window_info) { WorkspaceWMStrategy::advise_delete_window(window_info); if (is_application(window_info.depth_layer())) { commands->advise_delete_window_for(window_info.window().application()); } } void miriway::WindowManagerPolicy::dock_active_window_left(bool shift) { tools.invoke_under_lock( [this, shift] { if (!shift) { dock_active_window_under_lock( MirPlacementGravity(mir_placement_gravity_northwest | mir_placement_gravity_southwest)); } else { move_active_window_to_next_output(mir_placement_gravity_west); } }); } void miriway::WindowManagerPolicy::toggle_maximized_restored() { tools.invoke_under_lock( [this] { if (auto active_window = tools.active_window()) { auto& window_info = tools.info_for(active_window); if (!eligible_to_dock(window_info.type(), window_info.depth_layer())) { return; } WindowSpecification modifications; modifications.state() = (window_info.state() != mir_window_state_restored) ? mir_window_state_restored : mir_window_state_maximized; if (window_info.state() != mir_window_state_restored) { modifications.state() = mir_window_state_restored; modifications.size() = window_info.restore_rect().size; modifications.top_left() = window_info.restore_rect().top_left; } else { modifications.state() = mir_window_state_maximized; } tools.place_and_size_for_state(modifications, window_info); tools.modify_window(window_info, modifications); } }); } void miriway::WindowManagerPolicy::toggle_always_on_top() { tools.invoke_under_lock( [this] { if (auto const w = tools.active_window()) { auto const& info = tools.info_for(w); switch (info.depth_layer()) { case mir_depth_layer_application: { WindowSpecification modifications; tools.remove_tree_from_workspace(w, active_workspace()); modifications.depth_layer() = mir_depth_layer_always_on_top; tools.modify_window(tools.info_for(w), modifications); return; } case mir_depth_layer_always_on_top: { WindowSpecification modifications; modifications.depth_layer() = mir_depth_layer_application; tools.modify_window(tools.info_for(w), modifications); tools.add_tree_to_workspace(w, active_workspace()); return; } default:; } } }); } void miriway::WindowManagerPolicy::dock_active_window_right(bool shift) { tools.invoke_under_lock( [this, shift] { if (!shift) { dock_active_window_under_lock( MirPlacementGravity(mir_placement_gravity_northeast | mir_placement_gravity_southeast)); } else { move_active_window_to_next_output(mir_placement_gravity_east); } }); } void miriway::WindowManagerPolicy::move_active_window_to_next_output(MirPlacementGravity placement) { if (application_zones.size() < 2) return; auto const active_window = tools.active_window(); if (!active_window) return; auto const active_zone = tools.active_application_zone(); // Next or previous zone depending on direction Zone const target_zone = [&]() { auto iter = std::find(application_zones.begin(), application_zones.end(), active_zone); if (placement & mir_placement_gravity_east) { return ++iter != application_zones.end() ? *iter : *application_zones.begin(); } else { return iter != application_zones.begin() ? *--iter : *application_zones.rbegin(); } }(); auto const target_extents = target_zone.extents(); auto top_left_offset = active_window.top_left() - active_zone.extents().top_left; if (top_left_offset.dx < DeltaX{} || top_left_offset.dx > as_delta(target_extents.size.width)) { top_left_offset.dx = DeltaX{}; } if (top_left_offset.dy < DeltaY{} || top_left_offset.dy > as_delta(target_extents.size.height)) { top_left_offset.dy = DeltaY{}; } WindowSpecification modifications; modifications.top_left() = target_extents.top_left + top_left_offset; modifications.output_id() = -1; auto& window_info = tools.info_for(active_window); tools.place_and_size_for_state(modifications, window_info); tools.modify_window(window_info, modifications); } void miriway::WindowManagerPolicy::advise_application_zone_create(miral::Zone const& application_zone) { application_zones.push_back(application_zone); WorkspaceWMStrategy::advise_application_zone_create(application_zone); } void miriway::WindowManagerPolicy::advise_application_zone_update(miral::Zone const& updated, miral::Zone const& original) { for (auto& zone : application_zones) { if (zone.is_same_zone(original)) { zone = updated; break; } } WorkspaceWMStrategy::advise_application_zone_update(updated, original); } void miriway::WindowManagerPolicy::advise_application_zone_delete(miral::Zone const& application_zone) { application_zones.erase( std::remove_if(application_zones.begin(), application_zones.end(), [&application_zone](Zone const& z){ return z.is_same_zone(application_zone); }), application_zones.end()); WorkspaceWMStrategy::advise_application_zone_delete(application_zone); } bool miriway::WindowManagerPolicy::handle_pointer_event(const MirPointerEvent* event) { bool result = Super::handle_pointer_event(event); if (moving_window) { if (result) { window_moved = true; } if (!result) { moving_window = false; if (window_moved) { if (auto active_window = tools.active_window()) { Rectangle const window_rect{active_window.top_left(), active_window.size()}; auto const active_rect = tools.active_output(); auto const overlap = intersection_of(active_rect, window_rect); Point const cursor{ mir_pointer_event_axis_value(event, mir_pointer_axis_x), mir_pointer_event_axis_value(event, mir_pointer_axis_y)}; if (overlap.size.height < window_rect.size.height) { Rectangle const top_margin{active_rect.top_left, {active_rect.size.width, active_rect.size.height/20}}; // If part of the active window is offscreen at top, and cursor near top, maximize it! if (overlap.top() == active_rect.top() && top_margin.contains(cursor)) { auto& window_info = tools.info_for(active_window); WindowSpecification modifications; modifications.state() = mir_window_state_maximized; tools.place_and_size_for_state(modifications, window_info); tools.modify_window(window_info, modifications); return result; } } if (overlap.size.width < window_rect.size.width) { Rectangle const left_margin{active_rect.top_left, {active_rect.size.width/20, active_rect.size.height}}; Rectangle const right_margin{active_rect.top_left + as_delta(left_margin.size.width*19), left_margin.size}; // If part of the active window is offscreen at offscreen horizontally, and cursor near left, dock it! if (overlap.left() == active_rect.left() && left_margin.contains(cursor)) { dock_active_window_under_lock( MirPlacementGravity(mir_placement_gravity_northwest | mir_placement_gravity_southwest)); return result; } else if (right_margin.contains(cursor)) { dock_active_window_under_lock( MirPlacementGravity(mir_placement_gravity_northeast | mir_placement_gravity_southeast)); return result; } } } } } } return result; } void miriway::WindowManagerPolicy::handle_request_move(WindowInfo& window_info, const MirInputEvent* input_event) { moving_window = true; window_moved = false; Super::handle_request_move(window_info, input_event); } bool miriway::WindowManagerPolicy::handle_keyboard_event(MirKeyboardEvent const* event) { return commands->shell_keyboard_enabled() && WorkspaceWMStrategy::handle_keyboard_event(event); } void miriway::WindowManagerPolicy::dock_active_window_under_lock(MirPlacementGravity placement) { if (auto active_window = tools.active_window()) { auto const active_rect = tools.active_application_zone().extents(); auto& window_info = tools.info_for(active_window); if (!eligible_to_dock(window_info.type(), window_info.depth_layer())) { return; } WindowSpecification modifications; modifications.state() = mir_window_state_attached; modifications.attached_edges() = placement; modifications.size() = active_window.size(); if (window_info.state() != mir_window_state_attached || window_info.attached_edges() != placement) { modifications.size().value().width = active_rect.size.width / 2; } else { if (modifications.size().value().width == active_rect.size.width / 2) { modifications.size().value().width = active_rect.size.width / 3; } else if (modifications.size().value().width < active_rect.size.width / 2) { modifications.size().value().width = 2 * active_rect.size.width / 3; } else { modifications.size().value().width = active_rect.size.width / 2; } } tools.place_and_size_for_state(modifications, window_info); tools.modify_window(window_info, modifications); } } bool miriway::WindowManagerPolicy::eligible_to_dock(MirWindowType window_type, MirDepthLayer layer) { switch (window_type) { // Only normal (and freestyle) windows are eligible to dock. case mir_window_type_freestyle: case mir_window_type_normal: return layer == mir_depth_layer_application; default: return false; } } Miriway-Miriway-854d43d/miriway_policy.h000066400000000000000000000064511521360756500203440ustar00rootroot00000000000000/* * Copyright © 2022 Octopull Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Alan Griffiths */ #ifndef MIRIWAY_POLICY_H_ #define MIRIWAY_POLICY_H_ #include "miriway_workspace_manager.h" #include "miriway_ext_workspace_v1.h" #include #if MIRAL_VERSION >= MIR_VERSION_NUMBER(5, 8, 0) #define MIRIWAY_USE_APP_SWITCHER #include using MiralWindowManager = miral::FloatingWindowManager; #else #include using MiralWindowManager = miral::MinimalWindowManager; #endif #include #include #include #include namespace miriway { using namespace miral; class ShellCommands; // A window management policy that adds support for docking and workspaces. // Co-ordinates with `ShellCommands` for the handling of related commands. class WindowManagerPolicy : public WorkspaceWMStrategy { public: WindowManagerPolicy(WindowManagerTools const& tools, ShellCommands& commands); using WorkspaceWMStrategy::workspace_begin; using WorkspaceWMStrategy::workspace_end; using WorkspaceWMStrategy::workspace_up; using WorkspaceWMStrategy::workspace_down; void dock_active_window_left(bool shift); void dock_active_window_right(bool shift); bool handle_pointer_event(const MirPointerEvent* event) override; void handle_request_move(WindowInfo& window_info, const MirInputEvent* input_event) override; void toggle_maximized_restored(); void toggle_always_on_top(); private: auto place_new_window(ApplicationInfo const& app_info, WindowSpecification const& request_parameters) -> WindowSpecification override; void advise_new_window(const WindowInfo &window_info) override; void advise_delete_window(const WindowInfo &window_info) override; void advise_application_zone_create(Zone const& application_zone) override; void advise_application_zone_update(Zone const& updated, Zone const& original) override; void advise_application_zone_delete(Zone const& application_zone) override; void move_active_window_to_next_output(MirPlacementGravity placement); bool handle_keyboard_event(MirKeyboardEvent const* event) override; void dock_active_window_under_lock(MirPlacementGravity placement); static bool eligible_to_dock(MirWindowType window_type, MirDepthLayer layer); ShellCommands* const commands; // moving_window and window_moved are a huristic to deduce whether a window has been moved by user bool moving_window = false; // A move request has been made bool window_moved = false; // Pointer events have been processed following a move request std::vector application_zones; }; } #endif //MIRIWAY_POLICY_H_ Miriway-Miriway-854d43d/miriway_workspace_hooks.h000066400000000000000000000037061521360756500222460ustar00rootroot00000000000000/* * Copyright © 2023 Octopull Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Alan Griffiths */ #ifndef MIRIWAY_WORKSPACE_HOOKS_H_ #define MIRIWAY_WORKSPACE_HOOKS_H_ #include #include namespace miral { class Workspace; class Output; } namespace miriway { using miral::Workspace; using miral::Output; /// An interface to "hook into" the workspace management. /// Mostly, this provides notifications of workspace management events via `on...` methods. /// It also provides a callback to request workspace activation. class WorkspaceHooks { public: WorkspaceHooks() = default; virtual ~WorkspaceHooks() = default; virtual void on_workspace_create(std::shared_ptr const& wksp) = 0; virtual void on_workspace_activate(std::shared_ptr const& wksp) = 0; virtual void on_workspace_deactivate(std::shared_ptr const& wksp) = 0; virtual void on_workspace_destroy(std::shared_ptr const& wksp) = 0; virtual void on_output_create(Output const& output) = 0; virtual void on_output_destroy(Output const& output) = 0; virtual void set_workspace_activator_callback(std::function const &wksp)> f) = 0; private: WorkspaceHooks(WorkspaceHooks const&) = delete; WorkspaceHooks& operator=(WorkspaceHooks const&) = delete; }; } // miriway #endif //MIRIWAY_WORKSPACE_HOOKS_H_ Miriway-Miriway-854d43d/miriway_workspace_manager.cpp000066400000000000000000000242241521360756500230660ustar00rootroot00000000000000/* * Copyright © 2023 Octopull Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Alan Griffiths */ #include "miriway_workspace_manager.h" #include using namespace mir::geometry; using namespace miral; struct miriway::WorkspaceManager::WorkspaceInfo { bool in_hidden_workspace{false}; MirWindowState old_state = mir_window_state_unknown; }; miriway::WorkspaceManager::WorkspaceManager(miriway::WorkspaceHooks &hooks, const WindowManagerTools &tools) : hooks{hooks}, tools_{tools} { hooks.set_workspace_activator_callback([this](auto const& workspace) { tools_.invoke_under_lock([this, workspace] { auto const old_active= active_workspace_; if (*old_active != workspace) { active_workspace_ = std::find(workspaces.begin(), workspaces.end(), workspace); change_active_workspace(workspace, *old_active, Window{}); erase_if_empty(old_active); } }); }); append_new_workspace(); } miriway::WorkspaceManager::~WorkspaceManager() { hooks.set_workspace_activator_callback([](auto...) {}); } void miriway::WorkspaceManager::workspace_begin(bool take_active) { tools_.invoke_under_lock( [this, take_active] { if (active_workspace_ != workspaces.begin()) { auto const old_workspace = active_workspace_; auto const& window = take_active ? tools_.active_window() : Window{}; auto const& old_active = *active_workspace_; auto const& new_active = *(active_workspace_ = workspaces.cbegin()); change_active_workspace(new_active, old_active, window); erase_if_empty(old_workspace); } }); } void miriway::WorkspaceManager::workspace_end(bool take_active) { tools_.invoke_under_lock( [this, take_active] { auto const old_workspace = active_workspace_; auto const& window = take_active ? tools_.active_window() : Window{}; auto const& old_active = *active_workspace_; append_new_workspace(); auto const& new_active = *active_workspace_; change_active_workspace(new_active, old_active, window); erase_if_empty(old_workspace); }); } void miriway::WorkspaceManager::workspace_up(bool take_active) { tools_.invoke_under_lock( [this, take_active] { if (active_workspace_ != workspaces.cbegin()) { auto const old_workspace = active_workspace_; auto const& window = take_active ? tools_.active_window() : Window{}; auto const& old_active = *active_workspace_; auto const& new_active = *--active_workspace_; change_active_workspace(new_active, old_active, window); erase_if_empty(old_workspace); } }); } void miriway::WorkspaceManager::workspace_down(bool take_active) { tools_.invoke_under_lock( [this, take_active] { auto const old_workspace = active_workspace_; auto const& window = take_active ? tools_.active_window() : Window{}; auto const& old_active = *active_workspace_; if (++active_workspace_ == workspaces.cend()) { append_new_workspace(); } auto const& new_active = *active_workspace_; change_active_workspace(new_active, old_active, window); erase_if_empty(old_workspace); }); } void miriway::WorkspaceManager::append_new_workspace() { workspaces.push_back(tools_.create_workspace()); active_workspace_ = --workspaces.cend(); hooks.on_workspace_create(*active_workspace_); hooks.on_workspace_activate(*active_workspace_); } void miriway::WorkspaceManager::erase_if_empty(workspace_list::const_iterator const& old_workspace) { bool empty = true; tools_.for_each_window_in_workspace(*old_workspace, [&](auto ww) { if (is_application(tools_.info_for(ww).depth_layer())) empty = false; }); if (empty) { workspace_to_active.erase(*old_workspace); workspaces.erase(old_workspace); hooks.on_workspace_destroy(*old_workspace); } } void miriway::WorkspaceManager::apply_workspace_hidden_to(Window const& window) { auto const& window_info = tools_.info_for(window); auto& workspace_info = workspace_info_for(window_info); if (!workspace_info.in_hidden_workspace) { workspace_info.in_hidden_workspace = true; workspace_info.old_state = window_info.state(); WindowSpecification modifications; modifications.state() = mir_window_state_hidden; tools_.place_and_size_for_state(modifications, window_info); tools_.modify_window(window_info.window(), modifications); } } void miriway::WorkspaceManager::apply_workspace_visible_to(Window const& window) { auto const& window_info = tools_.info_for(window); auto& workspace_info = workspace_info_for(window_info); if (workspace_info.in_hidden_workspace) { workspace_info.in_hidden_workspace = false; WindowSpecification modifications; modifications.state() = workspace_info.old_state; tools_.place_and_size_for_state(modifications, window_info); tools_.modify_window(window_info.window(), modifications); } } void miriway::WorkspaceManager::change_active_workspace( std::shared_ptr const& new_active, std::shared_ptr const& old_active, Window const& window) { if (new_active == old_active) return; hooks.on_workspace_deactivate(old_active); hooks.on_workspace_activate(new_active); auto const old_active_window = tools_.active_window(); auto const old_active_window_shell = old_active_window && !is_application(tools_.info_for(old_active_window).depth_layer()); if (!old_active_window || old_active_window_shell) { // If there's no active window, the first shown grabs focus: get the right one if (auto const ww = workspace_to_active[new_active]) { tools_.for_each_workspace_containing(ww, [&](std::shared_ptr const& ws) { if (ws == new_active) { apply_workspace_visible_to(ww); } }); // If focus was on a shell window, put it on an app if (old_active_window_shell) tools_.select_active_window(ww); } } tools_.remove_tree_from_workspace(window, old_active); tools_.add_tree_to_workspace(window, new_active); tools_.for_each_window_in_workspace(new_active, [&](Window const& ww) { if (is_application(tools_.info_for(ww).depth_layer())) { apply_workspace_visible_to(ww); } }); bool hide_old_active = false; tools_.for_each_window_in_workspace(old_active, [&](Window const& ww) { if (is_application(tools_.info_for(ww).depth_layer())) { if (ww == old_active_window) { // If we hide the active window focus will shift: do that last hide_old_active = true; return; } apply_workspace_hidden_to(ww); return; } }); if (hide_old_active) { apply_workspace_hidden_to(old_active_window); // Remember the old active_window when we switch away workspace_to_active[old_active] = old_active_window; } } void miriway::WorkspaceManager::activate_workspace_containing(Window const& window) { tools_.for_each_workspace_containing(window, [this](std::shared_ptr const& workspace) { auto const old_active = active_workspace_; active_workspace_ = find(workspaces.cbegin(), workspaces.cend(), workspace); change_active_workspace(workspace, *old_active, Window{}); }); } void miriway::WorkspaceManager::advise_adding_to_workspace(std::shared_ptr const& workspace, std::vector const& windows) { if (windows.empty()) return; for (auto const& window : windows) { if (workspace == *active_workspace_) { apply_workspace_visible_to(window); } else { apply_workspace_hidden_to(window); } } } auto miriway::WorkspaceManager::active_workspace() const -> std::shared_ptr { return *active_workspace_; } bool miriway::WorkspaceManager::is_application(MirDepthLayer layer) { switch (layer) { case mir_depth_layer_application: case mir_depth_layer_always_on_top: return true; default:; return false; } } bool miriway::WorkspaceManager::in_hidden_workspace(WindowInfo const& info) const { auto& workspace_info = workspace_info_for(info); return workspace_info.in_hidden_workspace; } void miriway::WorkspaceManager::advise_new_window(WindowInfo const& window_info) { if (auto const& parent = window_info.parent()) { if (workspace_info_for(tools_.info_for(parent)).in_hidden_workspace) apply_workspace_hidden_to(window_info.window()); } else { tools_.add_tree_to_workspace(window_info.window(), active_workspace()); } } auto miriway::WorkspaceManager::make_workspace_info() -> std::shared_ptr { return std::make_shared(); } Miriway-Miriway-854d43d/miriway_workspace_manager.h000066400000000000000000000124321521360756500225310ustar00rootroot00000000000000/* * Copyright © 2023 Octopull Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Authored by: Alan Griffiths */ #ifndef MIRIWAY_WORKSPACE_MANAGER_H_ #define MIRIWAY_WORKSPACE_MANAGER_H_ #include "miriway_workspace_hooks.h" #include #include #include #include namespace miral { class Workspace; } namespace miriway { using miral::Window; using miral::WindowInfo; using miral::WindowManagerTools; using miral::WindowSpecification; using miral::Workspace; class WorkspaceManager { public: explicit WorkspaceManager(WindowManagerTools const& tools); WorkspaceManager(WorkspaceHooks& hooks, WindowManagerTools const& tools); virtual ~WorkspaceManager(); void workspace_begin(bool take_active); void workspace_end(bool take_active); void workspace_up(bool take_active); void workspace_down(bool take_active); void apply_workspace_hidden_to(Window const& window); void apply_workspace_visible_to(Window const& window); void change_active_workspace(std::shared_ptr const& ww, std::shared_ptr const& old_active, miral::Window const& window); void activate_workspace_containing(Window const& window); void advise_new_window(const WindowInfo &window_info); void advise_adding_to_workspace(std::shared_ptr const& workspace, std::vector const& windows); auto active_workspace() const -> std::shared_ptr; bool in_hidden_workspace(WindowInfo const& info) const; static bool is_application(MirDepthLayer layer); struct WorkspaceInfo; static auto make_workspace_info() -> std::shared_ptr; // This implementation assumes the userdata contains WorkspaceInfo // but, in case there's another option, made virtual virtual auto workspace_info_for(WindowInfo const& info) const -> WorkspaceInfo& { return *std::static_pointer_cast(info.userdata()); } private: WorkspaceHooks& hooks; WindowManagerTools tools_; using workspace_list = std::list>; workspace_list workspaces; workspace_list::const_iterator active_workspace_; std::map, miral::Window> workspace_to_active; void append_new_workspace(); void erase_if_empty(workspace_list::const_iterator const& old_workspace); }; // Template class to hook WorkspaceManager into a window management strategy template requires requires { { std::derived_from }; { std::derived_from }; } class WorkspaceWMStrategy : public WMStrategy, protected WMHooks, protected WorkspaceManager { protected: using Super = WorkspaceWMStrategy; explicit WorkspaceWMStrategy(WindowManagerTools const& tools) : WMStrategy{tools}, WorkspaceManager{*this, tools} {} void advise_new_window(const WindowInfo &window_info) override { WMStrategy::advise_new_window(window_info); WorkspaceManager::advise_new_window(window_info); } void advise_adding_to_workspace(std::shared_ptr const& workspace, std::vector const& windows) override { WMStrategy::advise_adding_to_workspace(workspace, windows); WorkspaceManager::advise_adding_to_workspace(workspace, windows); } void handle_modify_window(WindowInfo& window_info, WindowSpecification const& modifications) override { auto mods = modifications; if (in_hidden_workspace(window_info)) { // Don't allow state changes in hidden workspaces if (mods.state().is_set()) mods.state().consume(); // Don't allow size changes in hidden workspaces if (mods.size().is_set()) mods.size().consume(); } WMStrategy::handle_modify_window(window_info, mods); } void handle_raise_window(WindowInfo& window_info) override { if (in_hidden_workspace(window_info)) { activate_workspace_containing(window_info.window()); } WMStrategy::handle_raise_window(window_info); } virtual void advise_output_create(miral::Output const& output) override { WMHooks::on_output_create(output); WMStrategy::advise_output_create(output); } virtual void advise_output_delete(miral::Output const& output) override { WMHooks::on_output_destroy(output); WMStrategy::advise_output_delete(output); } }; } // miriway #endif //MIRIWAY_WORKSPACE_MANAGER_H_ Miriway-Miriway-854d43d/sddm/000077500000000000000000000000001521360756500160545ustar00rootroot00000000000000Miriway-Miriway-854d43d/sddm/miriway.conf.in000066400000000000000000000003271521360756500210130ustar00rootroot00000000000000[General] DisplayServer=wayland GreeterEnvironment=QT_WAYLAND_SHELL_INTEGRATION=layer-shell InputMethod= [Wayland] CompositorCommand=@CMAKE_INSTALL_FULL_BINDIR@/miriway --add-wayland-extensions=zwlr_layer_shell_v1 Miriway-Miriway-854d43d/snap-utils/000077500000000000000000000000001521360756500172245ustar00rootroot00000000000000Miriway-Miriway-854d43d/snap-utils/bin/000077500000000000000000000000001521360756500177745ustar00rootroot00000000000000Miriway-Miriway-854d43d/snap-utils/bin/miriway-session000077500000000000000000000003271521360756500230660ustar00rootroot00000000000000#!/bin/bash -l exec systemd-cat --identifier=miriway env MIRIWAY_SESSION_STARTUP="$SNAP/usr/libexec/miriway-session-startup-snap" MIRIWAY_SESSION_SHUTDOWN="$SNAP/usr/libexec/miriway-session-shutdown" miriway "$@" Miriway-Miriway-854d43d/snap-utils/bin/miriway-unconfine000077500000000000000000000004121521360756500233620ustar00rootroot00000000000000#! /bin/bash set -e if [ -d /sys/kernel/security/apparmor ] then if command -v aa-exec > /dev/null then exec aa-exec -p unconfined "$@" else echo "WARNING: AppArmor is installed, but aa-exec cannot found (needed to unconfine Miriway)" fi fi exec "$@"Miriway-Miriway-854d43d/snap-utils/usr/000077500000000000000000000000001521360756500200355ustar00rootroot00000000000000Miriway-Miriway-854d43d/snap-utils/usr/libexec/000077500000000000000000000000001521360756500214505ustar00rootroot00000000000000Miriway-Miriway-854d43d/snap-utils/usr/libexec/miriway-session-startup-snap000077500000000000000000000005121521360756500271750ustar00rootroot00000000000000#!/bin/sh -eu . "${SNAP}"/usr/libexec/miriway-session-startup "$@" # Run portals systemd-run --user --setenv=XDG_DESKTOP_PORTAL_DIR=${XDG_DESKTOP_PORTAL_DIR} $SNAP/usr/libexec/xdg-desktop-portal --replace systemd-run --user $SNAP/usr/local/libexec/xdg-desktop-portal-wlr --replace -c $SNAP/etc/xdg/xdg-desktop-portal-wlr/config Miriway-Miriway-854d43d/snap/000077500000000000000000000000001521360756500160665ustar00rootroot00000000000000Miriway-Miriway-854d43d/snap/hooks/000077500000000000000000000000001521360756500172115ustar00rootroot00000000000000Miriway-Miriway-854d43d/snap/hooks/configure000077500000000000000000000000121521360756500211110ustar00rootroot00000000000000#!/bin/sh Miriway-Miriway-854d43d/snap/hooks/install000077500000000000000000000135741521360756500206170ustar00rootroot00000000000000#!/bin/sh -e mkdir -p /usr/share/wayland-sessions/ /usr/lib/systemd/user/ sed -e s/miriway-session/miriway.session/ "$SNAP"/usr/share/wayland-sessions/miriway.desktop > /usr/share/wayland-sessions/miriway.desktop cp "$SNAP"/usr/lib/systemd/user/miriway-session.target /usr/lib/systemd/user/ xdg_config=/etc/xdg/xdg-miriway miriway_config="${xdg_config}/miriway-shell.config" yambar_config="${xdg_config}/yambar/config.yml" ################################################################### # Ensure we have a miriway-shell config file with the fixed options mkdir -p -m 755 "$(dirname "${miriway_config}")" cat < "${miriway_config}" x11-window-title=Miriway idle-timeout=600 app-env-amend=XDG_SESSION_TYPE=wayland:GTK_USE_PORTAL=0:XDG_CURRENT_DESKTOP=Miriway:GTK_A11Y=none ctrl-alt=t:miriway-unsnap /snap/${SNAP_INSTANCE_NAME}/current/usr/bin/miriway-terminal shell-component=miriway-background shell-component=yambar --config="${yambar_config}" shell-component=swaync shell-component=/snap/${SNAP_INSTANCE_NAME}/usr/libexec/polkit-mate-authentication-agent-1 shell-component=miriway-unsnap /snap/${SNAP_INSTANCE_NAME}/current/usr/bin/synapse --startup shell-meta=a:miriway-unsnap /snap/${SNAP_INSTANCE_NAME}/current/usr/bin/synapse meta=Left:@dock-left meta=Right:@dock-right meta=Space:@toggle-maximized meta=Home:@workspace-begin meta=End:@workspace-end meta=Page_Up:@workspace-up meta=Page_Down:@workspace-down ctrl-alt=BackSpace:@exit EOT # Ensure we have a miriway-shell config file with the fixed options ################################################################### ################################################################### # Ensure we have a yambar config file with the fixed options mkdir -p -m 755 "$(dirname "${yambar_config}")" cat < "${yambar_config}" awesome: &awesome Font Awesome 6 Free:style=solid:pixelsize=14 ubuntu: &ubuntu Font Ubuntu 6 Free:style=solid:pixelsize=14 bar: location: top height: 21 background: 282828ff font: *ubuntu left: - label: content: string: text: " start" margin: 5 on-click: miriway-unsnap /snap/${SNAP_INSTANCE_NAME}/current/usr/bin/synapse deco: &greybg background: color: 3f3f3fff center: - clock: content: - string: margin: 5 text: "{date} {time}" deco: *greybg right: EOT for wificard in /sys/class/net/wl* do cat <> "${yambar_config}" - network: name: $(basename "$wificard") content: map: deco: *greybg margin: 5 default: {string: {text: , font: *awesome}} conditions: state == down: {string: {text: , font: *awesome}} state == up: map: default: - string: {text: , font: *awesome, deco: *greybg} # - string: {text: "{ssid} {dl-speed:mb}/{ul-speed:mb} Mb/s" } conditions: ipv4 == "": - string: {text: , font: *awesome} # - string: {text: "{ssid} {dl-speed:mb}/{ul-speed:mb} Mb/s"} EOT done for battery in /sys/class/power_supply/BAT* do cat <> "${yambar_config}" - battery: name: $(basename "$battery") anchors: discharging: &discharging list: items: - ramp: tag: capacity items: - string: {text: , foreground: ff0000ff, font: *awesome} - string: {text: , foreground: ffa600ff, font: *awesome} - string: {text: , font: *awesome} - string: {text: , font: *awesome} - string: {text: , font: *awesome} - string: {text: , font: *awesome} - string: {text: , font: *awesome} - string: {text: , font: *awesome} - string: {text: , font: *awesome} - string: {text: , foreground: 00ff00ff, font: *awesome} - string: {text: "{capacity}% {estimate}"} content: map: deco: *greybg margin: 5 conditions: state == unknown: <<: *discharging state == discharging: <<: *discharging state == charging: - string: {text: , foreground: 00ff00ff, font: *awesome} - string: {text: "{capacity}% {estimate}"} state == full: - string: {text: , foreground: 00ff00ff, font: *awesome} - string: {text: "{capacity}% full"} state == "not charging": - ramp: tag: capacity items: - string: {text:  , foreground: ff0000ff, font: *awesome} - string: {text:  , foreground: ffa600ff, font: *awesome} - string: {text:  , foreground: 00ff00ff, font: *awesome} - string: {text:  , foreground: 00ff00ff, font: *awesome} - string: {text:  , foreground: 00ff00ff, font: *awesome} - string: {text:  , foreground: 00ff00ff, font: *awesome} - string: {text:  , foreground: 00ff00ff, font: *awesome} - string: {text:  , foreground: 00ff00ff, font: *awesome} - string: {text:  , foreground: 00ff00ff, font: *awesome} - string: {text:  , foreground: 00ff00ff, font: *awesome} - string: {text: "{capacity}%"} EOT done # Ensure we have a yambar config file with the fixed options ################################################################### Miriway-Miriway-854d43d/snap/hooks/post-refresh000077700000000000000000000000001521360756500231412installustar00rootroot00000000000000Miriway-Miriway-854d43d/snap/hooks/remove000077500000000000000000000002231521360756500204310ustar00rootroot00000000000000#!/bin/sh rm /usr/share/wayland-sessions/miriway.desktop /etc/xdg/xdg-miriway/miriway-shell.config rm /usr/lib/systemd/user/miriway-session.targetMiriway-Miriway-854d43d/snap/snapcraft.yaml000066400000000000000000000152341521360756500207400ustar00rootroot00000000000000name: miriway adopt-info: miriway summary: "Miriway: a graphical shell to configure for your desktop environment" description: | Miriway isn’t a full featured desktop environment by itself, but it could be used to build one. To provide a starting point here are some setup scripts: * /snap/miriway/current/example-configs/LXQT.bash * /snap/miriway/current/example-configs/MATE.bash * /snap/miriway/current/example-configs/SWAY.bash * /snap/miriway/current/example-configs/XFCE.bash * /snap/miriway/current/example-configs/alan_g.bash These are provided on a "best effort" basis as they rely on the current level of Wayland support from the corresponding components on the host OS. Miriway is based on Mir: https://mir-server.io/ website: https://github.com/Miriway contact: [https://github.com/Miriway/Miriway/discussions, https://matrix.to/#/#miriway:matrix.org] issues: https://github.com/Miriway/Miriway/issues source-code: https://github.com/Miriway/Miriway confinement: classic base: core24 platforms: amd64: arm64: armhf: package-repositories: - type: apt ppa: mir-team/release apps: miriway: command-chain: &command_chain # Workaround for classic snaps having a confinement profile - bin/miriway-unconfine command: &_command usr/bin/miriway environment: &_environment # Prep for Mir MIR_SERVER_PLATFORM_PATH: ${SNAP}/usr/lib/${CRAFT_ARCH_TRIPLET_BUILD_FOR}/mir/server-platform __EGL_VENDOR_LIBRARY_DIRS: ${SNAP}/etc/glvnd/egl_vendor.d:${SNAP}/usr/share/glvnd/egl_vendor.d GBM_BACKENDS_PATH: ${SNAP}/usr/lib/${CRAFT_ARCH_TRIPLET_BUILD_FOR}/gbm LIBGL_DRIVERS_PATH: ${SNAP}/usr/lib/${CRAFT_ARCH_TRIPLET_BUILD_FOR}/dri LIBINPUT_QUIRKS_DIR: ${SNAP}/usr/share/libinput PATH: ${SNAP}/bin/:${SNAP}/usr/bin/:${SNAP}/usr/local/bin/:${PATH} # Warning: This variable is used by xdg-desktop-portal to force it to look in # a particular directory for .portal files. Unfortunately, xdg-desktop-portal # does not respect XDG_DATA_DIRS so we are forced to use this workaround. This # environment variable is only intended to be used in their testing environment # but we are abusing it for our purposes here. XDG_DESKTOP_PORTAL_DIR: ${SNAP}/usr/share/xdg-desktop-portal/portals/ DRIRC_CONFIGDIR: ${SNAP}/usr/share/drirc.d session: command-chain: *command_chain command: bin/miriway-session environment: *_environment run: command-chain: - bin/miriway-unconfine command: usr/bin/miriway-run environment: *_environment parts: miriway: build-attributes: - enable-patchelf override-pull: | craftctl default # work around https://github.com/diddlesnaps/snapcraft-multiarch-action/issues/22 git config --global --add safe.directory ${CRAFT_PART_SRC} server_version=`git describe | cut -c 2-15` mir_version=`LANG=C apt-cache policy mir-graphics-drivers-desktop | sed -rne 's/^\s+Candidate:\s+([^-]*)-.+$/\1/p'` craftctl set version=$server_version-mir${mir_version} if echo $mir_version | grep -e '+dev' -e '~rc' -q; then craftctl set grade=devel; else craftctl set grade=stable; fi plugin: cmake cmake-parameters: - -DCMAKE_INSTALL_PREFIX=/usr source: . build-packages: - pkg-config - libmiral-dev - libmirwayland-dev - libboost-exception-dev - libboost-filesystem-dev - libfreetype-dev - libwayland-dev - libxkbcommon-dev - g++ - make - git # This is needed to satisfy the incorrect mirwayland.pc - see https://github.com/canonical/mir/pull/4313 - libmircommon-dev stage-packages: # Stage libmiral indirectly as we cannot (since core22) do `try:/else:` - libmiral-dev - mir-graphics-drivers-desktop - mir-platform-graphics-virtual - mir-graphics-drivers-nvidia - libfreetype6 - xdg-desktop-portal # included in this part because they are used in the snap - mate-polkit - sway-notification-center - swaybg - swaylock - synapse - xwayland - yambar # And try to get _all_ the mesa drivers - libgl1-mesa-dri - libdrm-nouveau2 - libdrm-amdgpu1 - libdrm-radeon1 - on amd64: - libdrm-intel1 - on arm64: - libdrm-etnaviv1 - libdrm-freedreno1 - libdrm-intel1 - libdrm-tegra0 - on armhf: - libdrm-etnaviv1 - libdrm-exynos1 - libdrm-freedreno1 - libdrm-omap1 - libdrm-tegra0 - on riscv64: - libdrm-intel1 prime: - -lib/udev - -usr/doc - -usr/doc-base - -usr/share/applications - -usr/share/apport - -usr/share/bug - -usr/share/doc - -usr/share/doc-base - -usr/share/icons - -usr/share/libdrm - -usr/share/libwacom - -usr/share/lintian - -usr/share/man - -usr/share/pkgconfig - -etc/xdg/xdg-miriway/miriway-shell.config-snap # We use another miriway-session (from snap-utils), avoid confusion - -usr/bin/miriway-session # Do not prime the `-dev` part of libmiral-dev, we don't need it (just the libmiral dependency) - -usr/include - -usr/lib/*/pkgconfig - -usr/lib/*/libmir*.so # The libgallium* library needs no-patchelf, so it comes from the mesa-unpatched part - -usr/lib/${CRAFT_ARCH_TRIPLET_BUILD_FOR}/libgallium* example-configs: plugin: dump source: example-configs organize: miriway-config-Budgie.bash: example-configs/Budgie.bash miriway-config-LXQt.bash: example-configs/LXQt.bash miriway-config-MATE.bash: example-configs/MATE.bash miriway-config-SWAY.bash: example-configs/SWAY.bash miriway-config-XFCE.bash: example-configs/XFCE.bash miriway-config-alan_g.bash: example-configs/alan_g.bash snap-utils: plugin: dump source: snap-utils systemd: plugin: dump source: systemd mesa-no-patchelf: plugin: nil stage-packages: - mesa-libgallium build-attributes: - no-patchelf # Otherwise snapcraft may strip the build ID and cause the driver to crash stage: - usr/lib/${CRAFT_ARCH_TRIPLET_BUILD_FOR}/libgallium* xdg-desktop-portal-wlr: plugin: meson source: https://github.com/emersion/xdg-desktop-portal-wlr.git source-tag: v0.5.0 build-attributes: - enable-patchelf build-packages: - meson - ninja-build - libpipewire-0.3-dev - libwayland-dev - libinih-dev - libsystemd-dev - wayland-protocols stage-packages: - slurp - libinih1 - libwayland-cursor0 - libcairo2 Miriway-Miriway-854d43d/systemd/000077500000000000000000000000001521360756500166155ustar00rootroot00000000000000Miriway-Miriway-854d43d/systemd/etc/000077500000000000000000000000001521360756500173705ustar00rootroot00000000000000Miriway-Miriway-854d43d/systemd/etc/xdg/000077500000000000000000000000001521360756500201525ustar00rootroot00000000000000Miriway-Miriway-854d43d/systemd/etc/xdg/xdg-desktop-portal-wlr/000077500000000000000000000000001521360756500245045ustar00rootroot00000000000000Miriway-Miriway-854d43d/systemd/etc/xdg/xdg-desktop-portal-wlr/config000066400000000000000000000001641521360756500256750ustar00rootroot00000000000000[screencast] max_fps=30 chooser_type=simple chooser_cmd=snap run --shell miriway -c "$SNAP/usr/bin/slurp -f %o -or" Miriway-Miriway-854d43d/systemd/usr/000077500000000000000000000000001521360756500174265ustar00rootroot00000000000000Miriway-Miriway-854d43d/systemd/usr/lib/000077500000000000000000000000001521360756500201745ustar00rootroot00000000000000Miriway-Miriway-854d43d/systemd/usr/lib/systemd/000077500000000000000000000000001521360756500216645ustar00rootroot00000000000000Miriway-Miriway-854d43d/systemd/usr/lib/systemd/user/000077500000000000000000000000001521360756500226425ustar00rootroot00000000000000Miriway-Miriway-854d43d/systemd/usr/lib/systemd/user/miriway-session.target000077500000000000000000000002561521360756500272220ustar00rootroot00000000000000[Unit] Description=Miriway session Documentation=man:systemd.special(7) BindsTo=graphical-session.target Wants=graphical-session-pre.target After=graphical-session-pre.targetMiriway-Miriway-854d43d/systemd/usr/libexec/000077500000000000000000000000001521360756500210415ustar00rootroot00000000000000Miriway-Miriway-854d43d/systemd/usr/libexec/miriway-session-shutdown000077500000000000000000000036511521360756500260070ustar00rootroot00000000000000#!/bin/sh -eu # # # Copyright (C) 2024 Matthew Kosarek # Copyright (C) 2024 Alan Griffiths # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # Portions of this code originate from https://github.com/alebastr/sway-systemd, # Portions of this code originate from https://github.com/miracle-wm-org/miracle-wm/blob/develop/session/usr/bin/libexec/miracle-wm-session-setup # licensed under the MIT license. See the LICENSE.sway-systemd file for details. # # 1. Stop the target and unset the variables when the compositor exits. # # References: # - https://github.com/swaywm/sway/wiki#gtk-applications-take-20-seconds-to-start # - https://github.com/emersion/xdg-desktop-portal-wlr/wiki/systemd-user-services,-pam,-and-environment-variables # - https://www.freedesktop.org/software/systemd/man/systemd.special.html#graphical-session.target # - https://systemd.io/DESKTOP_ENVIRONMENTS/ # export XDG_SESSION_DESKTOP="${XDG_SESSION_DESKTOP:-Miriway}" VARIABLES="DESKTOP_SESSION XDG_CURRENT_DESKTOP XDG_SESSION_DESKTOP XDG_SESSION_TYPE DISPLAY WAYLAND_DISPLAY" SESSION_TARGET="miriway-session.target" # shellcheck disable=SC2086 systemctl --user stop "$SESSION_TARGET" # stop the session target and unset the variables systemctl --user start --job-mode=replace-irreversibly "$SESSION_SHUTDOWN_TARGET" # shellcheck disable=SC2086 systemctl --user unset-environment $VARIABLES Miriway-Miriway-854d43d/systemd/usr/libexec/miriway-session-startup000077500000000000000000000111061521360756500256300ustar00rootroot00000000000000#!/bin/sh -eu # # # Copyright (C) 2024 Matthew Kosarek # Copyright (C) 2024 Alan Griffiths # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # Portions of this code originate from https://github.com/alebastr/sway-systemd, # Portions of this code originate from https://github.com/miracle-wm-org/miracle-wm/blob/develop/session/usr/bin/libexec/miracle-wm-session-setup # licensed under the MIT license. See the LICENSE.sway-systemd file for details. # # # # Address several issues with DBus activation and systemd user sessions # # 1. DBus-activated and systemd services do not share the environment with user # login session. In order to make the applications that have GUI or interact # with the compositor work as a systemd user service, certain variables must # be propagated to the systemd and dbus. # Possible (but not exhaustive) list of variables: # - DISPLAY - for X11 applications that are started as user session services # - WAYLAND_DISPLAY - similarly, this is needed for wayland-native services # # 2. `xdg-desktop-portal` requires XDG_CURRENT_DESKTOP to be set in order to # select the right implementation for portals. # # 3. GUI applications started as a systemd service (or via xdg-autostart-generator) # may rely on the XDG_SESSION_TYPE variable to select the backend. # Ensure that it is always set to `wayland`. # # 4. The common way to autostart a systemd service along with the desktop # environment is to add it to a `graphical-session.target`. However, systemd # forbids starting the graphical session target directly and encourages use # of an environment-specific target units. Therefore, the integration # package here provides and uses `miriway-session.target` which would bind to # the `graphical-session.target`. # # 5. Stop the target and unset the variables when the compositor exits. # # References: # - https://github.com/swaywm/sway/wiki#gtk-applications-take-20-seconds-to-start # - https://github.com/emersion/xdg-desktop-portal-wlr/wiki/systemd-user-services,-pam,-and-environment-variables # - https://www.freedesktop.org/software/systemd/man/systemd.special.html#graphical-session.target # - https://systemd.io/DESKTOP_ENVIRONMENTS/ # export XDG_SESSION_DESKTOP="${XDG_SESSION_DESKTOP:-Miriway}" export XDG_SESSION_TYPE=wayland VARIABLES="DESKTOP_SESSION XDG_CURRENT_DESKTOP XDG_SESSION_DESKTOP XDG_SESSION_TYPE DISPLAY WAYLAND_DISPLAY" SESSION_TARGET="miriway-session.target" print_usage() { cat <&2 print_usage exit 1 ;; *) break ;; esac shift done # Check if another Miriway session is already active. # # Ignores all other kinds of parallel or nested sessions # (Miriway on Gnome/KDE/X11/etc.), as the only way to detect these is to check # for (WAYLAND_)?DISPLAY and that is known to be broken on Arch. if systemctl --user -q is-active "$SESSION_TARGET"; then echo "Another session found; refusing to overwrite the variables" exit 1 fi # DBus activation environment is independent from systemd. While most of # dbus-activated services are already using `SystemdService` directive, some # still don't and thus we should set the dbus environment with a separate # command. if hash dbus-update-activation-environment 2>/dev/null; then # shellcheck disable=SC2086 dbus-update-activation-environment --systemd ${VARIABLES:- --all} fi # reset failed state of all user units systemctl --user reset-failed # shellcheck disable=SC2086 systemctl --user import-environment $VARIABLES systemctl --user start "$SESSION_TARGET" Miriway-Miriway-854d43d/systemd/usr/share/000077500000000000000000000000001521360756500205305ustar00rootroot00000000000000Miriway-Miriway-854d43d/systemd/usr/share/xdg-desktop-portal/000077500000000000000000000000001521360756500242605ustar00rootroot00000000000000Miriway-Miriway-854d43d/systemd/usr/share/xdg-desktop-portal/portals/000077500000000000000000000000001521360756500257445ustar00rootroot00000000000000Miriway-Miriway-854d43d/systemd/usr/share/xdg-desktop-portal/portals/mir.portal000066400000000000000000000002521521360756500277550ustar00rootroot00000000000000[portal] DBusName=org.freedesktop.impl.portal.desktop.wlr Interfaces=org.freedesktop.impl.portal.Screenshot;org.freedesktop.impl.portal.ScreenCast; UseIn=Miriway;Mir;mir Miriway-Miriway-854d43d/wayland-generated/000077500000000000000000000000001521360756500205205ustar00rootroot00000000000000Miriway-Miriway-854d43d/wayland-generated/CMakeLists.txt000066400000000000000000000013251521360756500232610ustar00rootroot00000000000000set(PROTOCOL "ext-workspace-v1") set(PROTOCOL_FILE "${CMAKE_CURRENT_SOURCE_DIR}/../wayland-protocols/${PROTOCOL}.xml") set(GENERATE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/ext-workspace-v1_wrapper") add_custom_command( OUTPUT ${GENERATE_FILE}.cpp OUTPUT ${GENERATE_FILE}.h DEPENDS ${PROTOCOL_FILE} COMMAND "sh" "-c" "mir_wayland_generator zwp_ ${PROTOCOL_FILE} header >${GENERATE_FILE}.h" COMMAND "sh" "-c" "mir_wayland_generator zwp_ ${PROTOCOL_FILE} source >${GENERATE_FILE}.cpp" ) add_custom_target(ext-workspace-v1 DEPENDS ${GENERATE_FILE}.cpp DEPENDS ${GENERATE_FILE}.h SOURCES ${GENERATE_FILE}.cpp ${GENERATE_FILE}.h ) set_directory_properties(PROPERTIES CLEAN_NO_CUSTOM 1) Miriway-Miriway-854d43d/wayland-generated/ext-workspace-v1_wrapper.cpp000066400000000000000000000453211521360756500261110ustar00rootroot00000000000000/* * AUTOGENERATED - DO NOT EDIT * * This file is generated from ext-workspace-v1.xml by mir_wayland_generator */ #include "ext-workspace-v1_wrapper.h" #include #include #include #include namespace mir { namespace wayland { extern struct wl_interface const ext_workspace_group_handle_v1_interface_data; extern struct wl_interface const ext_workspace_handle_v1_interface_data; extern struct wl_interface const ext_workspace_manager_v1_interface_data; extern struct wl_interface const wl_output_interface_data; } } namespace mw = mir::wayland; namespace { struct wl_interface const* all_null_types [] { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; } // ExtWorkspaceManagerV1 struct mw::ExtWorkspaceManagerV1::Thunks { static int const supported_version; static void commit_thunk(struct wl_client* client, struct wl_resource* resource) { try { auto me = static_cast(wl_resource_get_user_data(resource)); me->commit(); } catch(ProtocolError const& err) { wl_resource_post_error(err.resource(), err.code(), "%s", err.message()); } catch(...) { internal_error_processing_request(client, "ExtWorkspaceManagerV1::commit()"); } } static void stop_thunk(struct wl_client* client, struct wl_resource* resource) { try { auto me = static_cast(wl_resource_get_user_data(resource)); me->stop(); } catch(ProtocolError const& err) { wl_resource_post_error(err.resource(), err.code(), "%s", err.message()); } catch(...) { internal_error_processing_request(client, "ExtWorkspaceManagerV1::stop()"); } } static void resource_destroyed_thunk(wl_resource* resource) { delete static_cast(wl_resource_get_user_data(resource)); } static void bind_thunk(struct wl_client* client, void* data, uint32_t version, uint32_t id) { auto me = static_cast(data); auto resource = wl_resource_create( client, &ext_workspace_manager_v1_interface_data, std::min((int)version, Thunks::supported_version), id); if (resource == nullptr) { wl_client_post_no_memory(client); BOOST_THROW_EXCEPTION((std::bad_alloc{})); } try { me->bind(resource); } catch(...) { internal_error_processing_request(client, "ExtWorkspaceManagerV1 global bind"); } } static struct wl_interface const* workspace_group_types[]; static struct wl_interface const* workspace_types[]; static struct wl_message const request_messages[]; static struct wl_message const event_messages[]; static void const* request_vtable[]; }; int const mw::ExtWorkspaceManagerV1::Thunks::supported_version = 1; mw::ExtWorkspaceManagerV1::ExtWorkspaceManagerV1(struct wl_resource* resource, Version<1>) : Resource{resource} { wl_resource_set_implementation(resource, Thunks::request_vtable, this, &Thunks::resource_destroyed_thunk); } mw::ExtWorkspaceManagerV1::~ExtWorkspaceManagerV1() { wl_resource_set_implementation(resource, nullptr, nullptr, nullptr); } void mw::ExtWorkspaceManagerV1::send_workspace_group_event(struct wl_resource* workspace_group) const { wl_resource_post_event(resource, Opcode::workspace_group, workspace_group); } void mw::ExtWorkspaceManagerV1::send_workspace_event(struct wl_resource* workspace) const { wl_resource_post_event(resource, Opcode::workspace, workspace); } void mw::ExtWorkspaceManagerV1::send_done_event() const { wl_resource_post_event(resource, Opcode::done); } void mw::ExtWorkspaceManagerV1::send_finished_event() const { wl_resource_post_event(resource, Opcode::finished); } bool mw::ExtWorkspaceManagerV1::is_instance(wl_resource* resource) { return wl_resource_instance_of(resource, &ext_workspace_manager_v1_interface_data, Thunks::request_vtable); } void mw::ExtWorkspaceManagerV1::destroy_and_delete() const { // Will result in this object being deleted wl_resource_destroy(resource); } mw::ExtWorkspaceManagerV1::Global::Global(wl_display* display, Version<1>) : wayland::Global{ wl_global_create( display, &ext_workspace_manager_v1_interface_data, Thunks::supported_version, this, &Thunks::bind_thunk)} { } auto mw::ExtWorkspaceManagerV1::Global::interface_name() const -> char const* { return ExtWorkspaceManagerV1::interface_name; } struct wl_interface const* mw::ExtWorkspaceManagerV1::Thunks::workspace_group_types[] { &ext_workspace_group_handle_v1_interface_data}; struct wl_interface const* mw::ExtWorkspaceManagerV1::Thunks::workspace_types[] { &ext_workspace_handle_v1_interface_data}; struct wl_message const mw::ExtWorkspaceManagerV1::Thunks::request_messages[] { {"commit", "", all_null_types}, {"stop", "", all_null_types}}; struct wl_message const mw::ExtWorkspaceManagerV1::Thunks::event_messages[] { {"workspace_group", "n", workspace_group_types}, {"workspace", "n", workspace_types}, {"done", "", all_null_types}, {"finished", "", all_null_types}}; void const* mw::ExtWorkspaceManagerV1::Thunks::request_vtable[] { (void*)Thunks::commit_thunk, (void*)Thunks::stop_thunk}; mw::ExtWorkspaceManagerV1* mw::ExtWorkspaceManagerV1::from(struct wl_resource* resource) { if (resource && wl_resource_instance_of(resource, &ext_workspace_manager_v1_interface_data, ExtWorkspaceManagerV1::Thunks::request_vtable)) { return static_cast(wl_resource_get_user_data(resource)); } else { return nullptr; } } // ExtWorkspaceGroupHandleV1 struct mw::ExtWorkspaceGroupHandleV1::Thunks { static int const supported_version; static void create_workspace_thunk(struct wl_client* client, struct wl_resource* resource, char const* workspace) { try { auto me = static_cast(wl_resource_get_user_data(resource)); me->create_workspace(workspace); } catch(ProtocolError const& err) { wl_resource_post_error(err.resource(), err.code(), "%s", err.message()); } catch(...) { internal_error_processing_request(client, "ExtWorkspaceGroupHandleV1::create_workspace()"); } } static void destroy_thunk(struct wl_client* client, struct wl_resource* resource) { try { auto me = static_cast(wl_resource_get_user_data(resource)); me->destroy(); wl_resource_destroy(resource); } catch(ProtocolError const& err) { wl_resource_post_error(err.resource(), err.code(), "%s", err.message()); } catch(...) { internal_error_processing_request(client, "ExtWorkspaceGroupHandleV1::destroy()"); } } static void resource_destroyed_thunk(wl_resource* resource) { delete static_cast(wl_resource_get_user_data(resource)); } static struct wl_interface const* output_enter_types[]; static struct wl_interface const* output_leave_types[]; static struct wl_interface const* workspace_enter_types[]; static struct wl_interface const* workspace_leave_types[]; static struct wl_message const request_messages[]; static struct wl_message const event_messages[]; static void const* request_vtable[]; }; int const mw::ExtWorkspaceGroupHandleV1::Thunks::supported_version = 1; mw::ExtWorkspaceGroupHandleV1::ExtWorkspaceGroupHandleV1(ExtWorkspaceManagerV1 const& parent) : Resource{wl_resource_create( wl_resource_get_client(parent.resource), &ext_workspace_group_handle_v1_interface_data, wl_resource_get_version(parent.resource), 0)} { wl_resource_set_implementation(resource, Thunks::request_vtable, this, &Thunks::resource_destroyed_thunk); } mw::ExtWorkspaceGroupHandleV1::~ExtWorkspaceGroupHandleV1() { wl_resource_set_implementation(resource, nullptr, nullptr, nullptr); } void mw::ExtWorkspaceGroupHandleV1::send_capabilities_event(uint32_t capabilities) const { wl_resource_post_event(resource, Opcode::capabilities, capabilities); } void mw::ExtWorkspaceGroupHandleV1::send_output_enter_event(struct wl_resource* output) const { wl_resource_post_event(resource, Opcode::output_enter, output); } void mw::ExtWorkspaceGroupHandleV1::send_output_leave_event(struct wl_resource* output) const { wl_resource_post_event(resource, Opcode::output_leave, output); } void mw::ExtWorkspaceGroupHandleV1::send_workspace_enter_event(struct wl_resource* workspace) const { wl_resource_post_event(resource, Opcode::workspace_enter, workspace); } void mw::ExtWorkspaceGroupHandleV1::send_workspace_leave_event(struct wl_resource* workspace) const { wl_resource_post_event(resource, Opcode::workspace_leave, workspace); } void mw::ExtWorkspaceGroupHandleV1::send_removed_event() const { wl_resource_post_event(resource, Opcode::removed); } bool mw::ExtWorkspaceGroupHandleV1::is_instance(wl_resource* resource) { return wl_resource_instance_of(resource, &ext_workspace_group_handle_v1_interface_data, Thunks::request_vtable); } uint32_t const mw::ExtWorkspaceGroupHandleV1::GroupCapabilities::create_workspace; struct wl_interface const* mw::ExtWorkspaceGroupHandleV1::Thunks::output_enter_types[] { &wl_output_interface_data}; struct wl_interface const* mw::ExtWorkspaceGroupHandleV1::Thunks::output_leave_types[] { &wl_output_interface_data}; struct wl_interface const* mw::ExtWorkspaceGroupHandleV1::Thunks::workspace_enter_types[] { &ext_workspace_handle_v1_interface_data}; struct wl_interface const* mw::ExtWorkspaceGroupHandleV1::Thunks::workspace_leave_types[] { &ext_workspace_handle_v1_interface_data}; struct wl_message const mw::ExtWorkspaceGroupHandleV1::Thunks::request_messages[] { {"create_workspace", "s", all_null_types}, {"destroy", "", all_null_types}}; struct wl_message const mw::ExtWorkspaceGroupHandleV1::Thunks::event_messages[] { {"capabilities", "u", all_null_types}, {"output_enter", "o", output_enter_types}, {"output_leave", "o", output_leave_types}, {"workspace_enter", "o", workspace_enter_types}, {"workspace_leave", "o", workspace_leave_types}, {"removed", "", all_null_types}}; void const* mw::ExtWorkspaceGroupHandleV1::Thunks::request_vtable[] { (void*)Thunks::create_workspace_thunk, (void*)Thunks::destroy_thunk}; mw::ExtWorkspaceGroupHandleV1* mw::ExtWorkspaceGroupHandleV1::from(struct wl_resource* resource) { if (resource && wl_resource_instance_of(resource, &ext_workspace_group_handle_v1_interface_data, ExtWorkspaceGroupHandleV1::Thunks::request_vtable)) { return static_cast(wl_resource_get_user_data(resource)); } else { return nullptr; } } // ExtWorkspaceHandleV1 struct mw::ExtWorkspaceHandleV1::Thunks { static int const supported_version; static void destroy_thunk(struct wl_client* client, struct wl_resource* resource) { try { auto me = static_cast(wl_resource_get_user_data(resource)); me->destroy(); wl_resource_destroy(resource); } catch(ProtocolError const& err) { wl_resource_post_error(err.resource(), err.code(), "%s", err.message()); } catch(...) { internal_error_processing_request(client, "ExtWorkspaceHandleV1::destroy()"); } } static void activate_thunk(struct wl_client* client, struct wl_resource* resource) { try { auto me = static_cast(wl_resource_get_user_data(resource)); me->activate(); } catch(ProtocolError const& err) { wl_resource_post_error(err.resource(), err.code(), "%s", err.message()); } catch(...) { internal_error_processing_request(client, "ExtWorkspaceHandleV1::activate()"); } } static void deactivate_thunk(struct wl_client* client, struct wl_resource* resource) { try { auto me = static_cast(wl_resource_get_user_data(resource)); me->deactivate(); } catch(ProtocolError const& err) { wl_resource_post_error(err.resource(), err.code(), "%s", err.message()); } catch(...) { internal_error_processing_request(client, "ExtWorkspaceHandleV1::deactivate()"); } } static void assign_thunk(struct wl_client* client, struct wl_resource* resource, struct wl_resource* workspace_group) { try { auto me = static_cast(wl_resource_get_user_data(resource)); me->assign(workspace_group); } catch(ProtocolError const& err) { wl_resource_post_error(err.resource(), err.code(), "%s", err.message()); } catch(...) { internal_error_processing_request(client, "ExtWorkspaceHandleV1::assign()"); } } static void remove_thunk(struct wl_client* client, struct wl_resource* resource) { try { auto me = static_cast(wl_resource_get_user_data(resource)); me->remove(); } catch(ProtocolError const& err) { wl_resource_post_error(err.resource(), err.code(), "%s", err.message()); } catch(...) { internal_error_processing_request(client, "ExtWorkspaceHandleV1::remove()"); } } static void resource_destroyed_thunk(wl_resource* resource) { delete static_cast(wl_resource_get_user_data(resource)); } static struct wl_interface const* assign_types[]; static struct wl_message const request_messages[]; static struct wl_message const event_messages[]; static void const* request_vtable[]; }; int const mw::ExtWorkspaceHandleV1::Thunks::supported_version = 1; mw::ExtWorkspaceHandleV1::ExtWorkspaceHandleV1(ExtWorkspaceManagerV1 const& parent) : Resource{wl_resource_create( wl_resource_get_client(parent.resource), &ext_workspace_handle_v1_interface_data, wl_resource_get_version(parent.resource), 0)} { wl_resource_set_implementation(resource, Thunks::request_vtable, this, &Thunks::resource_destroyed_thunk); } mw::ExtWorkspaceHandleV1::~ExtWorkspaceHandleV1() { wl_resource_set_implementation(resource, nullptr, nullptr, nullptr); } void mw::ExtWorkspaceHandleV1::send_id_event(std::string const& id) const { const char* id_resolved = id.c_str(); wl_resource_post_event(resource, Opcode::id, id_resolved); } void mw::ExtWorkspaceHandleV1::send_name_event(std::string const& name) const { const char* name_resolved = name.c_str(); wl_resource_post_event(resource, Opcode::name, name_resolved); } void mw::ExtWorkspaceHandleV1::send_coordinates_event(struct wl_array* coordinates) const { wl_resource_post_event(resource, Opcode::coordinates, coordinates); } void mw::ExtWorkspaceHandleV1::send_state_event(uint32_t state) const { wl_resource_post_event(resource, Opcode::state, state); } void mw::ExtWorkspaceHandleV1::send_capabilities_event(uint32_t capabilities) const { wl_resource_post_event(resource, Opcode::capabilities, capabilities); } void mw::ExtWorkspaceHandleV1::send_removed_event() const { wl_resource_post_event(resource, Opcode::removed); } bool mw::ExtWorkspaceHandleV1::is_instance(wl_resource* resource) { return wl_resource_instance_of(resource, &ext_workspace_handle_v1_interface_data, Thunks::request_vtable); } uint32_t const mw::ExtWorkspaceHandleV1::State::active; uint32_t const mw::ExtWorkspaceHandleV1::State::urgent; uint32_t const mw::ExtWorkspaceHandleV1::State::hidden; uint32_t const mw::ExtWorkspaceHandleV1::WorkspaceCapabilities::activate; uint32_t const mw::ExtWorkspaceHandleV1::WorkspaceCapabilities::deactivate; uint32_t const mw::ExtWorkspaceHandleV1::WorkspaceCapabilities::remove; uint32_t const mw::ExtWorkspaceHandleV1::WorkspaceCapabilities::assign; struct wl_interface const* mw::ExtWorkspaceHandleV1::Thunks::assign_types[] { &ext_workspace_group_handle_v1_interface_data}; struct wl_message const mw::ExtWorkspaceHandleV1::Thunks::request_messages[] { {"destroy", "", all_null_types}, {"activate", "", all_null_types}, {"deactivate", "", all_null_types}, {"assign", "o", assign_types}, {"remove", "", all_null_types}}; struct wl_message const mw::ExtWorkspaceHandleV1::Thunks::event_messages[] { {"id", "s", all_null_types}, {"name", "s", all_null_types}, {"coordinates", "a", all_null_types}, {"state", "u", all_null_types}, {"capabilities", "u", all_null_types}, {"removed", "", all_null_types}}; void const* mw::ExtWorkspaceHandleV1::Thunks::request_vtable[] { (void*)Thunks::destroy_thunk, (void*)Thunks::activate_thunk, (void*)Thunks::deactivate_thunk, (void*)Thunks::assign_thunk, (void*)Thunks::remove_thunk}; mw::ExtWorkspaceHandleV1* mw::ExtWorkspaceHandleV1::from(struct wl_resource* resource) { if (resource && wl_resource_instance_of(resource, &ext_workspace_handle_v1_interface_data, ExtWorkspaceHandleV1::Thunks::request_vtable)) { return static_cast(wl_resource_get_user_data(resource)); } else { return nullptr; } } namespace mir { namespace wayland { struct wl_interface const ext_workspace_manager_v1_interface_data { mw::ExtWorkspaceManagerV1::interface_name, mw::ExtWorkspaceManagerV1::Thunks::supported_version, 2, mw::ExtWorkspaceManagerV1::Thunks::request_messages, 4, mw::ExtWorkspaceManagerV1::Thunks::event_messages}; struct wl_interface const ext_workspace_group_handle_v1_interface_data { mw::ExtWorkspaceGroupHandleV1::interface_name, mw::ExtWorkspaceGroupHandleV1::Thunks::supported_version, 2, mw::ExtWorkspaceGroupHandleV1::Thunks::request_messages, 6, mw::ExtWorkspaceGroupHandleV1::Thunks::event_messages}; struct wl_interface const ext_workspace_handle_v1_interface_data { mw::ExtWorkspaceHandleV1::interface_name, mw::ExtWorkspaceHandleV1::Thunks::supported_version, 5, mw::ExtWorkspaceHandleV1::Thunks::request_messages, 6, mw::ExtWorkspaceHandleV1::Thunks::event_messages}; } } Miriway-Miriway-854d43d/wayland-generated/ext-workspace-v1_wrapper.h000066400000000000000000000111151521360756500255500ustar00rootroot00000000000000/* * AUTOGENERATED - DO NOT EDIT * * This file is generated from ext-workspace-v1.xml by mir_wayland_generator */ #ifndef MIR_FRONTEND_WAYLAND_EXT_WORKSPACE_V1_XML_WRAPPER #define MIR_FRONTEND_WAYLAND_EXT_WORKSPACE_V1_XML_WRAPPER #include #include #include #include #include namespace mir { namespace wayland { class ExtWorkspaceManagerV1; class ExtWorkspaceGroupHandleV1; class ExtWorkspaceHandleV1; class ExtWorkspaceManagerV1 : public Resource { public: static char const constexpr* interface_name = "ext_workspace_manager_v1"; static ExtWorkspaceManagerV1* from(struct wl_resource*); ExtWorkspaceManagerV1(struct wl_resource* resource, Version<1>); virtual ~ExtWorkspaceManagerV1(); void send_workspace_group_event(struct wl_resource* workspace_group) const; void send_workspace_event(struct wl_resource* workspace) const; void send_done_event() const; void send_finished_event() const; void destroy_and_delete() const; struct Opcode { static uint32_t const workspace_group = 0; static uint32_t const workspace = 1; static uint32_t const done = 2; static uint32_t const finished = 3; }; struct Thunks; static bool is_instance(wl_resource* resource); class Global : public wayland::Global { public: Global(wl_display* display, Version<1>); auto interface_name() const -> char const* override; private: virtual void bind(wl_resource* new_ext_workspace_manager_v1) = 0; friend ExtWorkspaceManagerV1::Thunks; }; private: virtual void commit() = 0; virtual void stop() = 0; }; class ExtWorkspaceGroupHandleV1 : public Resource { public: static char const constexpr* interface_name = "ext_workspace_group_handle_v1"; static ExtWorkspaceGroupHandleV1* from(struct wl_resource*); ExtWorkspaceGroupHandleV1(ExtWorkspaceManagerV1 const& parent); virtual ~ExtWorkspaceGroupHandleV1(); void send_capabilities_event(uint32_t capabilities) const; void send_output_enter_event(struct wl_resource* output) const; void send_output_leave_event(struct wl_resource* output) const; void send_workspace_enter_event(struct wl_resource* workspace) const; void send_workspace_leave_event(struct wl_resource* workspace) const; void send_removed_event() const; struct GroupCapabilities { static uint32_t const create_workspace = 1; }; struct Opcode { static uint32_t const capabilities = 0; static uint32_t const output_enter = 1; static uint32_t const output_leave = 2; static uint32_t const workspace_enter = 3; static uint32_t const workspace_leave = 4; static uint32_t const removed = 5; }; struct Thunks; static bool is_instance(wl_resource* resource); private: virtual void create_workspace(std::string const& workspace) = 0; virtual void destroy() {} }; class ExtWorkspaceHandleV1 : public Resource { public: static char const constexpr* interface_name = "ext_workspace_handle_v1"; static ExtWorkspaceHandleV1* from(struct wl_resource*); ExtWorkspaceHandleV1(ExtWorkspaceManagerV1 const& parent); virtual ~ExtWorkspaceHandleV1(); void send_id_event(std::string const& id) const; void send_name_event(std::string const& name) const; void send_coordinates_event(struct wl_array* coordinates) const; void send_state_event(uint32_t state) const; void send_capabilities_event(uint32_t capabilities) const; void send_removed_event() const; struct State { static uint32_t const active = 1; static uint32_t const urgent = 2; static uint32_t const hidden = 4; }; struct WorkspaceCapabilities { static uint32_t const activate = 1; static uint32_t const deactivate = 2; static uint32_t const remove = 4; static uint32_t const assign = 8; }; struct Opcode { static uint32_t const id = 0; static uint32_t const name = 1; static uint32_t const coordinates = 2; static uint32_t const state = 3; static uint32_t const capabilities = 4; static uint32_t const removed = 5; }; struct Thunks; static bool is_instance(wl_resource* resource); private: virtual void destroy() {} virtual void activate() = 0; virtual void deactivate() = 0; virtual void assign(struct wl_resource* workspace_group) = 0; virtual void remove() = 0; }; } } #endif // MIR_FRONTEND_WAYLAND_EXT_WORKSPACE_V1_XML_WRAPPER Miriway-Miriway-854d43d/wayland-protocols/000077500000000000000000000000001521360756500206065ustar00rootroot00000000000000Miriway-Miriway-854d43d/wayland-protocols/ext-workspace-v1.xml000066400000000000000000000461711521360756500244610ustar00rootroot00000000000000 Copyright © 2019 Christopher Billington Copyright © 2020 Ilia Bozhinov Copyright © 2022 Victoria Brekenfeld Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of the copyright holders not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. The copyright holders make no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. Workspaces, also called virtual desktops, are groups of surfaces. A compositor with a concept of workspaces may only show some such groups of surfaces (those of 'active' workspaces) at a time. 'Activating' a workspace is a request for the compositor to display that workspace's surfaces as normal, whereas the compositor may hide or otherwise de-emphasise surfaces that are associated only with 'inactive' workspaces. Workspaces are grouped by which sets of outputs they correspond to, and may contain surfaces only from those outputs. In this way, it is possible for each output to have its own set of workspaces, or for all outputs (or any other arbitrary grouping) to share workspaces. Compositors may optionally conceptually arrange each group of workspaces in an N-dimensional grid. The purpose of this protocol is to enable the creation of taskbars and docks by providing them with a list of workspaces and their properties, and allowing them to activate and deactivate workspaces. After a client binds the ext_workspace_manager_v1, each workspace will be sent via the workspace event. This event is emitted whenever a new workspace group has been created. All initial details of the workspace group (outputs) will be sent immediately after this event via the corresponding events in ext_workspace_group_handle_v1 and ext_workspace_handle_v1. This event is emitted whenever a new workspace has been created. All initial details of the workspace (name, coordinates, state) will be sent immediately after this event via the corresponding events in ext_workspace_handle_v1. Workspaces start off unassigned to any workspace group. The client must send this request after it has finished sending other requests. The compositor must process a series of requests preceding a commit request atomically. This allows changes to the workspace properties to be seen as atomic, even if they happen via multiple events, and even if they involve multiple ext_workspace_handle_v1 objects, for example, deactivating one workspace and activating another. This event is sent after all changes in all workspaces and workspace groups have been sent. This allows changes to one or more ext_workspace_group_handle_v1 properties and ext_workspace_handle_v1 properties to be seen as atomic, even if they happen via multiple events. In particular, an output moving from one workspace group to another sends an output_enter event and an output_leave event to the two ext_workspace_group_handle_v1 objects in question. The compositor sends the done event only after updating the output information in both workspace groups. This event indicates that the compositor is done sending events to the ext_workspace_manager_v1. The server will destroy the object immediately after sending this request. Indicates the client no longer wishes to receive events for new workspace groups. However the compositor may emit further workspace events, until the finished event is emitted. The compositor is expected to send the finished event eventually once the stop request has been processed. The client must not send any requests after this one, doing so will raise a wl_display invalid_object error. A ext_workspace_group_handle_v1 object represents a workspace group that is assigned a set of outputs and contains a number of workspaces. The set of outputs assigned to the workspace group is conveyed to the client via output_enter and output_leave events, and its workspaces are conveyed with workspace events. For example, a compositor which has a set of workspaces for each output may advertise a workspace group (and its workspaces) per output, whereas a compositor where a workspace spans all outputs may advertise a single workspace group for all outputs. This event advertises the capabilities supported by the compositor. If a capability isn't supported, clients should hide or disable the UI elements that expose this functionality. For instance, if the compositor doesn't advertise support for creating workspaces, a button triggering the create_workspace request should not be displayed. The compositor will ignore requests it doesn't support. For instance, a compositor which doesn't advertise support for creating workspaces will ignore create_workspace requests. Compositors must send this event once after creation of an ext_workspace_group_handle_v1. When the capabilities change, compositors must send this event again. This event is emitted whenever an output is assigned to the workspace group or a new `wl_output` object is bound by the client, which was already assigned to this workspace_group. This event is emitted whenever an output is removed from the workspace group. This event is emitted whenever a workspace is assigned to this group. A workspace may only ever be assigned to a single group at a single point in time, but can be re-assigned during it's lifetime. This event is emitted whenever a workspace is removed from this group. This event is send when the group associated with the ext_workspace_group_handle_v1 has been removed. After sending this request the compositor will immediately consider the object inert. Any requests will be ignored except the destroy request. It is guaranteed there won't be any more events referencing this ext_workspace_group_handle_v1. The compositor must remove all workspaces belonging to a workspace group via a workspace_leave event before removing the workspace group. Request that the compositor create a new workspace with the given name and assign it to this group. There is no guarantee that the compositor will create a new workspace, or that the created workspace will have the provided name. Destroys the ext_workspace_group_handle_v1 object. This request should be send either when the client does not want to use the workspace group object any more or after the removed event to finalize the destruction of the object. A ext_workspace_handle_v1 object represents a workspace that handles a group of surfaces. Each workspace has: - a name, conveyed to the client with the name event - potentially an id conveyed with the id event - a list of states, conveyed to the client with the state event - and optionally a set of coordinates, conveyed to the client with the coordinates event The client may request that the compositor activate or deactivate the workspace. Each workspace can belong to only a single workspace group. Depepending on the compositor policy, there might be workspaces with the same name in different workspace groups, but these workspaces are still separate (e.g. one of them might be active while the other is not). If this event is emitted, it will be send immediately after the ext_workspace_handle_v1 is created or when an id is assigned to a workspace (at most once during it's lifetime). An id will never change during the lifetime of the `ext_workspace_handle_v1` and is guaranteed to be unique during it's lifetime. Ids are not human-readable and shouldn't be displayed, use `name` for that purpose. Compositors are expected to only send ids for workspaces likely stable across multiple sessions and can be used by clients to store preferences for workspaces. Workspaces without ids should be considered temporary and any data associated with them should be deleted once the respective object is lost. This event is emitted immediately after the ext_workspace_handle_v1 is created and whenever the name of the workspace changes. A name is meant to be human-readable and can be displayed to a user. Unlike the id it is neither stable nor unique. This event is used to organize workspaces into an N-dimensional grid within a workspace group, and if supported, is emitted immediately after the ext_workspace_handle_v1 is created and whenever the coordinates of the workspace change. Compositors may not send this event if they do not conceptually arrange workspaces in this way. If compositors simply number workspaces, without any geometric interpretation, they may send 1D coordinates, which clients should not interpret as implying any geometry. Sending an empty array means that the compositor no longer orders the workspace geometrically. Coordinates have an arbitrary number of dimensions N with an uint32 position along each dimension. By convention if N > 1, the first dimension is X, the second Y, the third Z, and so on. The compositor may chose to utilize these events for a more novel workspace layout convention, however. No guarantee is made about the grid being filled or bounded; there may be a workspace at coordinate 1 and another at coordinate 1000 and none in between. Within a workspace group, however, workspaces must have unique coordinates of equal dimensionality. The different states that a workspace can have. The workspace is not visible in its workspace group, and clients attempting to visualize the compositor workspace state should not display such workspaces. This event is emitted immediately after the ext_workspace_handle_v1 is created and each time the workspace state changes, either because of a compositor action or because of a request in this protocol. Missing states convey the opposite meaning, e.g. an unset active bit means the workspace is currently inactive. This event advertises the capabilities supported by the compositor. If a capability isn't supported, clients should hide or disable the UI elements that expose this functionality. For instance, if the compositor doesn't advertise support for removing workspaces, a button triggering the remove request should not be displayed. The compositor will ignore requests it doesn't support. For instance, a compositor which doesn't advertise support for remove will ignore remove requests. Compositors must send this event once after creation of an ext_workspace_handle_v1 . When the capabilities change, compositors must send this event again. This event is send when the workspace associated with the ext_workspace_handle_v1 has been removed. After sending this request, the compositor will immediately consider the object inert. Any requests will be ignored except the destroy request. It is guaranteed there won't be any more events referencing this ext_workspace_handle_v1. The compositor must only remove a workspaces not currently belonging to any workspace_group. Destroys the ext_workspace_handle_v1 object. This request should be made either when the client does not want to use the workspace object any more or after the remove event to finalize the destruction of the object. Request that this workspace be activated. There is no guarantee the workspace will be actually activated, and behaviour may be compositor-dependent. For example, activating a workspace may or may not deactivate all other workspaces in the same group. Request that this workspace be deactivated. There is no guarantee the workspace will be actually deactivated. Requests that this workspace is assigned to the given workspace group. There is no guarantee the workspace will be assigned. Request that this workspace be removed. There is no guarantee the workspace will be actually removed.