pax_global_header00006660000000000000000000000064144701633350014520gustar00rootroot0000000000000052 comment=c188da67be7e11233052e65cf765b7c2eeffcc18 lxi-tools-2.7/000077500000000000000000000000001447016333500133225ustar00rootroot00000000000000lxi-tools-2.7/.circleci/000077500000000000000000000000001447016333500151555ustar00rootroot00000000000000lxi-tools-2.7/.circleci/config.yml000066400000000000000000000025521447016333500171510ustar00rootroot00000000000000# Use the latest 2.1 version of CircleCI pipeline process engine. # See: https://circleci.com/docs/2.0/configuration-reference version: 2.1 # Define a job to be invoked later in a workflow. # See: https://circleci.com/docs/2.0/configuration-reference/#jobs jobs: build-lxi-tools: # Specify the execution environment. You can specify an image from Dockerhub or use one of our Convenience Images from CircleCI's Developer Hub. # See: https://circleci.com/docs/2.0/configuration-reference/#docker-machine-macos-windows-executor docker: - image: cimg/base:edge # Add steps to the job # See: https://circleci.com/docs/2.0/configuration-reference/#steps steps: - checkout - run: sudo apt-get -qq update - run: sudo apt-get install -y libreadline-dev liblua5.3-dev bash-completion libtirpc-dev libavahi-common-dev libavahi-client-dev libxml2-dev git meson - run: git clone https://github.com/lxi-tools/liblxi.git - run: cd liblxi && meson build --prefix $HOME/test/liblxi && ninja -C build install - run: PKG_CONFIG_PATH=$HOME/test/liblxi/lib/x86_64-linux-gnu/pkgconfig meson build --prefix=$HOME/test/lxi-tools -Dgui=false && ninja -C build install # Invoke jobs via workflows # See: https://circleci.com/docs/2.0/configuration-reference/#workflows workflows: build-lxi-tools-workflow: jobs: - build-lxi-tools lxi-tools-2.7/.github/000077500000000000000000000000001447016333500146625ustar00rootroot00000000000000lxi-tools-2.7/.github/FUNDING.yml000066400000000000000000000000521447016333500164740ustar00rootroot00000000000000custom: ["https://www.paypal.me/lundmar"] lxi-tools-2.7/.gitignore000066400000000000000000000003061447016333500153110ustar00rootroot00000000000000/subprojects/*/ /subprojects/gi-docgen.wrap /subprojects/pango.wrap /subprojects/gobject-introspection.wrap /subprojects/graphene.wrap /subprojects/mutest.wrap build .DS_Store *.swp *.tar.xz .cache lxi-tools-2.7/AUTHORS000066400000000000000000000021221447016333500143670ustar00rootroot00000000000000Maintainer: Martin Lund Contributors: Robert Scheck Jakub Wilk RoGeorge in EEVBlog forum dpenev in EEVBlog forum PeDre in EEVBlog forum BloodyCactus in EEVBlog forum crispus in EEVBlog forum ralphrmartin in EEVBlog forum Dmitri Goutnik Hydron in EEVBlog forum gsocker in EEVBlog forum N0NB in EEVBlog forum Timur Aydin timber23 in EEVBlog forum Uli Köhler Mete Balci Heiko Jakob Sam Harry Tzavaras werwaswarum on GitHub Mete Balci Martino Ferrari htro globalcitizen on GitHub Eddie Adrian Scripca Perry Hung bombsquad81 on GitHub Twilight-Logic Johan Heikkila Walter Stanish on GitHub Roger Saltsman JanSchmidt3 on GitHub MarkSupp on GitHub Thanks to everyone who has contributed to this project. lxi-tools-2.7/LICENSE000066400000000000000000000027541447016333500143370ustar00rootroot00000000000000BSD 3-Clause License Copyright (c) 2016-2022 Martin Lund All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. lxi-tools-2.7/NEWS000066400000000000000000000521031447016333500140220ustar00rootroot00000000000000=== lxi-tools v2.7 === Changes since lxi-tools v2.6: * Fix print() when using lxi-gui Redirect output of print() to gui console window. * Disable getenv in lua example Maybe crash if TERM is not defined (nil) * Do not use deprecated math.pow in lua example * Add simple connect examples * Add homebrew to installation notes * Add NGL202 to list of tested instruments Changes since lxi-tools v2.5: * Update postinstall.py to use gtk4-update-icon-cache Use gtk4-update-icon-cache instead of gtk-update-icon-cache which is only for gtk3. * Add Rigol MSO4024/4054 to list of supported instruments * Add screenshot support for Rigol DS4000 series * Add screenshot plugin support for Rigol MSO5000 series Changes since lxi-tools v2.4: * Add new screenshot plugins Add screenshot plugins to support: * Tektronix MSO 5 series * Rohde & Schwarz RTH series (hand help oscillopes) * Add code for backwards compatibility with lua 5.0/5.1 Twilight-Logic: * Updated rigol-2000 plugin to allow screenshot capture on MSO5000 Changes since lxi-tools v2.3: * Prefix all lua functions with lxi_ To avoid conflict with existing lua APIs. Changes since lxi-tools v2.2: * Fix copy of IP and ID * Also autocomplete lxi-tools.lxi * Update LICENSE Changes since lxi-tools v2.1: * Add support for manually adding instruments Manually added instruments are managed via settings in the dconf registry so that they can be remembered by the application. Manually added instruments will appear with an instrument icon with a yellow indicator (indicating that it may or may not be present). Automatically discovered instruments will appear with an instrument icon with a green indicator (indicating that it is likely present since it responded). Once added it is possible to edit or remove instruments again via the right click menu. * Show error in case benchmark fails * Make use of new AdwAboutWindow * Do not break normal clipboard copy feature * Only copy image data to clipboard when image data is available * Add lua log feature to command-line tool * Add repology packaging status * Fix desktop file categories Prevent that application might appear more than once in the application menu * Rework meson lua dependency check To support more distributions which package lua differently. * Rework meson readline dependency check To support readline installations without pkg-config. * Remove internationalization stuff There are no plans to support other languages. * Rename COPYING -> LICENSE * Cleanup date_time() Also, use ISO8601 timestamp format. * Rename test -> examples * Update PSU data log test script * Add automation test script (draft) * Reduce default timeout values * Fix timeout conversion Fix so that the printed default timeout values are not different when running 'lxi' or 'lxi --help'. Fix also simplifies code. * Remove obsolete completion script for snap * Use '#pragma once' in all headers * Disable natural wrap mode * Cleanup circleCI configuration * Rename ChangeLog to NEWS * Enable gui by default Distributions like Ubuntu now have all the components required to build lxi-gui so let's enable it by default. * Add TODO list Perry Hung: * README: update readme to reflect lecroy support Add the LeCroy WavePro ZI-a to the list of tested devices. * plugins: lecroy: poll status register until SCDP bit is set To avoid racing the device (transferring a file before it's available), poll the SCDP bit in the status register until the hardcopy has completed. * plugins: lecroy make command format consistent Use shortened and capitalized forms across all commands for consistency. * plugins: lecroy: error check and validate inputs Fix some memory safety issues. Add some rudimentary checks and validate untrusted input from the device. * plugins: implement screenshot for LeCroy WavePRO oscilloscopes This changeset adds screenshot support for LeCroy oscilloscopes that implement the MAUI LXI interface. In principle this should work with other LeCroy telescopes, but I have only tested it with the WavePro 7 Zi-A. Adrian Scripca: * Added ability to copy grabbed screenshot to clipboard Eddie: * adds R&S CMW270 to README werwaswarum: * Add R&S ZNL as compatible Tested R&S ZNL3. LXI discover and SCPI ok. As far as I read the manual screenshoots are only saved to the device or send to a printer. Walter Stanish: * Update Wiki link text; add Wiki section Changes since lxi-tools v2.0: * Remove scpi run commands from file feature Retiring this feature as one should use the Lua script feature instead. * Fix memory leak in screenshot plugins * Add extra features to the SCPI text view context menu Add "Clear all" and "Save as.." features. * Fix printing of sent SCPI command when using TCP/RAW A redundant newline is removed. * Improve SCPI send button state change * Fix appdata.xml.in * Prefix SCPI messages with timestamp, IP, and type Allow prefixing SCPI messages with timestamp, IP, and type (REQ/RSP). Add preference settings accordingly. Prefixing with IP is default. * Rename from metainfo to appdata because of meson * Update application meta file * Update AppData path * Fix psu data log test * meson: Require dependencies * Add doc section to README Valentin Belot: * Fix memory allocation and GUI update outside of main thread (macOS compatibility) Changes since lxi-tools v1.21: * New lxi-gui application with many new features Too many changes to list here. See git history for complete list of changes. * Replace autotools with meson * Pass id to screenshot plugins * Do not exit when screenshot plugin fails * Rename lxi option '-s --script' to -f --file' * Add lua clock API Add lua clock API for measuring elapsed time: * c = clock_new() - Returns new clock * time = clock_read(c) - Returns elapsed time in seconds since first read call * clock_reset(c) - Resets clock time * clock_free(c) - Releases clock handle First time clock_read() is called on a new clock it will return a time of 0 seconds and the clock will start running. This clock API is useful for time stamping data as it is retrieved from an instrument. * Replace Travis wth CircleCI Travis is no longer free for open source projects! CircleCI seems to be the new king for quick open source CI. * Add Rigol DM3058 to instrument list Sam Harry Tzavaras: * Add screenshot plugin for tek 3000 series Uli Köhler: * Added Rigol DL3021 to list of supported devices Heiko Jakob: * Added screenshot support for Rigol DL3000 series programmable DC load * Changed screenshot dg4000 regex to also match dg1000z series Mete Balci: * Added Keysight MSOX 6004A to list of supported device * Added Rohde & Schwarz NGE 100 to list of supported devices I tested discovery, a few SCPI commands (IDN?, MEAS?, MEAS:CURR?) and screenshot with the power supply R&S NGE 103B (NGE100 3-channels model). All works fine. Martino Ferrari: * Added Rohde & Schwarz RTM 3004 to list of supported devices htro: * Added Tek MDO3024, 4 Series and 5 Series as compatible Changes since lxi-tools v1.20: * Fix handling of question commands in interactive mode Changes since lxi-tools v1.19: * Add bash completion for snap * Update README Add tested instrument Keysight AWG 33612A as tested by Timur Aydin. * Add const qualifier * Update AUTHORS * Require Lua 5.1 or newer * Include test dir in distribution * Update Travis * Fix bash completion for run command * Update basic-tests.lua * Move test directory * Add basic Lua tests Changes since lxi-tools v1.18: * Downgrade to Lua 5.2 * Update Travis configuration * Add Lua scripting feature to support automation Add run command which makes it possible to run Lua scripts to support advanced instrument automation. To run a Lua script simply do: $ lxi run test.lua The following LXI specific Lua functions are added and made available for use in the Lua scripts: device = connect(ip) scpi(device, command) scpi_raw(device, command) msleep(miliseconds) sleep(seconds) disconnect(device) See src/test/test.lua for a simple Lua script example. * Update README * Update AUTHORS * Improve regex of rs-hmo-rtb screenshot plugin Include instruments made with "HAMEG" identifier. * README: Add sponsors section * lxi-gui: Fix snap build * configure: use pkg-config to check for Qt5 * lxi-gui: Cleanup Qt5 configuration * Reconfigure R&S screenshot plugin to BMP * Add RTB2004 to list of tested instruments Dmitri Goutnik: * Use QT_SELECT value instead of hardcoded QT version Changes since lxi-tools v1.17: * lxi-gui: Add X-axis title to data recorder chart * lxi-gui: Fix data recorder chart colors and csv export * lxi-gui: Add SCPI 1999.0 commands * lxi-gui: Add data recorder save data feauture Add a save button which allows to save recorded data to file in CSV format. * lxi: Increase default discover mDNS timeout * lxi-gui: Optimize data recorder plotting * lxi-gui: Fix arm snap build * lxi-gui: Print machine type during qmake build * lxi-gui: Remove *OPT? SCPI command * lxi-gui: Use elapsed real time in data recorder * lxi-gui: Print SCPI command requests * Add screenshot support for RTB 2000 * Cleanup timeout handling, etc. * lxi-gui: Reduce minimum window size * Add support for adding custom Qt qmake arguments Add QMAKE_ARGUMENTS flag which allows to pass on arguments to qmake when building lxi-gui. * lxi-gui: Make sure to call QT5 qmake Changes since lxi-tools v1.16: * lxi-gui: Add input dialog for *ESE and *SRE commands * lxi-gui: Fix qmake compile flags * lxi-gui: Start with SCPI page * Add configure check for Qt5Charts * lxi-gui: Cleanup Name UI elements accordingly * lxi-gui: Add screenshot live view * Update README screenshot * lxi-gui: Add ID/IP instrument table header * lxi-gui: Tag as BETA * Update README Introduce lxi-gui and include screenshot. * Link QT5 Charts manually To avoid build issue with snap. * lxi-gui: Add data recorder feature * lxi-gui: Add settings * lxi-gui: Add QT5 source files * lxi-gui: Introduce responsive layout The lxi-gui application can now automatically resize to fit any window size. * lxi-gui: Add 'Open in browser' right-click feature * lxi-gui: Add IEEE 488.2 Common Commands * lxi-gui: Add about details * lxi-gui: Add screenshot feature * lxi-gui: Add benchmark feature * Split features into separate files * Update README * Update lxi-gui * Add keysight-dmm screenshot plugin This plugin supports Keysight Truevolt digital multimeters. * Set default discover timeout to 1 s * Add experimental QT5 GUI Can be enabled using configure option --enable-lxi-gui Requires QT 5.0.0 or newer. * Cleanup * Update Travis Changes since lxi-tools v1.15: * Update AUTHORS * Convert tabs to spaces * Remove experimental label from keysight-ivx plugin Tested with MSO-X 3024T by ralphrmartin from EEVBlog forum. * Fix keysight-iv2000x plugin Fix header strip and change image format to BMP. Improve regex. * Fix image format for rigol-dg4000 plugin * Update completion script * Cleanup Dmitri Goutnik: * Make code clang friendly Changes since lxi-tools v1.14: * Update man page * Add support for using raw/TCP in benchmark mode Add the option to run benchmark using raw/TCP. For example: $ lxi benchmark --address 10.0.0.42 --port 5555 --raw Also, cleanup all port handling code and update documentation accordingly. * Decrease timeout for discover to 2 s Changes since lxi-tools v1.13: * Make screenshot plugin only support Rigol DM3068 Rigol DM3068 is the only DM3000 series digital multimeter that seems to have screenshot support. * Fix entering interactive mode Regardless of using --interactive a SCPI command was still required to be provided to enter interactive mode. * Update AUTHORS * Remove experimental label from Siglent plugins Thanks to Siglent who helped fix and test all the screenshot plugins for their instruments. * Cleanup screenshot plugins * Consolidate Rigol DSA plugins into one * Update README and man page * Support writing screenshot image to stdout To write screenshot image to stdout simply use '-' as the output filename. This allows to pipe the screenshot image directly to other tools for image processing. For example, using imagemagick to automatically convert captured screenshot image to JPG: $ lxi screenshot -a 10.0.0.42 - | convert - screenshot.jpg * Cleanup Siglent screenshot plugins * Update siglent-ssa3000x plugin * Add siglent-sdg plugin * Add siglent-sdm3000 plugin * Move siglent-sds out of experimental * Extend Siglent plugin to include SDS2000X Changes since lxi-tools v1.12: * Update README * Update SSA3000X capture command * Add completion for benchmark command * Update AUTHORS * Fix get_device_id() This function was missing a call to lxi_disconnect() which resulted in some instruments being left hanging when capturing screenshots. Instruments that presumable only allow one active connection. * Add benchmark feature This benchmark feature is useful if you want to compare the VXI-11 request/response performance of your instruments. By default the benchmark sends 100 SCPI ID requests ("*IDN?" commands) to the instrument. For each request it waits for and reads the response. When done the resulting request rate is printed. * Fix screenshot command when using plugin autodetection The wrong timeout value was passed when trying to autodetect which screenshot plugin to use. * Cleanup * Fix Rohde & Schwarz HMO 1000 screenshot plugin Fix plugin so that it does not strip off the PNG header of the PNG image stream. Also, the source files and functions of the plugin is now named more explicitly according to the name of the instrument series (HMO 1000). * Fix Siglent SSA3000 screenshot plugin Changes since lxi-tools v1.11: * Update to new URL * Add snap status * Fix redirection of output to file * Update README * Cleanup configure.ac Jakub Wilk: * Use HTTPS in the configure script Changes since lxi-tools v1.10: * Update README * Update man page * Update AUTHORS * Expand tested instruments list * Rename screenshot plugin rigol-1000 -> rigol-1000z * Add various Rigol screenshot plugins Add the following Rigol screenshot plugins: rigol-dg4000 Rigol DG4000 series function generator rigol-dm3000 Rigol DM3000 series digital multimeter rigol-dp800 Rigol DP800 series power supply rigol-dsa800 Rigol DSA800 series spectrum analyzer rigol-dsa700 Rigol DSA700 series spectrum analyzer The code is added on behalf of PeDre from the EEVBlog forum. * Add authors section in README * Add README.md to prettify GitHub page The original README is still preserved because it is more readable when not reading it via GitHub. Jakub Wilk: * Strip trailing spaces * Fix typo * Fix grammar and typos Changes since lxi-tools v1.9: * Add support for mDNS/DNS-SD discovery Add "--mdns" option which enables the discover command to search for LXI devices/services using mDNS/DNS-SD. * Fix Siglent screenshot plugins Write correct response buffer to file. Improve .regex match expression. Changes since lxi-tools v1.8: * Update README * Fix newlines when redirecting to file or terminal * Rename --dump-hex to --hex * Fix missing error message when no SCPI command defined * Update man page * Remove --dump-file option The correct way to dump response to file is to use pipe output redirection. For example: lxi scpi --address 192.168.1.210 "*IDN?" > response.txt This way it is possible to dump any binary response to file. * Fix missing error message when no IP address defined * Print errors to stderr * Cleanup Siglent SDS1000 plugin name * Add Siglent SSA 3000X screenshot plugin * Cleanup script examples * Correct default SCPI raw/TCP port By default use port 5025 as described here: http://www.lxistandard.org/About/LXI-Protocols.aspx If a different port is needed use the '--raw-port' option. Apparently Rigol is not using the recommended port for raw SCPI commands. * Update descriptions of the plugin options Changes since lxi-tools v1.7: * Update README * Add Siglent SDS 1000 screenshot plugin Changes since lxi-tools v1.6: * Update README * Cleanup * Update .regex for Tektronix plugin * Update .regex for R&S plugin * Update .regex for Keysight plugin * Update man page * Embed instrument IP address in screenshot filename This helps identify screenshot files when capturing screenshots from multiple instruments. It also allows simplifying the APIs used by the screenshot plugins. * Change option '--model' to '--plugin' Lets remove any model vs. plugin confusion and only deal with plugin names. Each plugin includes support for one or more instruments models as described in the plugin description. * Add automatic loading of screenshot plugin feature If no screenshot plugin is specified the tool will automatically try to select the best plugin by matching the instruments ID string against the regular expressions defined in each plugin. Each screenshot plugin defines a .regex string entry containing space separated regular expressions. Each regular expression is matched against the instrument ID string. The plugin with most matches is selected. Note: This mechanism is slightly slower than manually specifying which screenshot plugin because it needs to retrieve the instruments ID string first. * Improve description of Rigol plugins * Fix Rigol 2000 screenshot plugin Remove trailing newline in received image data. * Add screenshot plugin for Rigol 2000 series Also, make existing Rigol plugin only apply for 1000z series. Changes since lxi-tools v1.5: * Add date-time stamp to screenshot filename * Improve command handling In case of a misspelled command the tool would misleadingly respond: "Error: No IP address specified" With this fix, it now responds: "Error: Unknown command" * Update README * Added screenshot plugin for Tektronix 2000 series scopes * Improve scpi response output * Add --raw and --raw-port options to scpi command One can now use choose to use raw/TCP instead of VXI11 when firing SCPI commands. Simply append the --raw option like so: lxi scpi --raw --address 192.168.0.42 "*IDN?" By default raw/TCP port 5555 is used but it can be changed using the --raw-port option. Warning: Using raw/TCP is faster than VXI11 but does not provide any timeout/control mechanisms so if your command somehow stalls it will stall forever. * Use new lxi_connect() function * Cleanup * Make screenshot filename optional In case no screenshot filename is provided the tool will write the screenshot image to an automatically resolved and incremented filename on the form screenshot-###.. For example, screenshot-000.png, screenshot-001.png, etc. * Improve screenshot model listing * Increase default timeout for screenshot command Transferring screenshot image data takes time so lets increase the timeout so we do not easily interrupt a good but slow transfer. * Collapse Rigol screenshot plugin Support all Rigol oscilloscope models via one model name. * Add screenshot support for Keysight IV 2000 X * Cleanup plugins * Add screenshot support for R&S HMO1000 series * Add screenshot support for Rigol 2000/4000 * Create directory for screenshot plugins Changes since lxi-tools v1.4: * Remove -Og flag Not supported by older gcc versions. * Fix various bugs in script and interactive mode Changes since lxi-tools v1.3: * Add screenshot feature to lxi tool The old rigol_1000z_screenshot tool is retired in favor of a screenshot feature in the lxi tool. A new lxi command 'screenshot' is added and also a small screenshot plugin framework which makes it easy to add new screenshot plugins for new instruments. Currently there is only a screenshot plugin for Rigol 1000Z series oscilloscopes. * Update README Changes since lxi-tools v1.2: * Added AUTHORS file * Use new lxi_connect() function * Reconfigure default timeout to 3 seconds Changes since lxi-tools v1.1: * Increase default timeout value for lxi tool Increase the default timeout value for the lxi tool from 1 to 5 seconds * Fix timeout for Rigol screenshot tool Timeout is increased to avoid failure to capture screenshot * Fix typo * Cleanup test script * Fix crash in rigol_1000z_screenshot tool Add error handling to avoid crashing when connecting remote device fails. Changes since lxi-tools v1.0: * Fix missing src/bash-completion/lxi An automake rule was fixed to make sure that the file src/bash-completion/lxi is included in the distributed tarball. * Update README lxi-tools v1.0: * First release (stable) lxi-tools-2.7/README.md000066400000000000000000000417651447016333500146160ustar00rootroot00000000000000 [![lxi-tools](images/lxi-tools-icon.png)]() # lxi-tools - open source LXI tools [![](https://img.shields.io/circleci/build/github/lxi-tools/lxi-tools)](https://circleci.com/gh/lxi-tools/lxi-tools/tree/master) [![](https://img.shields.io/github/v/release/lxi-tools/lxi-tools?sort=semver)](https://github.com/lxi-tools/lxi-tools/releases) [![](https://img.shields.io/repology/repositories/lxi-tools)](https://repology.org/project/lxi-tools/versions) [![](https://img.shields.io/tokei/lines/github/lxi-tools/lxi-tools)](https://github.com/lxi-tools/lxi-tools) [![](https://img.shields.io/codefactor/grade/github/lxi-tools/lxi-tools)](https://www.codefactor.io/repository/github/lxi-tools/lxi-tools) ## 1. Introduction lxi-tools are open source software tools for managing network attached LXI compatible test instruments such as modern oscilloscopes, power supplies, spectrum analyzers etc. Features include automatic discovery of test instruments, sending SCPI commands, grabbing screenshots from supported instruments, benchmarking SCPI message performance, and powerful scripting for test automation. Both a commandline tool and a GUI tool are available. lxi-tools rely on [liblxi](https://github.com/lxi-tools/liblxi) for all communication. ### 1.1 What is LXI? LAN eXtensions for Instrumentation (LXI) is a standard developed by the LXI Consortium, an industry consortium that maintains the LXI specification and promotes the LXI Standard. The LXI standard defines the communication protocols for modern instrumentation and data acquisition systems using Ethernet. Visit www.lxistandard.org for more details. Please notice that lxi-tools is not affiliated with the LXI consortium - it is an independent open source community effort. ### 1.2 Motivation To make better and simpler open source tools for managing network attached LXI compatible test instruments. ## 2. Features * Automatically discover test instruments on local network via VXI11 or mDNS * Send SCPI commands and receive responses * Automatically grab screenshots from supported instruments * Benchmark request/response performance of instruments * Support for manually adding instruments in case they are undiscoverable * Powerful Lua scripting support for advanced automation - Simple script editor with syntax highlighting - Simple API which supports - Connecting/disconnecting remote test instruments - Send SCPI commands to connected test instruments and receive responses - Clock sources for managing elapsed time - Log data to CSV files - Charts for graphically presenting captured data live in various chart types: - Line - Scatter - Number - Angular gauge - Linear gauge - Charts can be saved in PNG or CSV format * Command-line and GUI tool available * Interactive command-line mode * Dump received response in hexadecimal format ## 3. Usage ### 3.1 lxi-gui The lxi-gui application provides some of the same features as the commandline tool and more but presents them in a modern GUI frontend.

SCPI mode - easily explore SCPI features of your instruments Search for instruments - using standard broadcast discovery or mDNS Screenshot mode - easily grab display screenshots from supported instruments Benchmark mode - measure the message response performance of your instruments Script mode - program your LXI compatible instruments in a powerful clean cut Lua script environment Script mode in action plotting voltage levels from a DC power supply to line chart and CSV/PNG files

### 3.2 lxi The commandline interface of the lxi application is described in the output from 'lxi --help': ``` Usage: lxi [--version] [--help] [] -v, --version Display version -h, --help Display help Commands: discover [] Search for devices scpi [] Send SCPI command screenshot [] [] Capture screenshot benchmark [] Benchmark run Run Lua script Discover options: -t, --timeout Timeout (default: 3) -m, --mdns Search via mDNS/DNS-SD Scpi options: -a, --address Device IP address -p, --port Use port (default: VXI11: 111, RAW: 5025) -t, --timeout Timeout (default: 3) -x, --hex Print response in hexadecimal -i, --interactive Enter interactive mode -r, --raw Use raw/TCP Screenshot options: -a, --address Device IP address -t, --timeout Timeout (default: 15) -p, --plugin Use screenshot plugin by name -l, --list List available screenshot plugins Benchmark options: -a, --address Device IP address -p, --port Use port (default: VXI11: 111, RAW: 5025) -t, --timeout Timeout (default: 3) -c, --count Number of request messages (default: 100) -r, --raw Use raw/TCP ``` #### 3.2.1 Example - Discover LXI devices on available networks ``` $ lxi discover Searching for LXI devices - please wait... Broadcasting on interface lo Broadcasting on interface eth0 Found "RIGOL TECHNOLOGIES,DS1104Z,DS1ZA1234567890,00.04.03.SP2" on address 10.42.1.20 Found "RIGOL TECHNOLOGIES,DP831,DP8F1234567890,00.01.14" on address 10.42.1.67 Broadcasting on interface wlan0 Found 2 devices ``` #### 3.2.2 Example - Send SCPI command to an instrument ``` $ lxi scpi --address 10.42.1.20 "*IDN?" RIGOL TECHNOLOGIES,DS1104Z,DS1ZA1234567890,00.04.03 ``` To dump response to file simply do: ``` $ lxi scpi --address 10.42.1.20 "*IDN?" > response.txt ``` #### 3.2.3 Example - Capture screenshot from a Rigol 1000z series oscilloscope ``` $ lxi screenshot --address 10.42.1.20 --plugin rigol-1000z Saved screenshot image to screenshot_10.42.1.20_2017-11-11_13:45:47.png ``` Or using plugin autodetection simply: ``` $ lxi screenshot --address 10.42.1.20 Loaded rigol-1000 screenshot plugin Saved screenshot image to screenshot_10.42.1.20_2017-11-11_13:46:02.png ``` #### 3.2.4 Example - Capture screenshot and convert it to any image format By default the format of the captured screenshot image is dictated by which screenshot plugin and instrument are in play. However, it is possible to write the screenshot image to stdout and pipe it directly to other tools for image processing. For example, use ImageMagicks convert tool to automatically convert any screenshot image to JPG: ``` $ lxi screenshot --address 10.42.1.20 - | convert - screenshot.jpg ``` #### 3.2.5 Example - List available screenshot plugins ``` $ lxi screenshot --list Name Description keysight-ivx Keysight InfiniVision 2000X/3000X series oscilloscope lecroy LeCroy WavePro oscilloscopes rigol-1000z Rigol DS/MSO 1000z series oscilloscope rigol-2000 Rigol DS/MSO 2000 series oscilloscope rigol-dg4000 Rigol DG 4000 series function generator rigol-dm3000 Rigol DM 3000 series digital multimeter rigol-dp800 Rigol DP 800 series power supply rigol-dsa Rigol DSA 700/800 series spectrum analyzer rs-hmo1000 Rohde & Schwarz HMO 1000 series oscilloscope siglent-sdm3000 Siglent SDM 3000/3000X series digital multimeter siglent-sdg Siglent SDG 1000X/2000X/6000X series waveform generator siglent-sds Siglent SDS 1000X/2000X series oscilloscope siglent-ssa3000x Siglent SSA 3000X series spectrum analyzer tektronix-2000 Tektronix DPO/MSO 2000 series oscilloscope (experimental) ``` #### 3.2.6 Example - Benchmark instrument request/response performance ``` $ lxi benchmark --address 10.42.1.20 Benchmarking by sending 100 ID requests. Please wait... Result: 24.7 requests/second ``` ## 4. Installation ### 4.1 Installation using package manager (Linux) lxi-tools comes prepackaged for various GNU/Linux distributions. Please consult your package manager tool to find and install lxi-tools. If you would like to see lxi-tools included in your favorite distribution, please reach out to their package maintainers team. ### 4.2 Installation using snap (Linux) Install latest stable version: ``` $ snap install lxi-tools ``` Install bleeding edge: ``` $ snap install lxi-tools --edge ``` ### 4.3 Installation using homebrew (MacOS, Linux) If you have [homebrew](http://brew.sh) installed: ``` $ brew install lxi-tools ``` ### 4.4 Installation from source The latest source releases can be found [here](https://github.com/lxi-tools/lxi-tools/releases). To compile and install successfully from source you need to first install the following dependencies: * liblxi * libreadline * liblua * libgtk * libadwaita * gtksourceview * bash-completion Install steps: ``` $ meson setup build $ meson compile -C build $ meson install -C build ``` See meson\_options.txt for which features to enable/disable. Note: The meson install steps may differ depending on your specific system. ## 5. Tested instruments The tools are tested to work successfully with the following LXI compatible instruments: | Instrument | Working features | Note | |-----------------------------------|----------------------------|-------------------------------| | Chroma 63205A | [discover+scpi] | Use RAW/TCP, port 2101 | | ITECH IT6018C | [discover+scpi] | | | GW-INSTEK PSW800 | [scpi] | Use RAW/TCP, port 2268 | | Keysight Technologies AWG 33612A | [discover+scpi+screenshot] | | | Keysight Technologies DMM 34461A | [discover+scpi+screenshot] | | | Keysight Technologies MSO-X 3024T | [discover+scpi+screenshot] | | | Keysight Technologies MSO-X 6004A | [discover+scpi+screenshot] | | | Kikusui Electronics PMX35-3A | [discover+scpi] | | | LeCroy WavePro ZI-a | [discover+scpi+screenshot] | | | Rigol Technologies DG1062Z | [discover+scpi+screenshot] | | | Rigol Technologies DG4062 | [discover+scpi+screenshot] | | | Rigol Technologies DG4102 | [discover+scpi+screenshot] | | | Rigol Technologies DG4162 | [discover+scpi+screenshot] | | | Rigol Technologies DL3021 | [discover+scpi] | | | Rigol Technologies DP831 | [discover+scpi+screenshot] | | | Rigol Technologies DP832 | [discover+scpi+screenshot] | | | Rigol Technologies DM3058 | [discover+scpi] | | | Rigol Technologies DM3068 | [discover+scpi+screenshot] | | | Rigol Technologies DS1074Z+ | [discover+scpi+screenshot] | | | Rigol Technologies DS1104Z | [discover+scpi+screenshot] | | | Rigol Technologies DS2302 | [discover+scpi+screenshot] | | | Rigol Technologies DSA815 | [discover+scpi+screenshot] | | | Rigol Technologies MSO1104Z | [discover+scpi+screenshot] | | | Rigol Technologies MSO2302A | [discover+scpi+screenshot] | | | Rigol Technologies MSO4024 | [discover+scpi+screenshot] | | | Rigol Technologies MSO4054 | [discover+scpi+screenshot] | | | Rigol Technologies MSO5074 | [discover+scpi+screenshot] | | | Rohde & Schwarz CMW 270 | [discover+scpi] | | | Rohde & Schwarz HMC 8012 | [discover+scpi+screenshot] | | | Rohde & Schwarz HMC 8043 | [discover+scpi+screenshot] | | | Rohde & Schwarz HMO 1202 | [discover+scpi+screenshot] | | | Rohde & Schwarz HMO 3054 | [scpi+screenshot] | | | Rohde & Schwarz NGE 100 | [discover+scpi+screenshot] | | | Rohde & Schwarz NGM 202 | [discover+scpi+screenshot] | | | Rohde & Schwarz NGL 202 | [discover+scpi+screenshot] | | | Rohde & Schwarz RTB 2004 | [discover+scpi+screenshot] | | | Rohde & Schwarz RTH 1004 | [discover+scpi+screenshot] | | | Rohde & Schwarz RTM 3004 | [discover+scpi+screenshot] | | | Rohde & Schwarz ZNL3 | [discover+scpi] | | | Siglent Technologies SDG1032X | [discover+scpi+screenshot] | | | Siglent Technologies SDG2122X | [discover+scpi+screenshot] | | | Siglent Technologies SDG6052 | [discover+scpi+screenshot] | | | Siglent Technologies SDS1152CML | [discover+scpi+screenshot] | | | Siglent Technologies SDS1202X-E | [discover+scpi+screenshot] | | | Siglent Technologies SDS1204X-E | [discover+scpi+screenshot] | | | Siglent Technologies SDS2304X | [discover+scpi+screenshot] | | | Siglent Technologies SDM3045X | [discover+scpi+screenshot] | | | Siglent Technologies SDM3055 | [discover+scpi+screenshot] | | | Siglent Technologies SDM3065X | [discover+scpi+screenshot] | | | Siglent Technologies SPD3303X-E | [scpi] | | | Siglent Technologies SSA3032X | [discover+scpi+screenshot] | | | Tektronix TDS3034B | [discover+scpi+screenshot] | | | Tektronix MDO3024 | [discover+scpi] | | | Tektronix 4 Series MSO | [discover+scpi] | | | Tektronix MSO56 | [discover+scpi+screenshot] | | Notes: * Feel free to add tested instruments to the list via GitHub pull request or report via GitHub issue. * The [lxi-tools wiki](https://github.com/lxi-tools/lxi-tools/wiki/) provides further information regarding test instruments, including known issues and SCPI commands. ## 6. Documentation ## 6.1 lxi The lxi commandline tool is documented in its included manpages. ## 6.2 Lua script API The lxi-tools Lua script API is documented [here](doc/lua-api.txt). ## 7. Contributing lxi-tools is open source. If you want to help out with the project please feel free to join in. All contributions (bug reports, code, doc, ideas, etc.) are welcome. Please use the github issue tracker and pull request features. Also, if you find this free open source software useful please feel free to consider making a donation of your choice: [![Donate](images/Paypal.png)](https://www.paypal.me/lundmar) ## 8. Support Submit bug reports [here](https://github.com/lxi-tools/lxi-tools/issues). ## 9. Website Visit [lxi-tools.github.io](https://lxi-tools.github.io) ## 10. Wiki Visit wiki [here](https://github.com/lxi-tools/lxi-tools/wiki/). ## 11. License This code is released under BSD-3, commonly known as the 3-clause (or "modified") BSD license. ## 12. Authors Created and maintained by Martin Lund \ See the AUTHORS file for full list of contributors. ## 13. Sponsors A big thank you to the following sponsors that have donated test equipment to support the lxi-tools open source effort: * Siglent Technologies - www.siglent.com * KIKUSUI Electronics Corp. - www.kikusui.co.jp lxi-tools-2.7/TODO000066400000000000000000000024131447016333500140120ustar00rootroot00000000000000# lxi-gui * Make lxi-gui work on MacOS - requires adoption of Bonjour API for mDNS Need help from people with access to MacOS. * Add support for test cases in lua scripts Add support for splitting a lua script into test cases for expressing pass/fail status via gui or console when running the script. This is a feature useful for test automation and reporting. The current idea is to define test cases via lua comments so that is becomes a layering not affecting normal script operation. Example lua test script: -- tc "Test case 1 description" print("This is test case 1") -- tc "Test case 2 description" print("This is test case 2") fail() -- tc "Test case 3 description" print("This is test case 3") fail_stop() -- tc "Test case 4 description" print("This is test case 4") -- tc end tc_save("test-results.log") When running the script the GUI will present a list of test cases and their pass/fail status as the script progresses. If run via command line tool lxi, a similar list will be presented in text. Also includes introduction of fail() function which will report failure and continue and fail_stop() function which will report failure and stop script execution. lxi-tools-2.7/build-aux/000077500000000000000000000000001447016333500152145ustar00rootroot00000000000000lxi-tools-2.7/build-aux/meson/000077500000000000000000000000001447016333500163355ustar00rootroot00000000000000lxi-tools-2.7/build-aux/meson/postinstall.py000077500000000000000000000012151447016333500212650ustar00rootroot00000000000000#!/usr/bin/env python3 from os import environ, path from subprocess import call prefix = environ.get('MESON_INSTALL_PREFIX', '/usr/local') datadir = path.join(prefix, 'share') destdir = environ.get('DESTDIR', '') # Package managers set this so we don't need to run if not destdir: print('Updating icon cache...') call(['gtk4-update-icon-cache', '-qtf', path.join(datadir, 'icons', 'hicolor')]) print('Updating desktop database...') call(['update-desktop-database', '-q', path.join(datadir, 'applications')]) print('Compiling GSettings schemas...') call(['glib-compile-schemas', path.join(datadir, 'glib-2.0', 'schemas')]) lxi-tools-2.7/data/000077500000000000000000000000001447016333500142335ustar00rootroot00000000000000lxi-tools-2.7/data/icons/000077500000000000000000000000001447016333500153465ustar00rootroot00000000000000lxi-tools-2.7/data/icons/hicolor/000077500000000000000000000000001447016333500170055ustar00rootroot00000000000000lxi-tools-2.7/data/icons/hicolor/scalable/000077500000000000000000000000001447016333500205535ustar00rootroot00000000000000lxi-tools-2.7/data/icons/hicolor/scalable/apps/000077500000000000000000000000001447016333500215165ustar00rootroot00000000000000lxi-tools-2.7/data/icons/hicolor/scalable/apps/io.github.lxi-tools.lxi-gui.svg000066400000000000000000000131001447016333500274300ustar00rootroot00000000000000 image/svg+xml LXI TOOLS lxi-tools-2.7/data/icons/hicolor/symbolic/000077500000000000000000000000001447016333500206265ustar00rootroot00000000000000lxi-tools-2.7/data/icons/hicolor/symbolic/apps/000077500000000000000000000000001447016333500215715ustar00rootroot00000000000000lxi-tools-2.7/data/icons/hicolor/symbolic/apps/io.github.lxi-tools.lxi-gui-symbolic.svg000066400000000000000000000040511447016333500313270ustar00rootroot00000000000000lxi-tools-2.7/data/icons/meson.build000066400000000000000000000007341447016333500175140ustar00rootroot00000000000000application_id = 'io.github.lxi-tools.lxi-gui' scalable_dir = join_paths('hicolor', 'scalable', 'apps') install_data( join_paths(scalable_dir, ('@0@.svg').format(application_id)), install_dir: join_paths(get_option('datadir'), 'icons', scalable_dir) ) symbolic_dir = join_paths('hicolor', 'symbolic', 'apps') install_data( join_paths(symbolic_dir, ('@0@-symbolic.svg').format(application_id)), install_dir: join_paths(get_option('datadir'), 'icons', symbolic_dir) ) lxi-tools-2.7/data/io.github.lxi-tools.lxi-gui.appdata.xml000066400000000000000000000044761447016333500235770ustar00rootroot00000000000000 io.github.lxi-tools.lxi-gui CC0-1.0 BSD-3-Clause LXI-Tools LXI-Tools is a collection of open source tools for managing network connected LXI compatible test instruments.

Features include automatic discovery of test instruments, sending SCPI commands, grabbing screenshots from supported instruments, benchmarking SCPI message performance, and powerful scripting for automation. Both a commandline tool and a GUI tool are available.

https://raw.githubusercontent.com/lxi-tools/lxi-tools/master/images/lxi-gui-scpi.png Easily explore SCPI features of your instruments https://raw.githubusercontent.com/lxi-tools/lxi-tools/master/images/lxi-gui-search.png Search for instruments https://raw.githubusercontent.com/lxi-tools/lxi-tools/master/images/lxi-gui-screenshot.png Easily grab screenshots from supported instruments https://raw.githubusercontent.com/lxi-tools/lxi-tools/master/images/lxi-gui-benchmark.png Measure instrument message response performance https://raw.githubusercontent.com/lxi-tools/lxi-tools/master/images/lxi-gui-script.png Powerful clean cut Lua script environment https://raw.githubusercontent.com/lxi-tools/lxi-tools/master/images/lxi-gui-script-in-action-900px.png Script mode plotting line chart and CSV/PNG files https://lxi-tools.github.io Utility Network Science
lxi-tools-2.7/data/io.github.lxi-tools.lxi-gui.desktop000066400000000000000000000002211447016333500230170ustar00rootroot00000000000000[Desktop Entry] Name=lxi-gui Exec=lxi-gui Icon=io.github.lxi-tools.lxi-gui Terminal=false Type=Application Categories=Utility StartupNotify=true lxi-tools-2.7/data/io.github.lxi-tools.lxi-gui.gschema.xml000066400000000000000000000047731447016333500235740ustar00rootroot00000000000000 1500 Discover timeout Timeout in milliseconds for discovery of LXI devices. 2000 SCPI timeout Timeout in milliseconds for communicating with LXI devices. 8000 Screenshot timeout Timeout in milliseconds for communicating screenshot with LXI devices. true Show sent SCPI message Show sent SCPI message. false Use mDNS discovery Use mDNS for discovery of LXI devices. 0 Communications protocol Communications protocol. 9221 RAW/TCP network port RAW/TCP network port true Prefer dark theme Prefer dark theme. false Show SCPI message timestamp Show SCPI message timestamp. true Show SCPI message IP Show SCPI message IP. false Show SCPI message type Show SCPI message type. '' Added instruments Added instruments JSON list lxi-tools-2.7/data/meson.build000066400000000000000000000024121447016333500163740ustar00rootroot00000000000000# See https://specifications.freedesktop.org/desktop-entry-spec/latest/ar01s02.html install_data('io.github.lxi-tools.lxi-gui.desktop', install_dir: join_paths(get_option('datadir'), 'applications') ) desktop_utils = find_program('desktop-file-validate', required: false) if desktop_utils.found() test('Validate desktop file', desktop_utils, args: files('io.github.lxi-tools.lxi-gui.desktop') ) endif # See https://www.freedesktop.org/software/appstream/docs/chap-Metadata.html#spec-component-location # Change appdata to metainfo once meson it updated to support it install_data('io.github.lxi-tools.lxi-gui.appdata.xml', install_dir: join_paths(get_option('datadir'), 'metainfo') ) appstream_util = find_program('appstream-util', required: false) if appstream_util.found() test('Validate appstream file', appstream_util, args: ['validate', files('io.github.lxi-tools.lxi-gui.appdata.xml')] ) endif install_data('io.github.lxi-tools.lxi-gui.gschema.xml', install_dir: join_paths(get_option('datadir'), 'glib-2.0/schemas') ) compile_schemas = find_program('glib-compile-schemas', required: false) if compile_schemas.found() test('Validate schema file', compile_schemas, args: ['--strict', '--dry-run', meson.current_source_dir()] ) endif subdir('icons') lxi-tools-2.7/doc/000077500000000000000000000000001447016333500140675ustar00rootroot00000000000000lxi-tools-2.7/doc/lua-api.txt000066400000000000000000000174351447016333500161720ustar00rootroot00000000000000------------------------------------------------------------------------------ lxi-tools Lua API ------------------------------------------------------------------------------ Both the lxi tool and lxi-gui tool add the following lua functions in addition to the standard lua library functions. ------------------------------------------------------------------------------ Function device = lxi_connect(address, port, name, timeout, protocol) Description Connect to LXI compatible device Parameters address: Address of remote device to connect [string] port: Port of remote device [integer] (only used for RAW connections) name: Name of remote device [string] (only used for VXI11 connection, best use nil to default to "inst0") timeout: Timeout in milliseconds [integer] protocol: Communications protocol to use [VXI11, RAW] Returns device: Handle of device ------------------------------------------------------------------------------ Function response = lxi_scpi(device, command, timeout) Description Send SCPI command and receive response if expected Parameters device: Handle of connected device command: SCPI command to send [string]. A response is expected if the command ends with "?". timeout: Timeout in milliseconds [integer] Returns response: Returns response [string] if command string ended with "?". If an error (timeout etc.) occurs the response is nil. ------------------------------------------------------------------------------ Function lxi_disconnect(device) Description Disconnect connected device Paramters device: Handle of device ------------------------------------------------------------------------------ Function lxi_sleep(time) Description Sleep for specified amount of time Parameters time: Time to sleep in seconds [integer] ------------------------------------------------------------------------------ Function lxi_msleep(time) Description Sleep for specified amount of time Parameters time: Time to sleep in milliseconds [integer] ------------------------------------------------------------------------------ Function clock = lxi_clock_new() Description Create new clock resource Returns clock: Handle of new clock ------------------------------------------------------------------------------ Function time = lxi_clock_read(clock) Description Read out the elapsed time of the clock since first clock_read() call Paramters clock: Handle of clock Returns time: Time in seconds since last call [double]. If first call it will return 0 and the clock will start ticking. ------------------------------------------------------------------------------ Function lxi_clock_reset(clock) Description Reset clock so that it stops ticking. First clock_read() will make the clock tick again. Paramters clock: Handle of clock ------------------------------------------------------------------------------ Function lxi_clock_free(clock) Desription Release clock resource Parameters clock: Handle of clock ------------------------------------------------------------------------------ Function log = lxi_log_new() Description Create new log resource Returns log: Handle of new log ------------------------------------------------------------------------------ Function lxi_log_add(log, ...) Description Log data to log. This is a variadic function which means that it can take a variable number of arguments and log them. Each log argument can be of any type. Example: log_add(log, 42, "hello", 4242). The resulting line in the CSV output file will look like this: 42,"hello",4242 Parameters log: Handle of log ------------------------------------------------------------------------------ Function lxi_log_save_csv(log, filename) Description Save log data to CSV formatted (RFC 4180) log file. Parameters log: Handle of log filename: Name of CSV file [string] ------------------------------------------------------------------------------ Function lxi_log_free(log) Desription Release log resource Parameters log: Handle of log ------------------------------------------------------------------------------ Additionally, the lxi-gui tool adds the following lua functions to present and manage data via the GUI. NOTE: These functions can only be used when running scripts via lxi-gui. ------------------------------------------------------------------------------ Function chart = lxi_chart_new(type, ...) Description Create and present a new chart. The chart is opened in a new window. Parameters type: Chart type [string] The type can be any of the following: "line" "scatter" "number" "angular-gauge" "linear-gauge" The number of parameters following the first parameter depends on which type of chart is requested: "line", "scatter": title: Title [string] x_label: Label of x-axis [string] y_label: Label of y-axis [string] x_max: Maximum value of x-axis [double] y_max: Maximum value of y-axis [double] width: Width of window in pixels [integer] "number": title: Title [string] label: Label [string] width: Width of window in pixels [integer] "angular-gauge", "linear-gauge": title: Title [string] label: Label [string] value_min: Minimum value [double] value_max: Maximum value [double] width: Width of window in pixels [integer] Returns chart: Handle of chart ------------------------------------------------------------------------------ Function lxi_chart_plot(chart, x, y) Description Plot x and y value to chart Paramters chart: Handle of chart x: X value [double] y: Y value [double] ------------------------------------------------------------------------------ Function lxi_chart_save_csv(chart, filename) Description Save plotted data to CSV file Paramters chart: Handle of chart filename: Name of CSV file [string] ------------------------------------------------------------------------------ Function lxi_chart_save_png(chart, filename) Description Save image of plotted chart to PNG file Paramters chart: Handle of chart filename: Name of PNG file [string] ------------------------------------------------------------------------------ Function lxi_chart_close(chart) Description Close chart window Paramters chart: Handle of chart ------------------------------------------------------------------------------ Function version = lxi_version() Description Get version of lxi-tools Returns version: Version of lxi-tools [string] ------------------------------------------------------------------------------ Function ip = lxi_selected_ip() Description Get IP of device selected in GUI Returns ip: IP of device selected in GUI [string]. Returns nil if none selected. ------------------------------------------------------------------------------ Function id = lxi_selected_id() Description Get ID of device selected in GUI Returns id: ID of device selected in GUI [string]. Returns nil if none selected. ------------------------------------------------------------------------------ lxi-tools-2.7/examples/000077500000000000000000000000001447016333500151405ustar00rootroot00000000000000lxi-tools-2.7/examples/lua/000077500000000000000000000000001447016333500157215ustar00rootroot00000000000000lxi-tools-2.7/examples/lua/basics.lua000066400000000000000000000035041447016333500176720ustar00rootroot00000000000000------------------------------------- -- lxi-tools -- -- https://lxi-tools.github.io -- ------------------------------------- -- Basic Lua tests --[[ Why Lua? Lua provides a set of unique features that makes it distinct from other languages. These include: * Extensible * Simple * Efficient * Portable * Free and open Official Lua documentation: http://www.lua.org/docs.html Lua quick guide: https://www.tutorialspoint.com/lua/lua_quick_guide.htm Lua tutorial: https://www.tutorialspoint.com/lua/index.htm --]] -- Print -- a = 42 print("Hello lxi-tools") print("Value of a is " .. a) print("Running " .. _VERSION) print("Is " .. a .. " the answer?") -- Conditional -- a = true if (a) then print("a is true") else print("a is false") end -- Loop -- for i=10, 1, -1 -- for init, max/min value, increment do print("loop count " .. i) end -- Conditional loops i = 0 j = 5 while (i < j) do print("loop count " .. i) i = i + 1 end repeat print("loop count " .. i) i = i - 1 until (i == 0) -- Function -- function add(a, b) return (a + b) end print("10 + 10 = " .. add(10,10)) -- Array -- array = {"duck", 42, "dog"} print(array[1]) print(array[2]) print(array[3]) -- File I/O -- file = io.open("test.txt", "a") io.output(file) io.write("Hello lxi-tools\n") io.close(file) -- String to number conversion a_string = "+5.111E+02" a_number = tonumber(a_string) print("a_number = " .. a_number) print(type(a_string)) print(type(a_number)) -- Math print("2*2 = " .. 2 * 2) print("2^4 = " .. 2 ^ 4) print("sin(2) = " .. math.sin(2)) print("sqrt(16) = " .. math.sqrt(16)) print("pi = " .. math.pi) print("a_number * 2 = " .. a_number * 2) -- OS functions os.execute ("echo 'Hello lxi-tools'") print(os.date("The time is %X")) -- print("TERM = " .. os.getenv("TERM")) print("Done") lxi-tools-2.7/examples/lua/chart-gauge-angular.lua000066400000000000000000000013441447016333500222440ustar00rootroot00000000000000------------------------------------- -- lxi-tools -- -- https://lxi-tools.github.io -- ------------------------------------- -- Angular gauge chart test -- Init clock0 = lxi_clock_new() chart0 = lxi_chart_new("angular-gauge", -- chart type "Engine", -- title "Tachometer [ RPM ]", -- label 0, 5000, 400) -- value min, value max, window width -- Manipulate gauge for 10 seconds clock = 0 while (clock < 10) do value = 3000 + 1000*math.sin(clock) clock = lxi_clock_read(clock0) lxi_chart_set_value(chart0, value) lxi_msleep(50) end -- Cleanup lxi_clock_free(clock0) lxi_chart_close(chart0) print("Done") lxi-tools-2.7/examples/lua/chart-gauge-linear.lua000066400000000000000000000013221447016333500220610ustar00rootroot00000000000000------------------------------------- -- lxi-tools -- -- https://lxi-tools.github.io -- ------------------------------------- -- Linear gauge chart test -- Init clock0 = lxi_clock_new() chart0 = lxi_chart_new("linear-gauge", -- chart type "Engine", -- title "Throttle [ % ]", -- label 0, 100, 400) -- value min, value max, window width -- Manipulate gauge for 10 seconds clock = 0 while (clock < 10) do clock = lxi_clock_read(clock0) value = 50 + 20*math.sin(10*clock) lxi_chart_set_value(chart0, value) lxi_msleep(20) end -- Cleanup lxi_clock_free(clock0) lxi_chart_close(chart0) print("Done") lxi-tools-2.7/examples/lua/chart-line.lua000066400000000000000000000020061447016333500204500ustar00rootroot00000000000000------------------------------------- -- lxi-tools -- -- https://lxi-tools.github.io -- ------------------------------------- -- Line chart test - plotting a sine wave function -- Init clock0 = lxi_clock_new() chart0 = lxi_chart_new("line", -- chart type "Sine wave plot, f(t) = 5 + 2sin(10t)", -- title "Time [ s ]", -- x-axis label "Value [ ]", -- y-axis label 10, 10, 800) -- x max, y max, window width -- Sample and plot sine wave at 100 Hz for 10 seconds clock = 0 while (clock < 10) do clock = lxi_clock_read(clock0) value = 5 + 2*math.sin(10*clock) lxi_chart_plot(chart0, clock, value) lxi_msleep(10) end -- Save chart data lxi_chart_save_csv(chart0, "chart0.csv") lxi_chart_save_png(chart0, "chart0.png") -- Cleanup lxi_clock_free(clock0) --lxi_chart_close(chart0) print("Done") lxi-tools-2.7/examples/lua/chart-number.lua000066400000000000000000000012061447016333500210120ustar00rootroot00000000000000------------------------------------- -- lxi-tools -- -- https://lxi-tools.github.io -- ------------------------------------- -- Number chart test -- Init clock0 = lxi_clock_new() chart0 = lxi_chart_new("number", -- chart type "PSU Voltage", -- title "[ V ]", -- label 800) -- window width -- Manipulate number for 10 seconds clock = 0 while (clock < 10) do clock = lxi_clock_read(clock0) lxi_chart_set_value(chart0, clock) lxi_msleep(100) end -- Cleanup lxi_clock_free(clock0) lxi_chart_close(chart0) print("Done") lxi-tools-2.7/examples/lua/chart-scatter.lua000066400000000000000000000020161447016333500211670ustar00rootroot00000000000000------------------------------------- -- lxi-tools -- -- https://lxi-tools.github.io -- ------------------------------------- -- Scatter chart test - plotting a sine wave function -- Init clock0 = lxi_clock_new() chart0 = lxi_chart_new("scatter", -- chart type "Sine wave plot, f(t) = 5 + 2sin(10t)", -- title "Time [ s ]", -- x-axis label "Value [ ]", -- y-axis label 10, 10, 800) -- x max, y max, window width -- Sample and plot sine wave at 100 Hz for 10 seconds clock = 0 while (clock < 10) do clock = lxi_clock_read(clock0) value = 5 + 2*math.sin(10*clock) lxi_chart_plot(chart0, clock, value) lxi_msleep(10) end -- Save chart data lxi_chart_save_csv(chart0, "chart0.csv") lxi_chart_save_png(chart0, "chart0.png") -- Cleanup lxi_clock_free(clock0) --lxi_chart_close(chart0) print("Done") lxi-tools-2.7/examples/lua/connect-raw.lua000066400000000000000000000006521447016333500206470ustar00rootroot00000000000000------------------------------------- -- lxi-tools -- -- https://lxi-tools.github.io -- ------------------------------------- -- Example: Retrieve ID from instrument (R&H NGM 202) via RAW (socket) -- Connect to power supply psu = lxi_connect("192.168.0.107", 5025, nil, 2000, "RAW") -- Print instrument ID print("Power Supply ID = " .. lxi_scpi(psu,"*IDN?\n")) -- Disconnect lxi_disconnect(psu) lxi-tools-2.7/examples/lua/connect-vxi11.lua000066400000000000000000000006551447016333500210310ustar00rootroot00000000000000------------------------------------- -- lxi-tools -- -- https://lxi-tools.github.io -- ------------------------------------- -- Example: Retrieve ID from instrument (R&H NGM 202) via VXI11 protocol -- Connect to power supply psu = lxi_connect("192.168.0.107", nil, nil, 2000, "VXI11") -- Print instrument ID print("Power Supply ID = " .. lxi_scpi(psu,"*IDN?\n")) -- Disconnect lxi_disconnect(psu) lxi-tools-2.7/examples/lua/log.lua000066400000000000000000000010041447016333500172000ustar00rootroot00000000000000------------------------------------- -- lxi-tools -- -- https://lxi-tools.github.io -- ------------------------------------- -- Data logger test - logging data and writing it to CSV file -- Init log0 = lxi_log_new() -- Log some data lxi_log_add(log0, 12, "text", 34, "text") lxi_log_add(log0, 56, "text", "text", "text", 78) lxi_log_add(log0, "text", 12, "text", 345, "text", 6) -- Dump data to CSV file lxi_log_save_csv(log0, "log0.csv") -- Cleanup lxi_log_free(log0) print("Done") lxi-tools-2.7/examples/lua/multi-device.lua000066400000000000000000000027071447016333500210210ustar00rootroot00000000000000------------------------------------- -- lxi-tools -- -- https://lxi-tools.github.io -- ------------------------------------- -- Example: Working with multiple devices -- Connect to instruments dso = lxi_connect("192.168.0.157", nil, nil, 6000, "VXI11") -- R&S RTB2004 psu = lxi_connect("192.168.0.107", 5025, nil, 2000, "RAW") -- R&S NGM202 -- Print instrument IDs print("Digital Storage Oscilloscope ID = " .. lxi_scpi(dso,"*IDN?")) print("Power Supply ID = " .. lxi_scpi(psu,"*IDN?")) -- Set power supply voltage on channel 1 to 1.2V lxi_scpi(psu, "voltage 1.2, (@1)") -- Turn on power supply lxi_scpi(psu, "output on") -- Wait for voltage to stabilize lxi_msleep(1000) -- Read out power supply voltage volt_psu = lxi_scpi(psu, "voltage? (@1)") volt_psu = tonumber(volt_psu) print("volt_psu = " .. volt_psu) -- Autoset oscilloscope lxi_scpi(dso, "autoscale") -- Start measurement on channel 1 lxi_scpi(dso, ":measurement1 on") lxi_scpi(dso, ":measurement1:main rms") -- Measure for 4 seconds lxi_msleep(4000) -- Read out DSO voltage of channel 1 volt_dso = lxi_scpi(dso, ":measurement1:result? rms") volt_dso = tonumber(volt_dso) print("volt_dso = " .. volt_dso) -- Do voltage comparison if (volt_psu < volt_dso) then print("Power supply voltage is lower") else print("Power supply voltage is higher") end -- Turn off power supply lxi_scpi(psu, "output off") -- Disconnect lxi_disconnect(psu) lxi_disconnect(dso) print("Done") lxi-tools-2.7/examples/lua/psu-data-log.lua000066400000000000000000000026271447016333500207300ustar00rootroot00000000000000------------------------------------- -- lxi-tools -- -- https://lxi-tools.github.io -- ------------------------------------- -- Example: Data logging from a NGM202 PSU for 25 seconds at 10 Hz -- Connect to power supply psu = lxi_connect("192.168.0.107", nil, nil, 2000, "VXI11") print("Power Supply ID = " .. lxi_scpi(psu,"*IDN?")) -- Set power supply voltage on channel 1 to 5V lxi_scpi(psu, "voltage 5.0, (@1)") -- Turn on power supply lxi_scpi(psu, "output on") -- Wait for power to stabilize lxi_msleep(100) -- Setup line chart and clock chart0 = lxi_chart_new("line", -- chart type "PSU Channel 1 Data Log", -- title "Time [ s ]", -- x-axis label "Current [ I ]", -- y-axis label 25, 1, 800) -- x max, y max, window width clock0 = lxi_clock_new() -- Capture and plot samples at 10 Hz for 25 seconds clock = 0 while (clock < 25) do current = lxi_scpi(psu, "measure:current? (@1)") current = tonumber(current) clock = lxi_clock_read(clock0) lxi_chart_plot(chart0, clock, current) lxi_msleep(100) end -- Save data lxi_chart_save_csv(chart0, "chart0.csv") lxi_chart_save_png(chart0, "chart0.png") -- Cleanup lxi_clock_free(clock0) lxi_chart_close(chart0) -- Turn off power supply lxi_scpi(psu, "output off") -- Finish print("Done") lxi-tools-2.7/examples/lua/test-automation.lua000066400000000000000000000007441447016333500215660ustar00rootroot00000000000000------------------------------------- -- lxi-tools -- -- https://lxi-tools.github.io -- ------------------------------------- -- Automation test -- tc "Test case 1 description" print("This is test case 1") -- tc "Test case 2 description" print("This is test case 2") fail() -- tc "Test case 3 description" print("This is test case 3") fail_stop() -- tc "Test case 4 description" print("This is test case 4") -- tc save test-results.log lxi-tools-2.7/examples/shell/000077500000000000000000000000001447016333500162475ustar00rootroot00000000000000lxi-tools-2.7/examples/shell/test.sh000077500000000000000000000005761447016333500175750ustar00rootroot00000000000000IP=$1 SCPI="lxi scpi --address $IP" $SCPI "*IDN?" $SCPI ":autoscale" $SCPI ":stop" $SCPI ":run" $SCPI ":clear" $SCPI ":tforce" $SCPI ":single" $SCPI ":CHANnel1:DISPlay on" $SCPI ":CHANnel2:DISPlay on" $SCPI ":CHANnel3:DISPlay on" $SCPI ":CHANnel4:DISPlay on" $SCPI ":CHANnel1:DISPlay off" $SCPI ":CHANnel2:DISPlay off" $SCPI ":CHANnel3:DISPlay off" $SCPI ":CHANnel4:DISPlay off" lxi-tools-2.7/images/000077500000000000000000000000001447016333500145675ustar00rootroot00000000000000lxi-tools-2.7/images/Paypal.png000066400000000000000000000300701447016333500165230ustar00rootroot00000000000000PNG  IHDR:RߠwSzTXtRaw profile type exifxڭWr#E1lěA$努wZRHdQI1ۀe+ML斳+|IW~;Wˏϯx ? {[~֯_z(("ϓX= {,V-}?>_癓r?|w,do%o@Џ'Gϯ,$_9>sN{znzƅmOyн{-;{JW_T@ӕ#GoUǻȮ{'q Br}q#4(6}fiYf5; XyUW[}M+λV;ēN>N3wYUsϪRU\ NjF|dzmQhhbFSlB2OIYNq;{{>VΨtQ9}S?jKl3m0W4J }">Z^=po/k"3/V1}lQL }*爭~D ԹJ`yzz_u0sΡ+EXn j,%M=0F_](>b`x Ů=!sPXc0P\ahO$a~W0?ǫtU:O*'x|JI>^#$0!2`Rq?ώ2Ӛa±} תi<;;T0:ع ܍MP6fl!1~&"muĊXYAG):GmU~ vL +3{:9(ϫ_[_u0N~2 ZK QY%QѓDȨ!nSU}MFqc"g<;z7;9m7] (cQ.]|IϮ&G[i#giaCCT2s="yb>Ef6IP HHzB#}ZzC;%ԓpc'Z.ld]AV(;6$P/E߁5]wa>@&PY&f\Ak 3+F 2= A+ޝ:C Cκa>c*W) E˻hlаQ, B>ݶsl `n*b -ZpD;CĀl܁F"t_¯ ` C?=>sD+C `8))IgGF2~0uGo|78::0GZ[cFP|Rfo 6Gc#Sz~% okA+FvH9,Ķ!̋]ŃP+ōeuNjdE >xhgn}20lRcE>F78!>Th\#T갍אQ %Cr|@ vbȹ{ư"l@ Y:R&Cu*Yخ8ؼyn* Ba^zdlBoXՖ3XΌY} a!qCͳ+u M7bNGlO_&7 ۴:iJ rTg,1rsfdM2*)q׌ poM" vw\$zRZDmcfVrI;C,;Fo6eǘwk:-FX'a-p%ԅLvԄ)uAps{2=8Y3Nh5蛛#G+-٥ SN¿@XB཈$Pp!LfM:rBB\KCX2Lbf+i,+[7 &2kvyHLAHle xĭSLdv §v4DIMw&}Q,I fH =Ш$#&PMzV-űرUsnaps\qR:\8QxmЩgi䟻<}0ÿFKGRX֘ʵTfxl/֞HJ{{#^&B}j6!<¼"tSM3EGj'L Ky낣=c93m7\[g1u9 6+2im/{d0}K4/yyF鎮x\[7`jk# XРAGd֐! fMWXF?= u\F3KJiJw -].fB OȌWT#ǽF\mcX Jh#MI-:]d.ޏY$&"Mu,"5ɨmaӋ6*F“7 :pÕ.jX"jP]9\H.A^$F,0<$E>zy'7Cَ4|-IbC+Ix^ՎSDYRY#j]> i-6$߷뇌1dG@%uF`XMHD&9}pl:d ႙kiA5It@]I: s}'YF̕lq<+?G0#M =H<^^Z?" BP{:O5o2e$7juАOp3TF:eeiJlpTbpS:<}z.;p_1C5* :0쏝RL*[<< @٧:?xm0]kyE \f= ͂!.7 Ҁ!IX:V(z<:p@Y銰Op5`P,CI#pח).@4"cP}vc:r*ԤFz5U/_P/;qɳ i$}$Ť~ҙjWCh\fyGoZ5`';%G[.--J8H<=$(ބXeǕ` j?y Gg7yyE:zl}|.o/-[K:q+g⬀=DBp` <]|v-N 1vqƖsՙ{/d/O?'&`ʹ|2#Yz ' #6@zU3( $&>V*OW^%/xe~'dx6ŴwCoS_:;0*zB ;p>u!Cz&4>MUG3_^tM?h,$AV_N*piCCPICC profilex}=HPOSED2TDEt*BZu0y4iHR\ׂ?Ug]\AIEJ/)}w^f1hmq1]^@˜ATf1'II=uSxߟի,DYf6Ԧmp'GM #8\xfLb6fES#$NBcg\e{r2i #E,AUP:)Rt~\ J`X@dgk'ƽP|qkhq'@[J$"G@6pqҔ=r|2dSv -!蛲-гͭy MJh}>{³r> iTXtXML:com.adobe.xmp օbKGD pHYs B(xtIME;$ IDATx{PUU?ppG.)JpD"3y)*KoԉI3{+dKFJrb:8 r;bGpؿ?'";gYg^Y2dȐ!C 2dȐ!C 2dȐ1J! ®]\A0WIII wX{_4 oUUU[ZZappp IRQ*=c@)z߱cO?#>NNN;CpVVKfffFF333\rkNS?^ϟGөC SY8ØٮN0\h s `(5՟xp`]#J&Ď}̙CDD:"Ξ=KWWm^֟g͚5:u .`00 ,_?,~zX9&,>Zqqq̝;E[oq!<X^#뉋c\x~d5[wܸq|{RVV&-[0ef̘ѣG~:;wdĉ,XT~WPT44n}wr rss%+YZZJ}}=;wϏŋSQQիWL& h0++Ղ7o jEy\ϜǯdAid7>chcee: @ˤ͛TWWsj;** 6`aaA}}= .IJv3!,K3]khسg&zJKKywٳg-[0}tyh4Fmm-cڵAMdd$Н0r]NpALZc~:k,T.UTVjl߾;:)ΎqƑ]ɓ'KUUU# 4,i~0m_R^գ`o>A 44y!<?~{YXmmmTWW0)Smضm8::SOVQ(Ǔ";v,XYYQWWGiiJ,4Xq@|(oǏKKKIOO禮 P__kuww'$$]vネ Jш`[sNEdBqq1o&/_&99%K0|735tҦ"2O,+lZ`mBcMwwӦM.~gʕ+e֭h~)ϔR]]MHH޸.:GåXz6W^˗YnJi8Fo3GAaݷfR]ZpXw^PP'蠪rΞ=Kss31sΕf}yy9]]]8::j%Q?K AVã>*u֙=mSStuuQSSÕ+W8#"ʆgEEEI8ząyyy5+V466(}󊋋z*'N4>{!&?EEEJAS\\_344TE!TwYڌqtA]\\$1Z[Yj RXX;ömhhhh4[UU%믿&33I&QWW'SMLIIARB@'m=W@VV֫iii"|Raz=3f]&(/V/--Mzu,_"go4r/bL<777j5F;v [|7?!#3V=7 h$Q`0pA֮]h@5c@?-rС{CI}4^;hvWM=ڌFՐ+))JZl2Ce˖*juRR! ޕJGBJJ[:N} yGsۏ{F_|(@q-C 2dȐ!C 2dȐ!C }{ǯIENDB`lxi-tools-2.7/images/lxi-gui-about.png000066400000000000000000000607411447016333500177730ustar00rootroot00000000000000PNG  IHDRr06gAMA a cHRMz&u0`:pQ<bKGDtIME  0[#B`IDATxy|eg&I U (ⅲ ."UN*(G,G)*7B)G4%1IsLi')'sq;@@>j"VDD:9zEv0{P@Q9A庪ySL+h}ءniAWsDD\PPe(U CCDp[ U pl`DDڨNV6m/T;ODDޔyΫ ,PB U6<[#DDSTLU&XYԆbږS*h5n;/XﹼҺ@- 5}Zjv]Դ&BBM*.0&P.1""ԝ:{'c=<PB%Y(LD? Q a+PkES~{Jg:1Wp.q(4PPqL Vk6|?뷅(N 6&L 10_&c('*OK=^'*!"yw׭>~[(ڒ@abğj*BܺuIII7ƫA@/CDtSeXPPQ.*FğA(T&@堫JCQsou߮+[%"֭['7lp,CC=E(d2d2gΜyn1 duTn&PD?<>\A*W\qٜf`DDulbnk׮/Q*a 12Z@c&0Lt2h4N.)){?y$tbܤI'Of"DC# SWQ( %bz4LJJJصEDTElٰaNnĞת*O))i ÄH@$l2VV3|{TPr\"sÆ Gl6Hk&H͆'E잋VJ?m߼/cVp7g!ݭZj! kw1y-F>821III7r(r8$%% /*jn[jJL&Sw Qp80L:j[c(|cX`XPTT|}c1] Y7 Ւbۯ0P ;L<%$$ 66:Uw6( <(x5Պjo'>>V_);8ADTK CZ&`0!W-""uh0LB0 >U8uEVJ fsu(bܹׯ_uܹsJmk@_ U"" YLLLu,c͚5xq=?<֭[ je&"0_5Pq߭s_|Qmo \1h7Tf̘^Vm!^ 2_Q-kADDh'q,lIL̙2L!"F "Zt:{g`Պ""nJc&>}`Ŋ["z<+fi׻}D?]Iz>"`0аaÀEQ 3gT>)) [n ?qz%T }1{G3 Il6[#:ͦQ|U)xQ-)))mVUU)ODDa$ EEEm&Z'PjQYY>Qs "ZVZZZJQQJKKa""qqqAokf6@!"҉$I(,,DII f3bbb`4W˲ Ӊr  $IBiiiDvcc(DD  iBDD`&(DD  iBDD`&(DD  iBDD`&(DD  iBDD`&(DD  iBDD`&(DD KQ@~wbf\N(D@jS@\uUqWe˖HLLftǎöm?b۶me 0X:U+Hf3 |ӻZhDÆ ѰaC`ĈҥKBAyEQ 2nvZ O>$$ կ_ǏǪUpCevUR1P(l1{l4nX*Q55ig?_T5򢰸4sުwuHcÆ CfSO=-RMQHzaRO>$$IbK@!U\_0bC5lԨQ( f23] %/bbb*Br5b4kLP-iҤ 3H5 ""w5=E&HK\c']vu& +t; B!)oQjNn& @EUW]w5H' Q( RUVzWt4>>^NlP0  IQL&A:1L RBDD`&(DD  iBDD`&(DD  iBDD`&(DD  iBDD0]"-N) YōХ]3M)ݪvNn-UwF٢jߺp46Hnլ3 }݇B [Ce{tj玮w޴^^$,{Y&!w=8S.( /@Z./]݁}N*{ejݬܦ=Gn*}ǶUIF"mc~+P&y3"_ ]\UYQХ]՝ZW6ʦ}6>N%ebТqR2?{bHA3"_ O*׾yC[cj/&U~:_2na 'C5 M۱_>}sPctX3)m֪N_NUr^YN,+3an*9dY!\t5?Tq:(Ɨ\^ܒ}RC]D0PHW {RU6tԎ*;듟5/xU/Ɖ3N;f jtpgr K ު}9[wo30Umw6XBR;~Һi=OJXҲ5[r0nW>Ux}0Cm]6ҕڃcm^K!+7Ŷ?[ 穾֤MCgsU3vwQb.Nwˀ/e,(kB3C~A_ G5(T(I`iڿ[<oYG0pʇ8v dyK4Z4 ^m8|\D3" &UW@7/}Ww2Eo=W׻ڱE Y.d@֍k}хB{yD4BPuD RJQsLuR.kfJB+|siV_mOsm-Wjt!MF K;m9*yt( vDJoVMU.i/X݊$ɲG  j͹b0PYZZoICo W65D(?a?ޜcgT$@uHvyQٖsl2cF~ׅsI.m!zުUd< X|zh iBFQ+m PiyFך\ڪ1>yi̦Ѝ[S#c1EIoP{Ac$ܕBFV$W0Pn>Zf ep$YTCԵRg}rJsAkߢ!nҶʟ`4VnIIIغukO$NwR<^yx̻BL,&qA|sJH &B7~x?AD5-""4@!""M0PH dYAq];$ʝz<}f QMY^TFL J =h]iy\/}ے#'tA)$YFɀ7W&ctТd?<{gq}R;}2$L_dZsi~Ѽ,v+m?'ݡi1ab,7JDK[-ѫs\ԐI+) w/*CW![:x,^X_(║}c2-K!<:aXV3^{*`cSvYV0?PB;joW%Rv$ĚѮ-UbkEݡ`8&AZL_^u}x/p?ҥE mFX+w!Z@Z}$+?+X& }l {;$2-'upQD_?o[=<|)vOHst]&wL~;\{y+\ݩ'+m9[ίuw0p5CFƘPTfGy.nX$i!|!֘*"E܏+;?؎eV͸=m#o2'FZXjO;ay>o0&1ʷyJi=l(໮7LtU2fC@!mj6Ǡ_2U:[꒖>?S/ނԎWZy[%_or[]=;n.m* ;%}[(#.mXdi+7fcἪp@!]ϣhFC ׅ(+A*L/mp h$)o x+^y;䩸f}SwGpˋtB1 MVZf,b[qq;4Z6Ir_$_\V3&wu~dy@1 MӰ( xx8|2?<o7T:̎ȿ=DU@!ʝ^gY@֍a6goѼзYsK=w.6Wn|D߮iSBϭ[.i׺i}SC\2;V}{cx#]"umF*-;3?qQ|e{^/C13Ժ]ug9U[ OՌ VC f W]}N SY;| I6vܚھg3bn2+}hq;Fkכ0Oy 7`$ʓ ./MUQĸ^>z+b_R8)'M9pͶJ-n쌇<MЧ[ْ|/@.MFebƽ^AGKf>K7wYb޽vMᬸo6c>mVQMcn| B~{M{[KtnI{ ߉'s^d<5 . `;]=*Zpse3}ညgfjHNIƮ7t-,1F|P޽﫟`Oe}ۋ#zW&, :'WVHxWi8 _ C׎ b3vV?_/ނ _+6`s18%qQwm'<طk'*]_{ f3]N.V 7^=;[R*݌|[%/dcYX}j}¨;ä>5{¹b&ԏG>/ơ|#bBh(15E?Sc Pjw@Q* ^hOl;F1! ~{ME-'Eop 4@!""M0PH ""4@!""M0PH ""4@!""M0PH ""4@A@yy T)..F(*] Rȑ#EÇ]  !222d^aPH `ڵzWt3HH $oߎ|Bٳd* Rһ T˖,Yw(0P((_(>'Ւ\|Ŋ[) TSӧO׻T EAZZ$Iһ*E(>~-/^w??(,  KLL ̙UV]!+Wa20LH= yP ]5лヒ &Ä( R3Tf3`ܸqջjTM'NO<ӧl6uB`PX|[*?YfٳzWtY̜9z+֮]0j1]> ƊB,Y][oEjj*Zj]eB] qlݺ=oQ+uq1L*(T%+XL&L&233}vȲ Yʐ<)EEY*(T-0 0 zWaB@jmPtaV(&21@0PEtaiDD  iBDD`&8(O!&&ݻwGǎѾ}{FL8 " -Z[o徕˾}4ݾ`O?ΝÌ3/@upwbԨQWڴiYfQFzW T1P肐u]jEnca׮]U@AA>w.@u.?^}Udee!=== n<]Eᅬ_\п6 E[no'OD٦M|a8u7xEֿ*ܼys 4_=Zn88z(e_}뮻Dc`ڵxGlݺ5V^Z"ˋڵk_6m &x=4jҤI0e*N:y]իWcرҥ `4d>(̙SIDu(1c^t @)7p{ʕ+j*q=`ԩZz@q)L6}hĔ)SpEsw%^y,?Dcǎaƌ?~S.8 Nnn.f̘ӧwu5h=z( "."2EQsNwQD EM6kuRwk|ǚ_O EcݸCGͱ~(aÆy]駟СC^_t)xԯ_ЫW/\s5HOO״Xp!.\赼I&^"8Ncܹ34hYQZZSNѣؽ{7~ST=V5/x̻^Ӯt>룸kpe„ 3fn͚5x[P@xO/嚇Ǽk-p<8p v؁111HIIAna( { ]P(D*/ g\R**d6ѡC岳1vXl6LTB!Rp`ҤIѩS'4n5(8}4كիW믿Fyy%u "N'[|zW("ˋ4@!""M0PH ""4@!""M0PH 2A0d۷E>,^V+QmbP+A-܂-[,k4__ ]MJM׵6/ƚ܇T7JyKE|޽u(8trss7?>y*?]&ٳgp8p OXp!jt#R!E6 %2"110tPt'N$Ie&Ix wQ4h۶mìY`2ЦM=7pX}vyQ@{ƍqFf7o~mi&ڵ ~)J6F#ƍѹs}ma׮]֭{;˖-oɄ 'A0h ]HOOGFF6n܈O>< Zh={BE?~-m6s=e0*P`0`Xn?k׮A!Q lP8pGѷo_駟F~ꫯ"77cƌ f^/2^hݺ5|J 䭷_|8~8'#''s-ZCbΝxر#L㧟~BFp l6C|8|0N V^B'x#G󑙙&MѣA!Q ]vaݺuSNO?_{b:u*V^ :u*{tEi_"-- {K/SN`0xZ0LϹCri۷].)) ߰`|͛7Cx衇0~xUe|կ_ `ӦMؽ{w%"f3bbb~6 [lqٷo~+)))að`^uO}H 4u1Ȳzm۶Z6m^{5wɄƍ֙3g0sL̞= VZԩS]LvW_}rlڴɽL$lٲ7x# 2222{G [nvPO>S5 NZWKEsp5נM68s FVVL?{/>쳠+I݋ ;v 8{,mۆ?cƌAii{`CxTC,˸꫱w^L&oΝS}j_<۷oGbb"={܇D0PFM>gϞŽދqơWƊ+EexW0h y>wNEQ0k,̘1Q\\7x۶mÿ/l6<#hذ!cy%o]׬YѣGUVp8صk^|EPSp̙3q9<0aΞ=iӦ!;;;>$ D`*eyc27v'.F~-/_ ]PIIIغukO$NwR<^yx̻B!v .CJJ 7oBT(DQ`07xb]%@1PM7ݤw5x0iBDD`&(DD  iBDD`&(DD ^Hub0C1\m!8!H$޻0PX(F+oPD @,,+c(T(F dS<@D(8HF+DG1M iBup DȦD byQ7G"81Q&R V1|. z-ը2`w5BQM1ZeRwPD dS< N(dc,?ao"NuFT\gRD6LQI1Ce߀⎃Q^ bf#)?9IP f^QOQ-J!F؛LWao" &W3 $UBI柮6$d0e'orLQz6*nņd$e.wELۈj(JiOW6SL=Ƣ#PH8sL7[P/cED E)Z%/YԍLluhAϲ |~Qaۚ KmHĹnU?Am=&0@CFTB8glSؚ] (opNȽ.j(b Jz@v-F(0P(* R&7- $k#uz[~04z킖E#c<yni{RjjjzAA޿갊z]뵕a(;w%KJJ֭[{( pzerc5]o ,ӻ MD(Dg)QD(XZhFt e@&8m&2N  E=cAA,/һD@:A,/ʖ A,/ԻDu(TgEPϙdbvsQ@:Ep`쐍i"CpUxc(T( DG (b0W<Q0Hm\qo. A*}NcP&HvĉjIQb&(DD  iBDD`&(DD  iBDD`&(DD  iBDD`&(DD  iBDD`&(DD  iBDD`&zW@-Y.D1:@Q`0bl6`0D%"*Y!Iv;$I A"2 bcca6QE(d2v;JKK!IRQ"2f3 QD00(**nPɲ 0!"#!!%"Ǖ#*P\-xBDa6#.T"&P\lEQ[D(eVUE Y#&T""Ph4b] "aX`4FιU(,O#""L&SČ(5!"  ^(AEױYH(Eұ3"j JD"BDDяBDD`&(DD  iBDD`&"bD}(((?wuCϞ=ѣG4o?U6P_ѩS*}h4bٲex'ҥ iD&LիW#-- w42j(㏪rM7_~A-jN,ȑ#P0ӦMõ^"l2={=i&ڻw/bbbЪU+ݻ@^ul۶ K.uر# p,x5DTˮ:hܸquW_}{/lFnn.4htCQt(:tpK~ᇐ$ CɁhȑ#ѷo_4n٘;w.^o͚5Ñ#Gxb[,ÇGf͐ o(Xt)~7,Xqaܸqɓ'c͚5AD^ĉs΀ev^{ 'N1x`]uMD}W^^N>5ѻwooW.R;bPcǎEobر(,,̙3NLL }?-{k(R!%%EUٔkGm3]^DDz6mT>^Ex ;[&DD%$$`0@Q( dYjջ*DDQjB 0X,zW(jX,snUD,S㈈H=1c)kM:vFBW`л*DDQudxV$/!"tt쌈DBEH9FDQc&(DD  iBDD`&(DDȹ$..={D=мys|84h999X`l^?j(r-h޼9fϞ5kƍq&O^r=GARRΝ;+V`ɒ%e(bФI}0w\ڵ+w}7f͚!?? ,7|td—_~e˖ᣏ>4o| Ə[ݯD^x'N:nڵ+^{5L8ǏQZZw5QgWaa!?0vXsE^^F3gb(++CnpA̜9ļy裏b޽G}?,X;믿1c`^zرc5k 9G}o[;wK/"t >(ۇpUWa>}:, iӦaРAAA&''駟[o 6A8ydujۯ%%%z3 UM4 &)))x0yddddx :(111hӦ ƌ|dff"11 YvZYg!%%6l #F@ii)8;ɘ={vHvmPqVgwÇ!z!Y$!>>^ѢE t;L&ڶmȲt,X~=}!''͛7w\gگ9"u2P>-܂'x=ϟFBqq1֮]իW?p80b4k ?1Efa_>rrr3ϸC"EQobʔ)6mJJJxb@ٻw/fϞaÆaРAp88s ;V}ѠA :-ZDvv6 IRu#G"11r_l2P.,4P &x,s =)555 d\ Ѓ(Xt)~7,X@zQt wLD1<Q =[P@xO/嚇Ǽk-//)))ʦuW4]^DDmڴiHKKSrIL>]*knaÆ] "r뮻nEDD`&(DD  iBDD`&(DD Y" L$;#"PAԻDDQtjܦꊈ@*EDDቤcgD zW(vP\\;B$l6CD5l6G׆ QQRRwuFII( $iu":(E6 zW(bfy;#Ad]_lQXX҈rlv(@\\,#"ҕfCII $I J"2 QRRٌƈiYt:Q^^I BĆ axkɲR]="Z$H  ׼s-'"F \"3jǾ H߁DD5-Z(.ѲC.T<]4@!""M0PH ""4@!""M0PH ""4@!""M0PH ""DRe@DhyJmD(Pf!jv.QUɲ I`p8܏;GlȲ XfCDTDQ(0LݎRHTGdȲ ٌBDf3f3`#2T"F,b0LHHHbq W$>>^Ex ;[&DD%$$`0@Q( dYjջ*DDQjB 0X,zW(jX,snUD,S㈈H=1c)kM:vFBW`л*DDQudxV$/!"tt쌈DBEH9FDQc&(DD  iBDD`&(DD5_~zWV0P$" ={]"#GDvFcIE <۷Pqe˖'.] 99YQxWV^gjbO/`ڵx7qʲ#G //@EL6ƿGFF~W5JԨȹ~5$$$`hٲ%Kdff"&&;wdY /. d|Xf ݫwujDQFu3f ˿;TF-܂͛p`Xr%F#F}qܹsg@LL {1qEVVcEQҥKoaƍøq'OÇGf͐ o{Q-7o}:R@X,۷/;0իW/;v f͂`#GcǎE>}0w\aĈ9s&R?~;-ZK.C룏>rEnn.O㭷† РACJJ vލ;-_mTx߿=_^=m۶.xb6m6­O=w!C… tRw!բGyK,ѻ5"OlX~=nvn:=z-[ġC^8|0v;zzn{ {۴iƏ??L&޻jI^(J@ EQ,\]vŢE'`޽0 ر#^Ν;+V`С$ ;vjEbb"VZ"|xTj$Im݆,k׮a2жm[@ew!ٌqazWD}^?0F7̟݃?ׯFb]W(Xx1 ׿?0qdv!-- +V9s( L"(#`ɒ%zWF@9z(ZlիWWZ1ȲΝ;#++vA,YEqիE J3R^=kفb :$aǎZHLLĪU?0p!\wu0+vÇ!z!Y$!>>޽}EQPPPTlG{7Q27n&OwUjL ̟?k+磠èQP\\kbՐegφfѣݻwCQȲ{b6l Á3gرcY;ǀ*}?ѣ~zݻWc8KX<]/wi{RjjjzAAA Ȳ YѤIM60fڵKQеkW<9r$l6˃(ߓu֞ Hix\wMםJUtMENB||< Ǐc߾}zWI&瞫0$tΝ;O>_>ʰuV(//׻zDTGؿըq""r]H ""4@!""M0PH ""41P+""R'( |& t:!B7 QDұ3"EvADuv;[(.!IR'l6$I QQRRwuFII $}f;y+,,tN"ED+aEQfCqqU""XŰl^HwWii)[*DD~4\"才(p8ŢwtePRRI„oȲBl6#&&F1bwDD5Ee8NnC$a >ykɲR괛$yD U Z(.yDDuUĖ@Q"#k3D"ug1}jQ]Zbxх.JJDvy%;ӥH ""DMJ!"y5˕ wiIQ "!"E @c7N>Dzpl1Lz?"":d2pl8yL  ' +(rL& ?`ұcǎ*l{]f3EرcGHU\}`X`0ޗDD,łء++Tk jywW ~^E򢢢런Z7:Nރ8l8 @9*Z(ǻ8Jqu(B P&2ԩS7n\lX$BDTK t:@*]U3Pʭe>]/A ➃LDTטffa"Gl ׻Vr)ȢO9p:u(kkTj!"Qa0Ab0:y?8@)J|]uw+ow,!s|ލe&/e{Ĥ p z "rE[^^5????8x W 1׻gPy\ŷZol pqN=^m=лlNV3yor;|ygWa_D""$Pk xgnЕp |~?߀>y`w۔`&2, "-ww|{+|EDJ.rW ^\A !.0JP|׈(4_*u7:sYb8zD?|["",PVJtW3!]@a˅'?B^&i@q- 53jwp1x(ZUw&}׫ `W8o]Ug!""uJ j*J]QB%:n*h>` 'TԔ gBD\&(&Y^@C*)*˅°! ڱ5A惍[`e*!"NJj\ถjB=K <LpQS 7(T `:-"`х"S: T.IEbPUMV`jMFMtUqH{Q7_Եhg.DչnU[/?d+&tEXtCreation Time2022-10-14T16:02:46 CESTPh%tEXtdate:create2022-10-14T14:09:43+00:00=%tEXtdate:modify2022-10-14T14:09:43+00:00q`tEXtSoftwaregnome-screenshot>IENDB`lxi-tools-2.7/images/lxi-gui-benchmark.png000066400000000000000000001006321447016333500206050ustar00rootroot00000000000000PNG  IHDR4+gAMA a cHRMz&u0`:pQ<bKGDtIME  0[#BIDATxy|Uս>SNHaܪmjkZVmUW:u, 2$c0 2gڿ?0 $ad83?{'^ːdu~9V]]81Oj]aX8٘ yR<{lKmgZx}Jjy8V{"R=gckJ3dWVC_[x^Ɩ[Ts4g -̦7_8簹RP ^=:hxj߾}sr>*z2 @2MS~_qqq}u떵:"IPznnc$j.̙3+..7;vBG}T^/..֯~+ݻO:A`/ۭ?WLLL`ApjdSCS˦z~Ɣj4ךZx7۠&q8|5k֨6G wMlgSLȑ#y=;;[z]I׿X]jtsю;٘͜9S_~}K y< ;jX|-DlZMt:Ů4iWc'4-^Xszai롇RRRw9zƏ~>tf?{ggϞ+WԒ%K>./99Y\r&O^zk׮]5{l]}՚6mn]n~\VVg%ѿ8`P^7ID'^Oڐk rs5nW}l;!NvǑrssmiI:0c=vҺu$IGV>}4ydM<9}{:>.m$jĈ1b~*99Y@@Z|%wioF|v0өn\~ZX"[iriɜ׉4 u6Tl"F骩C=9s愗p2 Cw~(666Ykw]ڰaCvk?mݺUn[cǎյ^l'|8N5Q||jkkU]]ݮ7ikf /wYl׏7h7CtKRgJ}jkk]Ip;ֻᆱi/~<͙3G˗/O<\ >\|ewywy&mwye^W'UEE9 M55юp-Msk-x wP5!]֬Y?O`-X@7x$i޼yah_cƌQ߾}w^j겒ZP0Yg8fϞc6y={ŝp(j(111PShMek 682=?R f.K?K۔{VX!Iݻnpؿ[4{lٳG˖-ӨQ.˫?oqԾ}i&1BCW_}ew]Zs= ^o׽xBQSZt h4DG/^ ,8!L>TݥwaUn[z.B:tHf?ϺTO~婰6111[Nґ6)6 #<系̓B.**:g<(?3̞=NtGhm֏:^KDzqihݔqh>T[nE^{ m2MSO?tպzj;iz'܋xƇ2d$)??_+Vĉ%I˗/W~~~Ϡ}K1(ltI_bm5c{\\***kƉ&iD-wS<7Q *-ޡws*~=d- %I? ¯?͆ѣG_E]ԡhizUZZQFi׮]ѣ3*99YP߾}n:hܹvߥM6M999ڹsnVM:Uij… BׯMc=~zIG&ߚuff@ M6]vwH@SV^msGw.3g{V8k2 ?f^[j:z7mmDd2ƹ }iJASJwa^6'./ ]ѶL SӧO׆ ߣҰa_. OBdrnM{ռyeee'a͚5*((P>}t 7^83111/)˥?Xvɵ"FcdSn?ǫx3Ks9Zaӟ?\q=\q]5YlZZ:܄n Ls)y>VdCSr܍z]t)AJee.<7Q?%;}2t~]r9:"CnVn?=Aҝ*1*畒$!wm7%]_T/@iʔ)K/$Iz$I[n K/k*--.'j|}NN֮]+04zh]tEUm9`PO<[]vY?rrrt+v|RHtVn;ڶ]s!x=j2MS /[4sLqzg[Cwm~f3piyd* C:k`VUZFIkjꂦ58ݥWZ7Hcq yN;$FSiaH7NSRCu}!SAIo:rqlimHqC_oÐ<*LSI}|TNs=뮻$P>򻜿:묳Y^eʔ)2eJѓO?򻴍7ԯ~+M3v~;lG$tM馛Nh Zֶk3g$;tdb;S>l8Pq'tͼnysuzvqn?-^ z*-+82_vSLW]Ԅ'inL[kk2;/ӝ)#--MӝJvh_L鼗kN}vo#Fk sֶYk3g w!Iz'\3[x.)2t8ϵ5~R.Gґ_zuyd2dRa0M=|^~zj=9yCqn{  GL)2j]0$YcEcVh2kz._2ЉI iN~\KFxu j9q5~Soa Ɨ6 p~9=A5!rUԙz;Z^o4eƺh;3 B;kM yHi2@:FjNvUU9 CC)NUL uy!o߾ڵkmƌ#I:xTȺ:Ƿ[QS[Bm{d~_5?c͙3eNRC_>SXBf̘!Iz~ٳgkŊuWgϞϴj*XBu-vwZb~-ΥoYMvv^7[-==]k''++K\s1cƌ^k뿩P(^ѹUWWG]\Fe~mCs[o՚5k[oi*))GyZvΝlIGMNNV^^ϟ)SoTuu͛g!Eݹڳn222%KhTXX?dNk뿩zaZt^~5Çӵ`u]ݻ$izW'wȑ#OܹiӦoW>}uV=o~ArG{ァ3goVϞ=~z=Cڽ{w{<=ٳ<֬Y҃>N;M>O/6n(I;_Ryyy~͘1C7|zkGit??/s}[eΝTQQO?]a.?я|֯~+Cn[6lH'O_,ܹS/$oԭު|=c}ݧl˗+##C Ў;裏HO=UWW>L/233uwr:zgTXX>!Cӆ .j&hm7UPP^zI>V^G}T2 C+VП'ݻ7fW^GU[[+!T[[KMXS0@pB[n{ァJGCܹs])!!A_,yOܹџ'B!=Ӛ5kRSS5j(-YD<4`צM㏫w޺{)))0`-[7xC&L_3|J%%%_~Z|.\O?]@@rssu>3Ow}w~y,ok/__JJJ_=z jkkgy˜ZUWWpLjHÇs/z-virg?l/[o{j۶m BɨscI 8{L_}#yMh{'˥kUW]_7nzc>t:Cko8TaodguA]V6l_p3<-3QM-}}>_\r%8qyns==;wgyi黊jI}mïWW^GP_uubbbvr߯PH@@~_uuuuxخvw[7i$]s5ڸq┖ZV҆ 4}tKڰaӵo>B͟?C͝˗+ ꮻ҇~&^b:(66Vyyy;ԒNґeGŋkԨQ0`1޲etwh _kϞ=r BK5ktڡ} \AgϞ?V^`0+Rzڼys={k׮U(M7ݤ>Lqqqmt0 Ѩx>_k뿩L:U:{n߿_]{]K0~:_}̝'#׫ ]{w<=|;_~ꪫ #'ƍ^oM^iӦ(r.2edd4zsrrrtT0?_]mۦ|Pɺ}vWR0׿U ~3 2S|JKK5vX~=sںuG~_?u{Ͷm6=zt9i>@ׯ׏c]wu:pqg BzuA|JNNjʰat7СC#]{@gHiX:*?7<9w}>yԩKo=E/d+Vl]. zƝŸq3_# '*))I ,"LRPR}ǡ7<l,9y1 b++'1peB ^~L%=yەz ezR@;ZjƏow,[ga6: fXBXBXBXBXn bJJJ.2Mnrvۭp\[!KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK\v@Wg PjjFGJNNQ]]***o>}ڲe8 4eF\. 0@gq $0UzzF%ϧ;vhѢEںu|>Aáds9ַ%U#GV~qF}*,,T0'9$t:K.DM:Zx4fedd>ӆ ><I @\. 4H]vRSS[ի=\\.] !C֥^X/##CӧOСCr_=DHfffΜnݺE4<իLvi!@111:tͣ Ј#`!NBH"`РA8pbbbu?NSGV߾}OhfW"<֨Q!KKKSNN>tI @eff*33Snݻ} 6۷;tzRZZN݇8 hLv>nz>|I @\.%%%uz)))>i  hy<[e%N^Htڶ%N^H  4M[ m7D jkkm r555 vI @TWWg)DUSSӡ ***Rmm݇8 hUVVv>ta:6*,,;4}*..'p<RRRԭ[7%&&*66V'&c P0T SmmTVVRUWWG:_^}Qn˵m6E혘edd(--M BURRB'f㕕>}(33Szx}Ԉ6Za\.bcc޽{k߿B,I4UTT*Dt(kII>sZ*bk?/v-ot:^zi޽r-&^:IQGj9=8WӦMSnn^o';&+׫$OW_}<תU tE)115>|XV\SjȐ!:C={i2f`1b<)NSQvvN9}Zvk:x.bׯU@@7oּyTPPP].SO=U.Wp81bVZ2I!7a? t8{Yb06Z͆P(r^ZEEEPBB޽[sѼyt!BPvv5mt:UUUݻwEZ!.!55U]v 5k%>}hӦM;wn)ϧ+VhʕׯFG|:xo߮<ܹS`PiHǭ{k"2vg+RIIIv.K#G|r-X@M5)o߮۷I\\nTWW^$$$G?wv';t}H@r:5s.Kz5uT1Bך5kTUUu0hfQFR]w"~G_@t @E}h袋4z6MtM^zƍ>L;vPMMMDPuu)33] n]9a(--M]vrssO999vZ͟?_Rmm-Av+''G_~yćھ}jjj: (á=z; pRdž`ر:tV\ŋTx=Z~Df[m͛wވ-1nH@8Neee/VNNIz:4|p-YDyyy*//oa(66V=zдi4bĈvTTThٲe*))i"H@Dԯ/xE .@vVX 6LUUUY;p(..N1b&Ov]*N- /789 mf2335sLۗ،duY:ӴemܸQSUU,1ө+55U Ҙ1c*ѮaYFvV@"@0 kƌ0`@m5^F#F\*((СCTQQ!'߯@ ^ptv())I=zPշovα!4g-YDT:?miӦiСhB h^Hp8JIIQJJF`0J44 C.K^7㘔a4M|ƌvߟiVQQ:*..Vyy]?X?#iBBԽ{w+==]֭ݧS˵n:|po}[JOOo}B!UTTP;w_{7j}:4uZPHҗ_~5k֨Q ~IH˵`D4M2EN#NSk.-^X[lQUU%`xӲe˴pv tꩧ*--#NQTSS<-]Twﷻ$@"@,X{@@֭_|n_~=z4MB:|.]׫Hi]  X999mn4M}O-<\.M:]vvuuuZ~VX={Dt[@EXVZZ={hСms[}Q/8|pߟBvܩe˖i*))l kׯF!0ZN G}ݻw[qqq:S`:ӗ_~-[D> pB8e˖)99UbO>D֭kמ &W^r8v.ۙ;vhժUڶmJKK#z+B`0[0 ͘1C}iϟEkW5a}lSVV-[hݺuڻw*++qp|>6oެRr)=z[ܦB~֯_voʔ)JOOorJmܸQSk3gTݵkUPPj* }. h߯{j֬YZr !C(##C'BmذAk׮Uiii1aÆ)&&SVSS9s樴T6mV||zLSJJJ49Q0Tyyt!ݻW*//W ]jPH555ڵk٣yr)66ViV@ |k5NLݻGU T\\P(@ ZUVVСC˓VbbbccrrQTSS|>B- # mVb{+++m 3ÇW~v>%a%%%Zh1`0`0xLlii$)A`$ 8^Wַԭ[79s樺!(=9?~jَݻwk\ )z~Jݺuѣlw)a`PsaE@BtjC'NT^jkǎ,RN-++K>:V .TmmݥQH@x4~xRL˵~}t9H@d\]NXIIVXK N)>>^#GT=.%, /ÇY% СCտ\ѳqaa}tYH@ӽ{w >\iiivVWWKRh7H@v5l0Dղ۶m֭[YХ Jff dK ʕ+UVVfw)+$ӈհaԧOK 3MS6lPAA~ЮN0 GC Q\\儕h>N H@C*++RBTXX`0hw9;$ 9hȐ!rvVTT|]  zݺuӰaÔnw)a`P6lPaaB!v5` 2DGڿ6oެJKDOb#GFղ@@7np!@Vll ]J#ںu.ED=zhԨQ0ϧM6Pi] Jvdgg]J#wֶmTSScw)t8$ 8Scƌe;ez'-$ $''kJKKFvڥ-[RU\.5rȨZZ[l޽{.DOf$hĉJHHFvܩ||>K6H@x<0`,0.'R[n.[ Q#%%ESL㱻FvڥM6) ] "@ըQnَ2m޼YlG0 uMzjTM#Yqƍ Bv4ɓ'+99Rѯ_?͘1Cv\v89eddhҤIQ5qNxMR,W_Z999r8yS`8}Q9t%NS#GT߾}pB}W*++c@G$NSƍe;NDRR.]uU8p^o z HNN.#"rssճgO-\PVRqqeq@:ԴiӔbw)3gXz#]=׫W/M42"0poܹs~z>|Xi]A$Cy<s9]zx]xᅺ ԻwofjtDtAiذaoR@@ Qƌݻ>ӶmT]]mwYS F7ws4ox:E?>XBׯW]]\.bbbp?&99Y R0Tiijjj. y^۷IuLI5s$CSO=U'N27ou,atzGUii***lе ^FF(>>>h…ڲe~8-[H~_gk4 CYYY޽*++UZZP(d[= ԜNfΜAE4Mm޼YK.UIII:m۶HLpcW4 CݻwWVVURR@ `K- s9G^7햕i…ڱcGy`PEEEھ}T]]-0l a(!!A{V(RIIy $$z Im֬YUV긟B:|p8HVVVJ:2OGk3ɡC=U{H9tiÆ SnnnCځav@@[nծ]Իwo 4H Rvvv.Qy)4M͟?e>Q h7))):SvꔗVOD}vٳG۶mA#{$5a>|X˖-H@?~"]iӦ0ԶӶmArРA6l233#Hs4v$D+$]KGVLLLD-//׆ wވijjjuVݻW;vСC5l0r:JOOW~FDԤIG4m6En4UYYM6i޽ڹsƎ\y|]_^cݺuJLLT޽u.K ڊ (׫o}[֭[D!ںunݪ`0!1x`M8C!@[ 5|pvGݽ{j8%NS={ԤI4x`v>O%%%ڂ 7N)))mZڵkLl{HLL5vXeddk|?Z cǶ:Znڥn˥~iԩ۷:l I ڷova5#>Lqqtlu릩SjĈJJJG+--՗_~nH!@tjܸqիWDڵk֯_ fn&LO?]ݺuzVUUUiɒ%ھ}-D mFjժhٺ Էo_yPuuΝŋ+R' h׫1cƨgϞ b>O۷oW~~~&z:묳t)FDÇӖ-[mE5`_;o>-[,"0 5J^xRSS#>ωBڸqy) V ' h9RiiimR6lО={VuEiĈGH/V1 CGV~":t4pc[x<M2Egum=Wijǎz7u![k-VСCvKJJ|rj{á,]r%۷m9JGcmm>-X^G@G0ۭ#F('''ڵKk֬i#|cnl]U~vء>@{D@؉ 8!ah2dHDNtѢEZ0 j̙޽m' R/… U[[k[-DpB5l0eggGݺ:mܸQ;vh >}222l9/UwڥO>D @{!@,s88pMMԡCxV5jzi5@@%%%ZbKUVVvx t$nݺiذa嫪ҲetVmt:=iR;v… sV  @,q4hvvޭm$$$(99Y.WX|:xVXիW ]K2335b%&&F݊ -XMvXx B*++Ӷm۴tR8i m7hӦMڲeK%2jjjTXXJyyy\8 -r8ݻF.v,X@PMmUUU9*..V~~V\6 @gD(11QC`P˖-VuuJKKv#ViΝ;zj竺:΄ hR߾}5bĈ/{nX""mB!رC RjjjD:p6lؠkj6ThE4+%%E#GTZZZDۭknݪ1c())MkTB!k˖-Znoަ ~J&h:thӦM"fqq֬Y=z󩠠@k׮ƍU\\c3#@aw+>>>m?o/֯_=zhҤI](RQQqFڵ9hp ׫+'''m/YDRwuu,Y"˥[ ڴi֭[m۶4- @1cDtFS9˖-kڋ_TcǎU^kǎڴiu&8F<z^zE@ ?\~ ֒%Kg(33SݺuӡCw^h߾}$] ЈU߾}rEGƍa|ڲevޭ$0 AUTT8AH@#'vTVV/e9t~"*4s8h˖-Saa! B^o>X F|>"V(ҢET\\L#]HMMo߮P(6oެ|& @ *,,Ԯ]Nmm.\2z"FLTQQ/^ܦK.]ݻw+ }H Bc~m޼Yy&ٶm/_*D@TUUK* 3T||vޭٳg ]!@d***pBjƌ߿NgӜ9stL "߯-[hΝݻF~[n2 Cڱc+#]p\iN۶mӶm.؄It                                                     .$)cR˗:o|T 9E9^rE.UL2]jt3]e98uݥpTY0ڬS`*νFQ8uS'(97_ݶѩd fRFݦS.,)KWZ%J^lowgMLS*>E&({ l圐NG_`:ã!?S_] 2&IEӟ̙vWs0s?-$]%Q ͸t84yݥ@ĕ&ҁ̸tK91I:8忎]TE|_Q蔇 N UtvѢ ~ͰU'QQ=NTH2a̙ e4)=n ͞A7LʶcD],u<82U2gO ]Q) nwDU,ν jD[F3]eC.FY␨ꅌYs%@ԉLVqS:!jfdYlK-)*dEdK-9Ђ!RLe =]DhNȺvQ/җcw !; 뼙vQ/Izѐl~g%@ԋd{ 9JQ %)yݳr|vq|J^e[(ߣ-/]&{ Q3jCQ %ɳ_?2e#]F2@JRҲGR2äSҲG.YQ %)Xe@KZi_ow-re, KKZK.E %Շc KJ)[ .ݥWHIR]ut)(mϢ^HZ?::5Gȧ>OG9Mq]l[Qvx=<O dQʢ_)t^!v-JWmoY0RZSz΂J/n},"N$h[J%w:u,n󕚔>g"c2l\ăKSiڜ. {{M^${S]`sT͔ϓ*3^!RtrO`<bbJ6y`UUDuH]W0_qv]@Z`$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$)qqqzr:4T5֪_ 7N;up<\.%$$L``+#g}zH))){ Q[nZz ]wuzWtg_Wllu +--*]y_?2d~pD}~@+))ѪUl2z4p@;Vґ^o]}֯_7xC#G ot:uO>ѦMj*:3%In[/_&;;[yyyy6n[ׯbcchѢV￾kɒ%z[ߛ VZu۠yVg|>nFM2E]wy=pG;6簾'Q<TTT; A БDXEE6mڤJ/4i$]wu;w)''G_u[EEv)߯q5۾i*..V|xo~"_]\snLTmmoStBhF%ө7}"z Xr^~evm7oo߮j**%%EJKK{?~o߮7>/ >O~mڴI/CQRR>zI&irUiiBB6oެ.Hk׮a*..Ç&55U͛?z>~~m]{ڳgӟTW͛ >]:^xAwr-ӟb}߮ }z #F?Ok5j^RjjnV%%%\k׮ liiiiէO~W$cgQee|I緸Mf`^nFjɒ%z'~>]!)cȰVkύoo]Vҋ/ӧ2 CӧO׭b{NS=FBZܧ$%'''Pzzq:z'5qֳ>>ň2gyΝKo4t2HI ПgAIҡC+{m۶-Y0tj~ȭު>P^}U(//OO>n6tMzrh̙Nĉ߯nMgyn6߿?^޽ug%@r8 ߟ`P~eNCXFk=zc>S}駊tdxhJJiO׭*0dnw=|o7 uTTT{t$ұL81<$4M>IݻxO0 ZjwȐ!:5n8*==]^Wڽ{,Xz5я~SW^ ڽ{-Zڷo_ի.rM:U999U]]UXX-[hڵ={|>$iԩz饗?k,y睍79y馛kk>}i֭[y۶mZr^{55^ /k{y睈#33?0\2b:lTDê HIʆ#{'7lؠ-[K/mqG[\}8jom8Pn=)))JIIQaaa_<^o2DC _{G}1m^qF)..Nٚ4i -_ p跿czCW_mu]̙3x̙q `+ج('N۷~(33STVVueC=zPϞ=5hР74k,Kmmذ!|,ao^z<]}pPSSsM+qׯ_~o[=1D=>|x/R=DŽǎO?t]y-ch>N.fv1"HB=zp/^(ҫzL̙3uJ:K~;ر3w&VVV{ծ],'hժU?~#9~5k ??ڹs B=*++SRR /Rґ/|~^y}zꪫt90 [oOSݻ{mk_o٣Xw}իW|R)h;C^zIuuuJOOȑ#XhxF޽;߿л}vmذ!b:LVV^~e;ܹs4\rr/>裈ձgW%[o?qI^?c^{5okUM׻䚘w~?_lz,SLQ\\t+555]v//pt:u-[lKGmݺU۷otkzQOں?0ٳg7cH$1E^zIYYY֭[t7gϞfl!C/~7y`Sz쩌f7 C?яtAkw bF(Ij4$866V{V~~o5 1#k4D{MzK}jkk\_[t:u營͞=;b:رc7ꫯt-sc߾}>HJNN}={_~ڷo__ۧaÆ0 %$$hug0 y<=Zxq=_~Yiii,KrwgϞ5b!˥{G{sW-g=04yn̶`P7n׶jֻdM2%N9r)*))믿W_}M!-=z~~c/w1"It L0A/r8< WII1?Ó3gNv?p8?Qgȑ#ܿiʕ+ӟT6m ףGc&i~px /~%Kw]=Gө믿Z[0VdFxp@ ЦzN.^oSO=uJjjN h>.񙦩?ky;Aegg駟VRR#d駺ۚMI~__u}5>).QفbŊP({ `Qۦiꮻ 2DׯW(jZGxhU555㦤XA׫3q $hذa6mZyyyxf>|X;vЋ/_|vkt$xZ`#ԣG-\P۶mSyy<}{u%%5wynaM>]g}VO?vޭL?mtmf^^^6[oU\\#͚5Kol"0>}hԨQ+!O?Ս76mz̷ÇW>}}tGIIIzoZGnG-_|:s`رCtd6߆l@uuuW?fϞ-ۭ>}h˖-C.Fs̚5?}@#@N;F8 /4Yf;l>=Fݻkذa-~~iuuu{Fcbbsvir\2 Cַ]#_h={sE8hddd[nirYYY"4wpK04sL͜9Ҿ~|Mu]I`&N^=kl}Ͷo-[~^QQ 5 C\r.g|pl>tgWVV?orִCXF {:ʠArF{F뇷.YDo;[k]]~kɒ%?_|QO>~s:߿y(> 6h֬Y3g13ٳG^znFyΖREEKfa袋. BfϐtWhZs{7ǏD$;@@\pAY["өw}WCtd3o>KJ;wnx"͘1Ph@INNW_}5ER@7C nf[s5x^!^~iӦvMDug7c|>D@$:                                                                                                       .+U=Cu.lSU {*uvҟ$87.y*g(srWJx% ](%WuU{e +g]DhNHz!; ` ` ` ` pRu˭8\v@Nq&^;T\>nN+5֡=!C! inhE$Ks' qp\zC MaHvF==.eBoIxXoSס)9noYЦ{2$I #3ѡZdOU9ҟO9c4K.~_@Zl{!3@ ]Ji)SÐՅ~ք4;Ϛ$(_TAIPPҠ2:wHzt?Ðn*LULBl{t%H@~_.3t״x}VO|QeF LF,~|L NHthmiTVCC)a-i(!h=$K1#!kkt8]2«ե#cuӿJfu:KOOW?5f $.D%-uW>SIMA\t1#hZs{7Ǐlvrߟv$''뫯"LRPR}ǡ7<L$$$+;n`ISJ#y*9,nnbʶڹ{ ;aM3 ECv=@n{#4DJe %)s僄HhBLVe|2$IvlBrzϿA%W2{}^V1e[g <:I:^55 MIF3 8hf^7[:#!47K 鬦&~#7я$Wn4n~JIo^jfnR3q {w۶q!i[JOA\@SnChvN=6Hq%2|W狲S'$9({z)X[I| }Zln6) Ɋ'YuoFC FSXcƘh> }N㱚y%>kHO>ի ~ү@JqBmK~{%HmIb6^Ϟ=7/\ UIHZMǦi޼{ӟ%pnIT$m M6f}IϟqxxUUt ͺ|řV uhtȅ@?U|.V)]$u6@DZ&{^N]e W~h!{؛5: \e2mV멫ϟP<vjlUwHulLth/musî1?:p]EHcʫ6H-L ڬ8q I?U.l26CflԔT)w޶T mP\ptNi7mNIMe K|)"Sު^>[o/cu}.M9 U!cRbV^ۺg :~ЯDwB~ϱH i~hZ*nJc5I%i}{Klk6Ph%_^UXSCUH7zu.qn9g.`3c포8P s7dh,8ƾ?Z}k=BI^gg+6B/Ml:jNjj[og!cU`E폷7L"9qR1($uWs(_gK XM=-$檌m暝dh+h]aov]lE@]-sJdP$\R+rɻ} ][n?uNI}>Uwm:nS}Ѱ:$@ sCc+clL* NCB8J(0J`Mnw %cIENDB`lxi-tools-2.7/images/lxi-gui-preferences.png000066400000000000000000001127631447016333500211640ustar00rootroot00000000000000PNG  IHDR gAMA a cHRMz&u0`:pQ<bKGDtIME4I4ǩIDATxy\TUg`D@qL%AE^MfhiHVoOM KMߴ0p%M]DAey|f9 Ùsl$-_iADDDDC(az,oBVs*ŕ+j{Cki9b֗e?""""©TDikYC*C-ev,ᵬDiڗݜz9MHiY掀> [ړrx.\eskZҶT"""Co뢖K*S\YuonXܑTg%"""XZkeyVȨ9RFM͝&`T""""挆4Zksɢ./)Laa@[2o@DDD$.%H B1 }aAZ"""">sGHK\KZFs.EU\X-*;2V""""q).XZj7o,,0%ZEXd,""""*^'U(䵾ZAZX Mٜ&"""ST4<^3)BCƖH @nHO[N """GAż..OQLȋh\qEV""""3d4C -~C\َ<%El7*ll/*J Y/AᡖH\ LjaSmRl7 %_=sV TkqhzS=r3[ސT԰|u߷R7՜*˳ͳuR}+O""""2Oio o@ -HlVE=#BGXkQY roځ!UѺuZj}ƦT** <ξɓ.^x@rëAV٢B+Pp*P0He;՜SuTe0Ukݺu7gg GVVj!%""""kJ尵B@VV/^< 6Fb JP|XaX˻^o! v:tiӧOa'"""2=RRR~;yG yêuКwka'W (&BeqZ-jjZdXԩ{{ʲv?Q ;;jݽݻww#7O-??UC*0ZS EUUªNUm ;;u񈏏?К>jVV+` yϻSQE]K0m֭_rss fX%"""^z=Z-JFᣨOQTЛsv~K]x^ @ @ӧOjݧDDDDdaZO>(<ϛEݜHE] [.lz UV]Je`EDDDT}edd@T6hժUWN {}ŒevUQIQS utt,8::`/} ̐)I*t"0dDDDDTakk}uFÚw]y/u%ŹDDDD՟VM-^*N^*q%'kSRw""""LBrHZ999*՜A4ZuZͺ@Z܈k9Y`Q%dR,tT*-lmmaooLdddX2E]?cYY%|eE`ȲJ%juQ*HKKCfffy޾L?3W_غFBKMyoJDDDTJVRհ+O ˄ŝtb yvUeZ.XDDDDTJ%]}S ` Y r)Q'5ZL&aɋVQRQZ~=ڷo ~ 8}4V\r[o7ހ-bڵ>d""k"LKK+o5͓eVU"hsjժh۶-zUl"GT+Vi4DDD7>}?#233ѿ\~j׮3fSNEtt4,Y۷o >/rT*ELL lB@t:lڴ 6l{g@8;;ҥK/qb}"(( 6Djj*_ӧ&^lll~-42dqeA*дiSPxWV1uToPh޼9~GѣGS2:t(nݺ8tӧOٳgqi,^z*9ooo<~ĺ[j?x~GY DՏ\^|={6,Y&M`ѢEhڴ)J;"KJX.jQH$h֬z Ai4 68oool۶ _|`ƍڵ+J%~7t͛7͛q1\de>ĠA O t:8uƏ.ƍC"իXc" bjQ0sLchD̚5 媻ʓbn+ׂ oKRSSMjڴ)7oaRZ./Sz ''Fϝ;ptt&a՜?x"00/_ƚ5kpkdDdZYYY* +UiFjj*n߾իŖ _ŏ?h -OY{o#ȥ[ 0ݻwGnгgO|=z4Ο?_aU>A uvv… ѨQ# 6ĢEbV"-Zw]h۷oy!''B1gju_6l`9u ={`Ϟ=HHH[o͛3U3ZEn;w1/^ /ĉ[ XF9w=.] <<Gƍ,Ybg?ÇhӦ qnquw}<FC\xYXNNNyv>chjHH 4k֬ĺpW"c̙qơYf%*>wž}P~}백cukZW^#O>)DT䝛Z^zaҤI&_'''cĉ^՜+DpYCpb%| ٳg׆gǞ={F罴 U Zm]eff֬ػw?T:<³B#kYgxm[Uݨ*WfN`""""t -IZZUK*XY#DDDD@ff&>}Zz>}Z5(HkZZVDDDDHff&rrr`gggXȨiJDDDTfdd@PrxAj,UV"""jJӉ+V""""5V""""5V""""5V""""5V""""5V""""5V""""5V""""5V""""5V"""" 5}|DDDDT + W\Abbb5ͭ""""5V""""5V""""5V""""5V""""5V""""5V""""5V""""5V""""5V""""5V""""5V""""5V""""5V""""5V""""5V""""5V""""5V""""5V""""5V""""5V""""5V""""5V""""5V""""5V""""5V*V ^߃.P۷/agg۷o~CXXfؽ{7A@ǎhUd2ӡ+=a`-]]vӧOqd2xyyyndff"66ZYYY/,, :t@ΝT!ADDDkL0]vŞ={0{lؿ?:~qaĉ˗?@PGtn:3gSW= .`HIIԩSѩS'"11 VZA?C K/T{wŵtUJ͚5-N>mV[r%~m$''ĉ͛i,3tPkׯ_>#O +VR,>%5j|}} WWWe~+VoLRJHHѾZj8pl;vIYZ :uڧ$999t&u:99y\ yu| 8M6j׮]5m3U} t5zo7.J{B"/dyYQ'o;JR{:88҂?6ڵCXX֭3gO>e߲]IDDDDUk)=y[n\.Dzea]&!..гgOc3|5~Jkam֭4s[y&_.Z ɰw^6m`̙}6`̘1U:vX`˗/SN?>ӧ_m9eĎ#ԩSѣzYfܹsXd yrG r {W厭vuV[< 1]AD֮];\}}eJ%/&7ox{{>/P?4ǜ25َ;ck7Jjx .]+W`…ؿ?njFDTm⧟~¡CoZFT"==O>-`׮]8t`ҥ 'n߾mv#"pa\t q݊+0drΝb4iqD"#uVٳK.;@*bرضmgmܹmҖ ,\`kkiӦ!""vBhhmѧO\QQQ3kڴi߿? hۅ[xx8z-X~=0tPlٲQQQXx1Զv s=8\zڰaOPdJbǍ y6sU "qExzzMVcѢEѯ_?̚5ܐٻwo|'9r$كǏ&L@b̘1V\.Ǟ={ХKH1֭  Faĉ&m Ʈ]0~x={da<,,ży0h ܻw6l;}A&]Rۊ;9>W"J%^~eؼy3˸J &ݿ...f!*8%@$L~\G"-- iiim666=z4{=\r@!{аa0n8TO?ҥ !ٳpqqAӦMqԪU ѣXv->s|_f "##};wիW7nD^qF$%%"##1`(m%+s,qQH$'' o,X)Sݻptt'O*S̝+ڷoJoC*VSܹS7n &&[l#Goĉ @Tj^` P .q8x 8={8r233ѼysHR,^ظ\.R4y, ؼu <==m9]J:>W" l@JJ ϟ+WGذa\ǎÃJU*J@ܾ}W\رc5FV{,, 3gDݺu#||ǻm6`طoΝk~,m%_>[lÇ V[.JD˸d-[?;v,S\x!!!&Ӡ,]C Aڵq |7&eN@@5;*ɳΰ,ɳlxȞ=˟6<;G'&&Z,F777k7D`ԩdXlYOӦM5+QSNk79;;#99ƷpJLLT*5dUhtyg<}ay 9%č A["::7n,n8DDD5ʕ+r _ůj$""111YX:SϹ0YXVV@sa`%""0FѷjNBX5+QHKKchZ-Ҭ݌a%"":?JB\r:V,Z!""@Z$k7Am)DDDD$j DDDD$j DDDD$j DDDD$j DDDD$j DDDD$j DDDD$j DDDD$j DDDD$jU)yzzZ DDDT%&&Z U k)ݾ}M """Q8%DDDDDDDDDw"""@* ry'5 ZYYYh4V=zCDD$2 j՚L.C.CP -- :M18%0V_rjͨQX,LR1Vsr*ͨ1X,LPX T 9WV""" jϹ01111JdkkÇO>WqU^/_6)e˖pttD||<كpرc1a GTTŒ;v,|||0eʔmQ(6[nN<իW[TX:u*Ape[}b֬YH$x zm.!*}xѤIHR?֭CBBI9___ >ӧ_%GX+Qpp0uya4iO<~ؤܤI0g=z>Ǝ~>4)w)}ҥKѳgO|Gf3Yw\pTvuV[< 1]ADU&Lc̙3gX|~~I]*Sر;vv3 a$2 })Sp@rr2n޼iR СCd\ƍujZ_`Ŋ/\6Fob`„ cXb܌ ]p!ҥKOOOܾ}ۢeVT T OObˍ76m2 2z[nڴi߿? h+V`Ȑ!rx뭷`СCeDEEaprr2ckkiӦ!""vBhhɭR)Ǝm۶a߾}Xt)ݍw s=8:wp>>ׯ.\XDT 8:u*t:q}ZZZ-o\j2f2I `CA mq=x䚢7oƀкu5\%a՜yF]Ν;H$h׮qL&q@ff&4iR.ʩS0g?ݺuk/UzG_#&&;w6]67onRe JRg{hܸ1ѻwo 6 rwf=^^^_>w^zY= 󃋋Y呝M6aT*; 44pvvFpp0<Ϝ98p`;?\\WWW(JoƢsz1n8̝;>RRLDDzݻ~>}:;X QU)D&֭[5j<<< qM,X{5)o߾xW1rHd2ܾ};wX{ml߾ܹs-RN[3gDݺu#|;y-ZSLҥK!p1L6͸_>[lÇ V[KV{ð<ˆל@DDDDJՊ }AzWbո|W&Q z=޾n:}`ʕܩӦMCDDvڅPŕ=<<AAAX~=87m۶;wFxx8<۷cҤI&m~W*bرضmgr<ӦMC1dDGG6+V!CL[o!<<兡Cb˖-ŋdvnؽ{7|||=8`q,QgCDⓑ///rݺuacc8:????~ܸ7oޱT`ǎ5kf̘a* | F={LƮ]0~x={!((5ĉ:uꄅ ^1|@VcѢEѯ_?̚5 4hŋ&L@b̘1V\.aj<,,̤ޒyaРAw6lwww B J'ŵ$iwyÜφg˖-h׮ϟ]⣏>ڵkRDBB~߇EU<-\'ODPPsaÆ Ưmll0zh{r ܑ֬YHrZЯ_?=)))k?Ǘ_~Yv;wsÆ xаaCH$r=ziiiHKK+p\tR}ݻaÆaܸqƑO?ҥ |fBÆ aooƦM0ydB*fm/a+J%ڷoFMKKPx{{HLL4LHH\\\ =ΒEI}bNϜ98p`ے YÇ3f瞃+{6@^н{wԯ_ӧODZcL.h2DUTL[naԨQ\.͛7`ݻXnΜ9Ʒ~ \X{W0h4̜9uţGUjt'O=nݺٳgy-Z)S`ҥd8vMfܾm6`طoΝkI˪>)_5>#lٲ>Ddd$Zmے Y BV#>>6l0?KbȐ!]6N8oƤK! $y^< ˒<ˆٳkótbbbA pssvS:u*d2-[VӴiSoJTԩc&T8ggg$''6RZkWnnn @@YxZygSHX@ <X~8p qFP sX`ʕXre믿_aYGXHXHXHX,,u\yX,,++MJϹ0YF[5j %Y+QHKKchZ-Ҭ݌a%"":?JB\r:V,Z!""@Z$k7Am)DDDD$j DDDD$j DDDD$j DDDD$j DDDD$j DDDD$j DDDD$j DDDD$j DDDD$jU)yzzZ DDDT%&&Z U k)ݾ}M """Q8%DDDDDDDDDDDDDMnEP@RAPRiŎ deeA ++]@``%"""RTUlmmMBK$T*BB@Z'O@XKj4V"""gggЦM4k Ճ ==G\\Ν;  HOOGrrb`%"""QJS z=z聀B:88EhѢ^y>|7ntpupp >|AU5+!^Cz7 ͛7/BWhkBBUꜜ`kk WWW=Taՠ^z=z4\]]닜Z JRzqjY888^3ՊPTV믚͝;3f(Ǐc˗SN=vۺu͛7mmm1flݺ fǏ`ݺu0a,@VC_.j~/\!aՠVZE5RNBHHR)4h.]`ɒ%vZYYY0zb'E7oܹZj^Ǐ#G ..]EDDdkk [[[yUY௿Ы( ^0RZ'OҥKr .\hԯ_C ?Xh}2 })Sp@rr2n޼Y6[T*z=ڴic۴icǎYƍ77BJJ4d2&M~ {Ň~h}Ŋ2dY}&H0blݺ{ҥKnlرcm6۷dܹs}pB>p+WDTT0g|&u1_~E~v[[[z4ou7oxUEEUdj5-ZìYpxxx ((AAAhԨ&NXd}7o {aÆ pwwᅬ 4hРxbˈ_~999رcf͚3f˫zЩS'̜9GFfff,(({'|#GbϞ=Ʃ&L@`` BCC1fUVA.cϞ=ҥmu놽{Yc׮]?~<Ξ=}3 ځDD5^ zq+tMEv*2nnn8z(/ȝݯ_?])))HHHڵkXd};wիW7B"`ƍ۷mۚն"O [f ytҥ .Ĝ9s/Ǻu늜dkkc,lll0zh̟?W\Abb"vލL( 6 G\\޽O?ҥ /rIe...hڴ)9bgfDFFڵkıc ˍ_}9::u8tPlzZm uVTh;@sXEƍ-[po8qR/6P*f 7`gggu;w ݖ%K $$111 {b޽hӦ  %K`_L6hRW\)w5hJк Wzq\p7qٳ#G͛Y۔C! gΜA.]pIuDDQEVdTyX+QZZZ#jx)Aɓ~a…AHHD1cƔJ?r֭ׯz-?rΝùsЧO8՜gŮP( HL!''4ك`Z \1yd\ݺuþ}JUiiieޢp,]v >>>5Y߮];Aם:u sѭ[7">>]v~(ܒ%K0h 4mڴ:|fBÆ aooT*?@hh(`$&&c̙6|9998tOgr:ho]f+NS*Qff&ƍSbP*ٳ>j5wɓ'nٳA),, 3gDݺu#||@ܾ}W\رcq]߲e ^yd2n¨Q\7ob3[d f̘KB"22/̙`|刍Ell,4 -Z)S`ҥd8vMfRݻo",,d}y>}/nύ*̄N>]҉u +h4zF@5;*ɳΰ,ɳlxȞ=˟6<;G'&&Z,FPFJAW^y#DTcSd2^yt"u:tvL&3`𚕕2h<_pssCtt?T:<³B>ð<ˆל@d /bbbVF3ȴ4HRܹ"N߿;wB*V'O*j:V"+ٳ jLddd@"`֭c>-- [n5}XJzz:T2VJooo,0Ǐ#''  +H誥GXlnqX*ݻwѩS'$%%Y)DD V|W8xXHTND^_hͻAb`%"""Q{2VqaAc`%"""Qc %^DDDDDDDDDDf-%OOOk7Dk7Ja`-۷o[ DDDD5 11111111NWDDD"RP( i1jʂFvSj@DD$2 jAUr9r9 ҠݤSDajPnFJDD$*a PTnFJDD$ MRgVyXDU?JDDDDJDDDDJDDDDJDDDDJDDDD۬F˖-xٳnE['Oի]B^Gvvv/cEڼy3;ݻڇNDe [nom̙׿O>2 ~); ++ Я_?L8>#Eswݻwxpi,Y}&HyfH$ܹs[.X: {nݺqPT>?zIIIp{$$$Xc Z&McXz5A77}Y`h4,[BŽ(GA@@LT*E3g@ȑ#ڵ+|MP5jrBW՘8q"Kj‘#Gp]$''{zz"660/_ 2Q~)|||hpMHR4i 64?&&999hٲ%^z%>>4h$7nXiGۈ4Qi8qYYYhҤ ԩcw瞃Z޽{jWF1h ٳo&Z7oqfo3xgϞŎ;#FMy7h|Wx)nkkkRp}(J,Z͚5C`` vi폆*k%7n6mdV #J}v8s /^ j2~]ru,\۷Qn]-Z@\\~"ߵk㑙 ^ؒ7ē'Ol2RAY~طo5kGÇՆ7DQ-Z%0a1c@Z7o {aÆ pwwᅬ 4h'N4,SNXp!^{5?χMeлwo|'9r$كǏ#''wŬY0l0DFFO>AF˗/GDDn ߊjZƢE ̄_~5k8Pq+VosaŊPصkƏgϖؾc*O"> ;ӧLڵ /^D˖-!/_AKGrrq.lI6l\t_뻺qA^6m͛KaUX+ZFZEQ(6lϟ8ܽ{~)ѥKc;wիHNNƍ!HqFۈD۶mM.>%ٹs'\lذ... Fʕ+HLLݻ1o۶ qqq _[auss\.ѣG8ia~'={>cӸ}͚5ĵkאivJsLiYޏôm5Bz_zǏΝ;֮ vBsqիxH$4jݺu^/J 6mbX9JB˰իupB s`J:;;"ߧ,h4PT5hJW\)t_''' 2_|VZ,7n@LL lقsgϞq,򴯤}ӲU=NR6mڠcǎL8;;7߄^ FUajӦ G/dݺu7|Ş[Th5wzܼy8( 2 d}NNNT%T*aaa 1 Z(o ɓ'Gvv6.\ŋͯ*kJڧ>!>}@'˗/Ç1p@hѢBTzmzx{{~%?qߏ7bʔ)i&|w& Uk%ڼy3 PWw܁D"Avd2+NhҤEwd2ZjU`[V舕+WE]*nԩS3gƏnݺEP_^=ƒ)OsDD0- ^^^8vX;v?.\{b͚5J6mZkoӦ Cy)v \Pԭ[dL&3Y^f K㏥ζm۰yfリJ{n߿k֬ѣ{ի -- BCC ggg#11 v 0pww\Wrr2>YfaÆG@@T*=zprrB޽ ՟???:堼VV-P*h߾=4 RSS -?n8 ƍ=ߜ?ƒ)OyTԯ_(,U-8y$j׮ Db<@Raĉ_A&MZo 0uTvoooL:=z(qpM4ok֬e0gxw,g6m¦M*!•?F߾}ꫯbȑd}u-Z)S`ҥd8vMVmGa˖-x!"## ^sApp0[r"66nʕ+1~xL87?nm۷c߾};wnojݻwɓaoo[naEuƔ)SPN;w&L@NNNQR ;ƒ)O5Mnڴ !!!h֬> Qe;|0tRt#Gv2&ho0l0=zݻq^zEn3\)4'\cڴix7СC4jZw1\j& E@$:ò$ϲ!{,hA ܬpψvSS`!!! ȑ#٫JzQ!J՝. 6ϳ쵐0,#ϲ5GXr_۷o׈J,fnUCg%Ҙ1c""#DDDD$j DDDD$j DDD"P\u3< DDD"e&P)3< DDD"h8bWhZh4k7``%""4*@"--ͨQxY+"""tx1T* r3-&ZYYYY@DD$2(N """"Qc`%""""Qc`%""""Qc`%""""Qc`%""""Qc`%""""Qc`%""""Qc`%""""Qc`%""""Q㝮JM ""*.11MRXKnQ)DDDD$j DDDD$j DDDD$j DDDD$j DDDD$j DDDD$j DDDD$j DDDD$j DDDD$jQRTP(˫?HNNQmjʂFqD"""dP.drr iiitnR)DDDaPnFJDDda*aPTnFJDDda MJϹ0YGWk~ΕDDDDDUcb„ 唔={V­[LJ$DDDvݻ7222x L</2Zq}`` >C̞=N2/""˖-CTTqW_}xyygϞEO?Ů]~~~>QQQ ) zdggW{D&a޽;lllc&ڷo_M4T*n:$$$Lhɓq kwX+٩SDwwwL4 ˗/Ǜoi˪m۶FRRt邽{=z!!!xpΝ;CVk׮&qpqqm\'JѶm[|駟`̙~fff_O4 իzjoooHBS.u ;>J`h4,[ޓ$C AΝ1w\rL6 |̙prr„ e\|kƄ SL^7 (J_~v۷B%Jj4>CzвeKrz¡C=zl>nܸ:ѹsg;vę3gS㺖-[B"Dzz:Ӎ#t( #G_E\\nܸ;w?Ftt4 W_Ŏ;+W`ٲeر#6l ۷ & ** ǥK|r4innnfrkzz:>}j0Zʲ rrrd2wn ;wR4/::$֫Wvvvذa4iwww6???=zdtfuܸqشiJ}z!CoETT֯_֭[KR;۶mþ}tR G>}rJDEEӦMC1dDGG߮ϒ$ NNNzq]ll,>|___2%%@]QT&ߒUU V3f̙3rq/R)Μ9HGA6mAcǎ8~8pcy\_|&o߾<גhϟ/ӱ޽[~aŊx7q9Xj0a"44cƌ XjFk.?gϞ[aaay$++ uߓiӦ RRRX2J/2~gl޼en *5ad~~~8~qyϞ=:uI^zѣA=LN:{, //9 7_~A6mj2^"]vذaVըUVG"A Add$RSS -O?ٳ˗k׮ٳ'v؁aÆaܸq{XDDt邃֬YJad111@@@> Lfr-^z%PTPTA.]`kkk,jqqB"_4Tu;v,0ڴiSf;==0!;v k֬իWxbgϞ~} .quYYY Ϻupy|q%\~'"99WT8!%%W\qFGX+N3p|hҤq ۱cG>|ظ|Qhٲ%#˗m}I=eqMt (*ZL 2 d ''!Obɒ%&n`ԩSmNApVqa2x#Vty?&' vBǎMgϞ-_-[G& z=+y8y~ڵ+Uؼy3 `rBTQ W 07:88,j ׯ_ǝ;wS d2Sw+kNի>?.t_sYʋѣG4n* ]vΝ; ۷o`ccc\#74 @})ppwf=^^^_>w^zƍ899aܸqGTT 44pvvFpp0qĉbLHH\\\R,E׮]ѬY3!!!زeI|1n8̝;>RR472SN/\]] &^z&7! 8deǏիW1vX_HOO71}tI=z(4i@:Uٕjj^1W_}#GL&۷ ٥cʔ)SΝ; &/h"L2K.L&ñc0mڴܶm|||}v۷sεgFDT͚5;;;;ܸq֭39VRaH$:t .4 1vXӧx"BBB% E@$:ò$ϲ!{,]7A _f̘aFDDBDduԱv*3k|rmrHLLT*-pȪ Rh< ^ y<2,^sJ@M~ """20Ua%""""Q+Yݘ1c"""111YVvs< DDDe&P%\yX,Lpjn}N1VSZiiinFZ 6jDDT1t:?~ JBVuZYYYY\D$ Z-lmm"""4M8))MEBB"XU K);;M ""*YXKA"@"""*, ?X:nUAtZ f2PIR<}!""*ӧƓXZ:O}pY=z5EDDDTȭ݀ؼy3RRRн{wW\d2\|+WD&MеkW|_|Q^=L::u+/`ժUxYf]? zN֭(JL>=z􀋋 .\ŋŶ,8ZF*`ի@ɓ'iӦ믿鉥Kϯ2 ׯ:… Zv JSb&?b5 oիWoԨQEll,\]]:VX~8x ֭LDDDTa-TW^ywիW/^D֭ѸqcܼyXƍ8p AСC#GDLLLкukO۷oG`` T*>| 7n4Āp-:sKLLD>}q:/N<#FGs{ŶYX#""* ^|E!11| @(ڵke333nϞ=&MyaÆaذa&VhХK1[ v&e?~lV_NNt:;EUV?$0DDDDZ}gϞ&zmX󲷷deeɓ'm۶aÆ &咒Ю];… 9s&\`a+b\Dˈرcq5O2֭ZƤIТE tݻwcƍ8p Ξ=_ rrr]vCqoqm&"""* E@nYgXY6)έYcXHlΪQܠ Iݝ0c%8P ]+I7 _@rr1f힪qxBņUM; ?SMȠwCFb`%"""ӷPaEUn[Zmj;sC ZjV"""/VМܰt|qjYqA :={n>sX+->}^zHOOիWzj\|nE) zdggo 0x`lǞ={;v,&L񈊊BXX4Lb[[[>|:޽kQ o>*}vq~A{=4-o@h6SY5k% F-0o<ܹsj /Ǐ[ir˖-+WL4 իzjoo;uBBB ѺukrjY1S{Um;`lylW K-DZ[5k%dӧL3gqMk7 4CERRq7 ԩj_|+V/DrrP掮:~y5 2V J"J!Ji eEy1p@4mwŋHRo߾]6Μ9ŋ`kk?@nğŋlllw^;@ܹ3}]4iIIIؿ?_O8=z􀭭-_bGTT {ڴi߿?` CXXXfܸqشiIX5zX%  Ν3qqoC[nhܸ1_ }8p ֭'Ob޼yHII)>666xWWW$$$`عs< ?.z ;;;=z""riU掮Bйk[^?']UرfŒ3Uy xbk8<ϟ P3 `ժU刊{666ڵmѣGªZƢE ̄_~5k8`!((5ĉMԩ.\X˗/GDDn ZiѢΟ?_wqqgwO0rHٳ857ży0h ܻw6l;}A4ݻ5k H|'hԨY{ԩfΜѣG#33""R7p^W]ϫ-z w,U8JpB̙3/"{[EDDҥKHII ₆ BP`ذa?>p]|pttD.]p1rjת/6mGGG4l SN777r=ziiiŋjB~vZ !!k׮E``I;wĕ+W }VQV-㨤$ <<<H[Gq$&&b,իW7B"`ƍ۷mm6m||>>ׯ.\O^3fL\Ѡyf#jM.Z.W,_GR!,, '|Wfekkk7,@DdqO*fz$,>ʚzޢqJ=xkwH$kθN&qqq#Ge˖ɓ'GqBCS0g?ݺu+hL–Eye͛7c.* p=d2㴊ehժrJ\~Ν;`r)gThW?P:yZIT*>3t7;zm=[o@Ddq.U\ (_iD>>ؾ};ۇs疩o>c*F L۷o\ҩ̙`|刍Ell,4Y_nݺ+Wb8q"o|]s-Y3fҥKjiBI? DD$I8 }7,X!H Hǩj]S! y;]U E@$:ò$ϲ!{,hA ܬ""jE?ە>w޿N A!'S^[u,RIX.i7!{+ҔVbb| Rh< ^ y<2,^sJYگ-wM"lg7 #VXȺb[{,XH >1.2JJ @r{Fa`%"""Y <`rG>sGXHmk.i,4Az!Y], DDD$ ,Zv#1!".1C`f״C YLH\W """qN迡o;hTJrgRH` wNDUƛ $p9>Wcx$?A"W@z(7rtr1Hάr\=@?RHʐw[&N݂ؒnH2Z+OB $ 1SKv\Zꆥih@D Z Ě8H$zn@eX*V"""\-w5zBeҼA5z| DDDT#$7DcP>V"""Q Y+H UJDDDDJDDDDJDDDDJDDDDJDDDDJDDDDJDDDDJDDDDJDDDDJDDDD[@DDDU\bbP0۷"""SHXHXHXHXHXHXHXHXHXHXHXHXHnQZB_ P7lkYr vxt@UkĨ7VKk^HάvX DDD$j}gUШjnP^NձВud\.͕?S/ 9NvO8<銈DbêlIDATudEŒީud;{C!T#1Nذ"ǪQv-u-X5M]乡w]5+YW+hjnX :|>8O,8 W=7Y ZƎǏ믿}vL<*uKRcϞ=MV1(W=߿`ٳET(52:7X"wΪ eYpBQ5OdNBHHr9ZnP?.WNj/ÇC}`ʕܯMڵ Ʃgѷo_DGGcƍ%S{%0i$oػw/>C6L>۷oǡCO?O>&زe ~$ F[bϞ=Xt)N;v,mۆ}l+LIKjiп 2&}~z8p7nD۶mz-X~=0tPlٲQQQXx1̮piU掮Bйk٫0Z ݻuصkƏgBBBၠ QF8q"`ؼy3v9}{{=t 3gѣiܖwb֬Y6l"##'QFfL&üy޽{O>ȑ#g<~0a"44cƌ XjgS._غu+M۠A,^Ο?àAp=lذx cNDDU+zj~^ld1ZD"BCCT5k 22׮]Cff&jժ~aڵHIIABB֮]"7w-#66Ǘ_~iRf۶m3xnڬH$=8=Ǖ+WeSݙ:I&Dы n!xO'(",ϋKݡI<˹fI$%3WfdV=VTUWL$6U]5=g}l6v=cz400g_Vooy}m}Duq]pAnݺؿO?T:v-cvޭa j޽m=вڮn|#G8  ̚T3V,ƍ_K&&&y\.WneYz+:::B?'1eYN<fժUzuwhʕ?6lؠGyD|>;::?ߝ-M7ݤ>kddDwwiIjsiuuuIs_uZqlKYb $\_cdY,˒mG٩]v/Ю]4::7|3vGэ7ިM6ߞʷ+JSu9P(ΤIUܨ>%*IRë%qxDbHsg HryxxX!IҝwÆ Վ;+$dd265r?T* 1R֯_6F6H#~K'4ͥEH>.#F`]٣zJw},ҵ^7L&}饗^߮UVi͕ѣ>UV顇-ܒg;tvܩ[{_^кuݭ_t߯_|QׯիeÒ/뮓1&V8ƴqFź+fmpU?$#M\xg!Į]4;;{N\s&''ĉ =7г>۷X,j޽ Μ9;v'ГO>o2>7w}Wvmۦ͛7WU_ymٲE;wT:֩St)j۶mz駵}vR):tHs꫋kF f순[Jrdszi9Iɜvi+YUW7+5Lϭ{xm[mkڵ>.+ν]9qRNv!/5 <+J}Oʳ$5>>^OrvZִBcoUi=1/{\c2d}sS]]*Vm sšnxV8w;iG505c;5]%%~- 2ѬehrΖ?2AtVju LLtb8'O LI&.k+Y~JuuiX@K14zX_>VdK+ 90=C0cIs7lY:ğMD`gQiխrԷAj]ǸVV##Xrrhusu.fdJ5'ߗ*au]藹пn$q*K,+mB7zcX81DG`W7U;45!۶/ǨpjV m{\aH^ cT,}`+To"&} `#K$G`M\.#\\ kB֘?Rl6P6UTM]IXcr,LO,C333 XP*455Td GdY٬}J`V6o+!ЀL&CDR&a(Op+BAhf533RTV XmkjjJ333jooW[[4~ mX,*+˩T*CXmk!6ȶme2e2fh"oPuVG`]ohu{H G`] ސ'W&7 A (@cq;Z- F`@KXLf֤ XTT r@XhiXYyr7-Z!۝Nҿ^m?N/Nevg a/۳t_TGښ`)T͆BېlK*NLLYGG&&&~/ XoTT`uj\mfX$]]]mAU  ͣV}Q%[+7::AOO pIrVŵj_j%I&`i% JVqn [f4_إZUTF>kкcѯ(#өgKjEԄVZÎ T^WKjU_V+nuL>)-@^T$5h_=6ؠ6hjX@wR}ThM?+(Jl=C$id*9T8A*U Z]-Y;5nTW>jjж$RUh}QZX'f?5'5ZƲzZXohզVx'N ڗ4 R@S,$jX$!XRK򍬈 QR '[;t1.3~`55}zT@IBc#u,'Iu! mA5%tEXtCreation Time2022-01-29T11:40:49 CETl%tEXtdate:create2022-01-31T04:06:48+00:00r޿s%tEXtdate:modify2022-01-31T04:06:48+00:00tEXtSoftwaregnome-screenshot>IENDB`lxi-tools-2.7/images/lxi-gui-scpi.png000066400000000000000000002576501447016333500176260ustar00rootroot00000000000000PNG  IHDR4+gAMA a cHRMz&u0`:pQ<bKGDtIME  0[#BIDATxyxT%˄ ! YAeT ZXb_V[EڟV TQ+@ a3l@VȞyf6f;s939{M΍rֵ۷Gsq!B!Qގ¹%NqsM`B!FmvG۵I #JB!箳dQ=ugsI]4J)B!8x.&v銪t#nB!Bl"Pk-&mxB!Fm纽Zw44(ζ辴6 !B!Tnwm:踫ɣmiB!B W{eNoxk9t$SpUnv}B!B#2vtۑ񕭒ȶ;M;/V:ئ䱣+B!?w v(Z;xrNMMmB!B? :H:DLYz䱽іKiB!Bu\[&׶LJ%yl+Դp:B!B[9Nj;;$ K:KJӜuξ-B!?G%%V^L"@N%%Д4*M*B!mҺPvGId[i1;v(Qdz c B!Q9Ss^ܫe"ْyZVyަfSմ|{ɣN2%B!B0ZO^kƶ]Y 5m<<6'O&;)B!uҔCLn5l~畳qkl<;hA: CuwA!=jZ,*ɔV[[ѣGwFIRHh=Z'Z![td9&9+VG `4h$__G"f3X,T\p!DWD B!zEQjt:z=&/GnRV׶S4'z~i㱖kz9ql޷9r_hX|hlljmkB !DwD uuuB!zJcc#& N{SvҔ0BC6ouغלuc{cN"J!))5//iuuu>BHٳH)BX,<ɓ_qyFVCM [n-#G״ZiqgR!QUٌ`~ԩ4%g$LG˵" J GڸVՖɤ>!!aϵ2Q!B!smBB$W8;_;{ 6ioHA{;`ZNhb㒨8w2q}{4liw"B!, F??GiJS<;k;Z.|Ö?mYcVK-KHHQ]]jFC8LJ>(tD I!D/xb~qY&x۷ww?s?CBbFooSؼWۻLӲ59I6'n}ބ9|k܈;]ve 6L0?CyWyW;`0ȤM]ӦM#77mݙ>}:w?Ow.qssl;c6ΎlXfvhZV/okk_ܽ%@sڛՖj4M[b1?w㸢 s5þhoks<:#߿?Ǐgmn&.EK/gӓѣG3zh.illdРAܹC}>]wuwB8M^GO7/xo6hbMɵ1imiNCꜝ@5NL,ia¥šerz|Ik:EQ9s&m_ԆK/;ww!==777ƎŋFUUz)INj v777򢡡.M$&]<6-|L`?ͭxgȷ;!Dg[|9[nLֲqFXbEwhxpssc͚5|Oyxxk<<|8w/j@._\H+xxx&///VKZ$vuӵ\îO^ö# '( LvcH psYx1\s AAA/W_}U֥N0o<=ʩSz; ,5/mXQ$.&Yh^qUU[F6vpJEkijQ;7fIL^G 37— I'=2\hozMpp0 .DUU\XϨQ.=z, ѣGIIIa̘1=znѵN> j'xնL4Ft)z`0P]]-1uqL?q6kK+Z %y o%x䥡MNcvw[ epDOuMw]]co:|~ڴi4&EQxgٲe 6m{nƌL2z*mq<[Gx8ZwI V-njzh,Zop^h.[G o\b3:n/+I;ՈVaZ;q:td#^)lU}{/`-*o@Pp jyuw-UwiƌCVVl'\vͷELL UUUEjw'|_|Q#F0{VʞZ:'xUV_zj9ƍ㮻b}Y&Of᜜.]*P$Ewy'wyS#_ }4M,w}ӖPvG}c;+o Sf}-Nb}X6ً7¶Zfղ2/K^*F~?7qxkcUa*?[ÎdU/VfYή&ܴ }hoRTu4N3O&6>ݹv$h[|7r(._~YZz]vq2o< "##1dee_駟]lƍL0+/lٲ7vwآ c rswo믿FQ.] K/ԪKo{}5\pO8#<~'w~rcdO@gEQPTr14[T-,*#x)Zy뇦*4ZUuX!Uv:,BqN>++ݡ,L&xCb]H$2lq7d»iJOy\YeZ,-שX*+p6|/W84بڽN!BjvY߹1܅HWj2j|D F(i:}4‘FV7B ŪBp f thWdkk僇L/}yi;ʓm CCC̒#B!..x%1o}"ӧ9yLdGIj2[iBSRQ#fJvy#ֳpʗgfycUk*竣FXaw LC̈́Y{y=Y=ǏV;rLLB B!\'4&F%+b (L2՘1SL/lw&֞2^]GZQU *gRa>ZʱR غi%Yev-V8tҌ}1#}^ɽ4-nYC'͜o%QU!IRkR)YZZJpp0QQQ9#GPRR !B1F//.wWt>ImWĤ*?p M;\\cr1EWl}4-n+?]4gnhtwҤIZo_{psz[o%0\䂃;BiiiwpArדʾ};ƅ:ye]^c<|njhhZbrqL>>>l߾2-?ݶ?]Zަcͷ麹oEꫯ;8Ŵz_?Sp-qFy&N;v>7n믧o߾||lܸիW`t:aaalܸ{キvi4~ߒ (.bcc~MDD> GYhh(_|wf޽lܸe˖llϹsѷo_~_r;EojR__.zOsd do)`6e67_͙3gP| &pvI~j]K7o|]ns嗳xb8ڵkՋߟoC9gzPǖ-[5j#??O>8߿4fΜvg]nj]j,tbrBk?$-B^!44T֬Y_8p ^z){aٲek>VΝ;xE6mZNڱc,Zs뭷Ftt4>,V|3|pv+BZZqqq<b "##y0`@Grr2|\r :u*SL>^˚5k9r$0`_0L; 4g}Vk{'|c=Ƒ#Gsm6~iN>ͮ]=׶_>wqUWȇ~ȠAXp!&kϲc̙CRRAAA>NAA˗/d2uR7Ւ/qqqܹ>1c3ح+w1|EVWWw^c]%Sbpz2B'OxbfϞӹ뮻#33N2)S*|'t?_aa!saΜ9# dffwRRRlcm])ϟW]uW^y%:UU|={X~=ӧO'** W\~HFFC`Ν_3fe]^_d޽x{{3g['4Msq>믿O?e,Y?Oݻש:qvdzk}l۶iӦ?MFxx8L8#GPN8\΂ hhhok;߿4|'_ֺ g]~ f 444PWWe1% JTTT3vX6oތje„ m255/SNܔ]' 4MXFo#55hZxԩm>~*& N~ǭ<ѣYvmmZ}mݲ5*..&%%3g8pSǵ9)}l>g?~\i[oeĉ> v8-|:Ҽ[ȋ..cpwwG۝V+fFI$wHl㺻޽guvw 7zhnߟ|K/'33JJJꫯ]vuwzq_#G`0 "''~²eذaūSRRX,vmIZZZ4/;|p{N\\ݗ䖒illdҥl߾k XV~_́zm׾r7Hxx8| ,^w^GG)(ɩ駟7Ⱦ}믻vjˤIf̙p)<==/ϺX,Rb:| s'P7/~ 222Xb&{osu1l0TU=_/fo4q9O<'K,kms1t{1f3-n $$o[q, j;v___~ߑ?b!;;_ 8{Au!vlq3i$ 9}\=訏>T?p=p ;|˜-7YX&0ρgu6i0B!?S2{] ?KI ;YZ#;Y6B>PBхGRRRw!YXC>H!B!zn*B!R!B!C$B!BI B!B8DH!B!YX+++9sLwOӧOwwB!YYYTL'>>OOO9r]]Yh4̚5 SN?gddĉ- &sVnСƶz)((@2sL4 Vʢ^V͛7:t(lݺUU`h4CvvyQ!B W$jL&233o(=@rr2 DFF2fvAuu5JII X,bcc7n;we0~x[dZfJuu5AAA9LnnۗÇNqq11113۷SSSzuVjev}z=ƍɓ@KUUBXXr ;FAAAAA <{R__O]]ݾ(**ۛ0qDv؁h;F'33Ã4011jJJJ\^!B!B4 \EHvv6ՑI]]@SpJJ P^^΁ qi< QVVFEEyyyGEQ󣴴R(**___≎jjj8|0f(ˑ]|||0]@v TVVR[[ @MM h"ms)Vm3rGII UUUdff*uB!3(JRVkɘNCQ[wDWh4ri.f̘ԩS̩JYYxyyغ:uʩuݴZ9s???t.ei4(**QBACC999Cg544pUZZJcc#tht=B!.1TVVEII &pAQ6&$$P[[1F;qqq;vGСCX,Mc5 SNEUUTU%--Rc4`СٳD>}\^/g ˋ|,..`222pssԩS7~_ K V+Ǐ'&&v_ܭϏݻwG !B!E@ʁ5jӦMCUUN>͉'Z;l@pp0w1 ;4u &""|TU%220KMM $&&b6ma6bt1wh˝BmPZZnSW(**bM~ e˖-Z !B] $4%h۷o EQ0;ت1!!gϞ.IlV+1wm-uZs1[KYuu5 0'O:4jl6Nnn.@Ӭ&r>}¾}UQXVv4pvws%yaffBbbbmY4 L&iyB!E=%Ʉhӓ@%:ǤEFF{nݏ^ZTU)DKѴHm^|V/xzz*366`QU|7)(( //뮻O^^<s={Ժ:-[xnb7c PB'֭#**=+Ν;k@V\IZZlذ/(||g>|,>3&Nt0j(֬YCFF]___^^^<߿Ǐk.^t:<;w.;w$''M61iҤ.WGeMaaa;cȬXX8teSXXHAA|WW:](p=Jnn.;v`Сv y~rrrxW]g,==?8}Ϙ1cXf >|#Fp-PXXo\9rS獎.\yϷ~KVVǎ?窫j]gGsT_;8#WSgދزe K.=s3q芺_|eA_|-Z9Gb5kqsss88g8vBOH IYY+W$77u4^z%F… +x7lDh4MƶmXx1ϧիW~ <5kP\\… Y`ׯ[Tkeҥ;%K0|+ygywꪫHIIaժU 0,5\m9sPWWdž *o&SLcǎB=z4wO<ƍ̙3E+g'`ƌdܹ>efN<ɭ-¦M6lm:Hxx5>7:p7x3w\=ʪU5jmG?Ufw}dgg;#WgGΫó͞=sŹ8^tU/q>ײznG &MĻh9ba…vg]wf~GaW'<|gֶzۛK/UVBAA/2tM@Iogʕl۶d?0epw{n~vEJJ k֬ hB9|pvm())?YYY 2XE7 ɼ[OSYYs#ejki$$$PSSæM\SQQcNII W_}yFŋٳglٲn{w;O=Gdɒ%I+ 7w}GNN{eٲevt:L&}߳gz=W_}56l 33۷裏rABBBXbرc|WL6͡zt:vs֦ut9o8wڵkINNf޽3ZFc N&aÆ;FéS\Ncܸqj*<֭[m jeϞ==hSe 6ۗ^ȡC9rd|lY:n:jjj\z*kڴi}yo˽˳>_ڵky>ɓ'rV\۫Wcc#oW|Vˈ#HIIAUUBBBرcmrXͮB>>>u]w}$$$xb?O?8ݻ{۶m1sVυȗ_~ig\s51f?q8xzzr뭷m]98WaÆڦΎs||<~!7nb{1<۬Y wuعc믳o>nr1sqx9777nF~mmFNN>(t:?O?vɛo_NCQnL&\s]+^ll, GyK/}ŋfY`ѢE$''STTĦMx뭷?t 8^z ooo /^СCf[y'HOOl6w^rrr/ FHTTO=O?4N_b…hZPֲMff&yyyڵˮEDӱtRkםlm7|?&''L-[w͞={l8rl?sW\Yx'M٦%G-!CG3u=6t,Z5kPVVsyuwE.DY=Ã)Se, ۶mc̙vјu:;w!r#q8{nBϹx X,-[ʕ+IMMbΠAZm( K.e̝;î>碹355^{%/n࣏>jr73k,-Zıc;v,<gΜ9_jjj(**ˏ#e)‚ HNNرc]˻OLL s?0yyy@Sejȑ#;Vbv[UU ((___m)--v?((0}Q}Q+++h436$<<~|ǯkEg֭?Ǔ/~ ,Ywm:t(999`uT}#ǴiӘ9s&_|ըÇI^&L?___g6233;ח^{7u)uֺuXd cƌpZnf͚el/#v[t9o8wqlf̘/7pO=dff:|l?KQ!!!<<>}!ls1qxzz{1l6m4"""x~|ߋ+u!;fرӇdw]wE~(**[X,ĉJJJl;ۏ?Ǒg^aN 5khZx7())IQ-[Ɯ9s7o^ 6ԐcR*šhpss_端aܸq,ZM6پwVVUUAAA^֍$00 lY111L<%Kt~dddF'f͢ک8cdz_( `6o믺*8@qq1Ŭ\W_}믿Fm۶m6^z%|M?cVWVVuuu 6K/_I&fޫEꫯCUU^{6jXJ{XO? %'N@UU[j%336GQUUŎ;߿;:o8wd}q޷oC a,]ԡOsL%Aѯ_?Y[3226mQQQnt~nq8SO=Edd$< cLqw}w'Npi]U QVO1c^^^ꪫxw[nNԎ?*fG#q8oynBػTQQAii)aaaL0]vͨ|rnFn!"" ::cXHOO':: vXXXVz=}ijb0Z}1o/FHJJupwwgذa8p󩗳e͛72;׼ooϼ<sqQYYi7ˋ`RN:e]~ u|wٻw/WfܸqGZmlѷos>^&CqW%\رcIMM}G+?@qq1KdwMCCC `p;c'NpQf̘P}]L&S:;o8wѺO>cGsTJJ SNeڴiL6ӧo>5kEEEmRGGscc#7n_ zΎa+Vu>8^+:]|SGqss㪫⥗^ӦM/ucuU̎UGq"׫HNILL B\\m#F`1cWAQ}QnVz)<<<2dC _~ʼٽ{wVjfNʂ ofԩ[Jmm-vmL2HnfΜ͛[t^dzpBbbbX|9~~~|.3ey{{s'\.yw kr 7pw%\id?׿m]we; 2@SH>ܰZ|ִt[~;2|nFonKz7nHaa!ǘ1cׯW\qzRU̙޽{mĉm 8q &&vXl9%W]uwu> xyyi_=)))\-[}- < &L'd :-7p^=<$<7x#~){챭էOx7?a+soͱcx޽{`˖-XVl¸ql566rT*++ꫯ~oƏ`޳{_{j7-_"h}vϟϲeQd48zO{uolle˖F!33xO?Զ]gGs+utn9|nn.=INNfΝ'O&>>ŋ['W{ُ#\Uf-tsww̙3)..&++n߻wFQNʚ5k\uwǑ8z N[܆VIc/ڟu?nMJJ՜uV7|:/Aղ~zos=BQV^7x]/?_lZ-k׮%==?NϳBtl6djRȐ3___RSS/* mk|o.V_pvw8XlYYY 6Lv #G}9b?ݡt< !D[ B!DZ B!Bz@ !B!p$B!B!;v,),,DKHH`(Bff&Gb02e vB!8KO iA}z`00h 1 sAm:t(}ERUUEzz:m"##FCee%G̩8߶3gHIIl6M>4pz= 瓕NԿ#Gݕ,FìYhZ7z:un 2338qSq:KՒ@xx8FN>͑#G#&&}vjjjl aرٳNDxxxqdddѥum)66b2l3a)--eDGGz}yy9vBQOnmZ&;;ΎOKb4zxBCC1 Frrrξ`B!Do+hZL&Ƿz^QF` 99"##3f ;v젺EQ L, 7;wLmIjnNjj*1rHf3ӷo_Nzz:0f̘V +YYV۷(5zqqI| 4|p8|0xxxзo_ܨ#//IIIAUUZ-C Cg9rm@IMM%O $&&Slc6=VWW޽{~hllDUU{j3j(f3L&S?N TWWSRRrA !BަW'դ( 111+HZZKqff#G*)))vbڴi8@v(///-+ֻ"uDGGSQQANNraBCC.#eUUUٽ&66ܥ NCa2֔h4rQN8agYʏ?Ȅ  %nnn;zr5P]]*ވd2Gff&^Jii)dggKPPYYYdff:T:%Diiݚl[M&j ءMIɓQUUٹsg.GLL ֒e9b Մ˳CS jyy5`0s(Bq'QEQZ-FoZ;Lt:eHӧK1cSN%66֚*eee`:ڲȑ}qZ9s???@Wٲ4 QQQR\\ǀL&j̙3员H>}ѣv G㈨(JVV7of߾}DFF2`6PXXHFF.eE~~KcqTsQ6mSTTdk-lAhh(]vUUUv1;ΎZ!**VUUJJJӧV4 777,..f jkk @UV-̞=l섄lh]]ǏwQSXXHQQ-}ewMMVTTPSS5wqc+B!DotQ'rۗWUU9}4'Nh5YBB޽Z***l Auu5DDDDFF޽{! Df3f3v]eEGGS^^Xs5%%%|@XX$%%.0dee1|VOGdȐ! 21mBmZmnֽz%88rDNy7Ǐxyy1p@:DmmK( 1RUUE@@ݏA vZ,6[?Ghh([li5S!BN )A۾};nnn(hdرV@BBgϞ=]XV\C:V9v옭@ ɓ'jb6qww'776̛3eӇfZmM3333f 񔕕JTUm94'ɶיswII ,4TWW&JJJb۶mv? $-B!N@d20xzzhDG8Hv&z=4ޭ:<==mFAӵڶl/Jee%y3gZ}i?z9[VTTFD|8S/UU-Kqe?FvuEO:E@@}%3:u B\\Kٍ]Vjkk) =qkw̥B!hW'_ }||jk7Ϗh eܸqL&qlC jOOVerWÑxTU%//}` 22 QUFˉ!$$@DD%00HLLDZ^Δ뉈tm^0vXbcc ۛh"""(--u8!q~V+YYYDGG`ח\ZfOFUUbcclsŖ͗Cg<''<<<\v|TU%??$66sGL\\K'B!.nnnL46ۛ~Q]]֭[m]u;rmF_~zƌcǏs!STT^'..Cb4Ȱ} VUT=z4zrss^lC1p@!%%ѲV(((G '!!VK}}=999deeu~lwuufOgX,어9``ҤIvձyv{ ȑ#{PYYQU\Z-SWWϹj]B!z poqZ%5WZoht7))i#k(v6رcilld߾}}( 'NGvw8B!B\0f$TzIחˀJ4t⢶4ߧ=RUU c)+!!xB!BFO SRR;quB!ItB!B\8@ !B!p$B!B!7|;qQPP<!B!~HuW^aΝsϵzm`` +W$--l6l`[c8|0YYY|gL88`ԨQY Yv-罼x'ٿ?Ǐg׮]{ty4w\vINN6mj+QYnnndggSXX;-b bcc9pӱ:sg Wns!/!B!JH IYY+WlsuFK/Ĉ#Xp!W\q}omFôiضm/fzjx̚5k(..f…,X-dCqײtRƎ?ϒ%K?S\y<쳼\uUj* zuVlka˜9scÆ ._U Wls/!B!JN 333yϨm7^z)V"%%^~e 馛X,~\m۶̟'LxnvϮ]HIIa͚5TUUM ٱc۶m?dee1dcQ7$''[oO?Mee%sui)KUU9|풐@MM 6mrGlj ~ !BUzuVFl6SUİaMFԩS.G1n8RSSYjd֭~h4MojeϞ==hSe 6V+FC1rH[yet:ϟϺu먩qqv# WmUP!B VZYYÇ7oh4fϞMBB~~~m~)W￟ǏqFN@@wqtM;,_9sض{شi[n%''5kO_;Ueee\wu:t#FP^^N@@Ks)kĉDEEG;ʑφiB!VjXXlnnns( K.eojnJMM^#33_l޼n$|̚5E1}t{1y~_S555Q__ܑEa$''sر.-|6\MWC!B!z2YYY̚5Z-eeeغ BSRl2̙üyvy,FrrrlɅF͍|_VqƱh"6mڄbq*Xzk`` vuwE)+&&ɓ'd,G>ڦ'_B!B JKK c„ ڵ˖i4/_΍7-Bfff!""OOOcX,m76.,,rV+z>}jZ Vcڋ4l- 6JHΧ^Ζ5o<\枧>UB!ݡW': 286#F`$%%1c V^MYYm읢(444uVy*++8gΜ/V{?x ;x'8u+V>{˗K/Kqq1o6/Sg,_{?deeqw:=Бz9Zٳfڵ=~b ~ !BUmhjTZ<|_iqZkߤ]|7ߤ{キZ-ׯgu?~FFL8ѩ8ۢh0a;wluZ- h9r:owq^~* b@Ohh(HNN]G!B!.^@Gb2$>>0zh 444ɘ1cرc(Bhh(%%%dffbXeܸqܹө;LJے&Պ6&<ta̘1l߾֫V+۷oGQkz=ƍɓ@KUUBXXr NPP틛uuu9rcǎHbb"`+ԩS9rEQa9r{xxf&&&R]]MII/B!DW duu5iii(BLLLtfK$233ׯ9rUUIII{]UUӦM#$$ĩx @yy95Mֻ"uDGGSQQANNraBCC.#eUUUٽ&66% ɓ''** ƌÙ3gZ&CCC9z-kjjj{mIyuu5VIrm333`0B!BtzEQPbVdLӡ(] +h49}4\r 3f`ԩUU)++///[SN9UDjrZ]Q/gh4DEEQTTDccK34%YYYt:<<>2b;{ ^gСdeedG!B+]c [2LF<== [yLZdd$wﶛ$lzOOs7*UUU&N%Nk*xV+ 6U>>hZwGtt42n8L&ػ!Cf j닧g2ccc v:UUˣo߾DGGc0$$$BTUrbbb `0A~())iuOnn.Ebb"z6Ur,^ODDKmGcK@@DGGAii-:>}M߾}0`խSIB!PzuV777&MdM~f֭ hjRRR‘#Glqj4^g̘1v?~8ri3>LVV}'Nt:NG5jk֬!##t֮]y///|Iٵk{/:s͝;;wæM4iRիΦwAQ۶+V 668.B!^@ӓ2V\Innni4K1 rWwoؖh4L6m۶xbϟOYYWfС.`Yb.\Ȃ X~ݢ=^{-K.eر<,Y;ϕW^ɳ>˻UW]EJJ Vb.WgefOn̙3:6l`WWpU݅B!ӫLq>3jkk[=ͥ^ʪUHII_~n&, ~;+Wd۶m$''? )S4ロݻwsk.RRRXf UUU@SB;|pvm())?YYY 2XE7 ɼ[OSYYܹs]Z/GRUt>l$$$PSSæM\py݅B!ӫhZ4 fL& fm%OOO4 Nri<:qƑʪU8x [noGiz+V+{aDGGDTT*kذa`Z0:t#GsU-K1|֭[GMMˏ󅪻B!?'7J>̼yF0{lk3P￟ǏqFN@@wqtM;,_9sض{شi[n%''5kO_;Ueee\wu:t#FP^^N@@Ks)kĉDEEG_ !Bs,baٲe\T, | 4tR&Oܹsz[#V+7|3fbѢE;vc#p6lt555Q__ܑEa$''sرnG!Bᘋ:b֬Yj)++7ޠֽe˖1g͛Gvvc1Ԑc4FUU Cƃ>믿W_}eøqXh6mb8TVUUAAA^500 ^ΔɓYdK莺 !BsWQQAii)aaaL0]vْ8F˹w?>>>DDDt t_Q^^jEӧOVZV CqHZZIII. 6JΧ^Ζ5o<\gn]!B^݅Ϗ 61cL>FV+'66n3YYYTL'>>OOO9r]]Yh4̚5 uSl322dĉNTUe˖-\znhꪫ^'>>P F5.!Bѳ=ZDff&WѣGc0HNNHƌÎ;FQBCC)))!33Bll,ƍcΝ80~x[dZmWLxx8TWWȑ#1:O߾}>|8Ø1cؾ};555.WgeYVoߎ(zƍɓ']Ã4Ebb"ՔtwxB! duu5iii(BLLLtFEE׏H9ؽiӦTY< ZcϏR[]QQqqq:u| ''UU9|0DEEqaˑ^lRӡ0LvkJ LBrr]KsLL  `X,E!..ݩ%++˩\}նÇ3|p8@~~>$$$NcǎٕhHLL$22UU%<<|;f.""x0L呙i̕S^^n>33 CB! dgEAQV[1N(4444FC`` ǏK.!00EUUTUpup,???lIj̙3(a]YF!**"]z[#!!~SNӄHEQ ԩSX,)8p pFht+h/ %%%c4۷olӵ 4Um? Fj%++Uh;FB!BN f3DEEQRRd"<<ooojjjMuy˘Fݝ8;ѣG dСX,1Sڒʴ4k4z=Fʞ={0Lr loVb`0#==hJOaa!EEEdggӷo_Kڙ'N#22`JKKh4DFFcf0`]+i]]999DEEq1|s7o???vMB!N UU5iӦ*Oĉ6KHH 88ݻwwYXEEauu5DDDDFF޽{! Dfs$fz[ZWrh˝y.222m=uQ\\L~l-Д\ qRUUE@@K[qi§mݨqss l20vdȐ! 2{sv#44-[PWWץB!.۷۾FƎhl?!!gϞ.IlV+=^__okj ӧ(mUUٿ?Æ cڴiMZ.Mc:Z-\r C]]]yyyX,}Ϭ+B!D[z|)oa!B^= B!B\lE-yW\\ܣf̗H!B!AZ-EEE(9Uz| oIAAyyy\wu~(((pB!EAӡt='֭#**=+Ν;k@V\IZZlذ/(||g>|,>3&Nt0j(֬YCFF]___^^^<߿Ǐk.^t:ΝΝ;aӦML4QYnnndggSXX;QXX8txV$''w1m<3m~m }|B!D+xzzRVVʕ+\$]K/1b.\W\w}oa[&B0m4mŋ?>eee^C4fYp! ,`v?C\{,]cϳdϟT,.W]u)))Z^e6k>}2gذaC,bQfΜi+׿5ǰ7nϬYޓj?7tSɷ+B!= MIJO׺n7_&%%47{mwV_|Ç<&>(k֬@W_e׿????ʕ+?Am/W^y:4%֭?mذ.-܂jݝ۷_O^Zm&MDMMM֯_mr&O̒%K\GG*++)(( ,,̥۴ߑ#G70m4 /7HCCbqi(z+O= 2!CЯ_Ve~޽ɓ';je͚5L: 7ԩSYnVZۘ2e p ̜9͛7j-j/UUYz5Ǐg…İ|r]Z/gO>鲮:^x뮻ѣG3eVZFaڵݑzmh2xuuhJ2/_K//żۼN͛7|r?ŝwCGhYgۻDΕ =ד-:s {6o5QT~~>&MСC$$$tB!E:B!B\dNXV~_õ^ `ٲedee1l0#'B!D[ B!B4H!B!$B!B!" B!BH)B!!@ !B!p$B!B!4aB!7l6wwB!B+wk'B!!@ !B!p$B!B!" B!BH)B!!@ !B!p$B!B!" B!BH)B!!@ !B!p$B!B!" B!BH)B!!@ !B!p$B!B!" B!BH)B!!@ !B!p$B!B!" B!BH)B!!@ !B!p$B!B!" B!BH)B!!@ !B!p$B!B!" BޝGY3d2d P!,*(KTCGjW{,A+biGKO{zAsbF" [}&eBBfy=k{3{ H H H H H H H H H H H H H H H H H HY yP;,P^@lhPf l9Zn^ogGDDDDD$$X,"##Cx) ܞPiPaADDDDDtX={Y AEɰaطogϞeذaرc|7-kDGGIee%v ===z8rG0p8۷/nk?^o.rtbTTTjC(** 숈tzA/ RXXHqq1=0`TVVD^8rQQQdddPTTDtttN366ΡC֭} a\uUSTTDUU`7k:64,'>>#Gp {cZ9~8'&&㡨l6ȑ#6;Nsӷ혦ѣG9pi}#""2d԰~N<nC󜑑K\9""+ҿg8//`EDDDD:, 3224MQSSӢO 22^zqA-SիW_}5>"ʨip|>.3gx9Nk/..~qiHMM 8Nu7|C||<?~fDZN?22z{m9n|>]v}sγbW^RQQA^HII!!!_dVUUm,""""dYPP@QQiRZZJTTTJKKPXXHrr2a`XZX,JKKq:\.X, ?bРA|>+<1ϗW_}EMM $&&gXXXٳgq\>x78p@k(h"F|cflW\ɔ)S 66믳}`7S7}|deev/:+kd)W?L? ʕ@}9͉{ڈH,XᠦGc1l08~;NoFȸ)))vjjj ..COdbbb,Vsy'%%+0m4222"**}2r !snngdee@|||>6P655L"""z׏~ڿIF[fj]҉pt;rD' bb&:y@B@6b3nԩS&::;wߎ!//Lnv^{ Ւq.]ʊ+f„ < 4_|1M)5'|#}_.yKi-添ߟ4^/>(vtrUW:Rj*\x-gwΜ9ϟ-–-[x'N(ft:!??dV\Idd$iii:K}sj%'~oM `D'4-F?Uӈ9{1E_+<_$&":Q}6E_`V_7aQY9_ v$lD^^3f ''FII g楗^`̘1$%%˲e|L0~Z2n]Zl `l/NLL4M^{5֭[Gaa!gΜaΝܹ޴.6o2禔a&a0l0N'eee m|-g'W(f[VVF~~>aj/"թ\%"bJiN}GTRJ_Ӎk$?5҅EMY>a%M߲W>@tҕoM)>/0p݌3#GvZ9s&nmƍȑ#t҅ntZ2ncvލi$&&0K'}'MN-Krn΁Xjapn:,X^S7%l'Ǒ3())aΜ9:|fb˿˿:(W k$C7[[g*]N˯ma|`+u-obˉr]NZcIѓs31ӄ5kУG-[FMM {졼}rWR\\̎;zl޼L8͛72\~ۘ@k,-K-rniԔAl T{OvSɿuzNc^'ucx)1ͮ]$-d?~iӦaɇ~-aAXx1K,r***"77aÆ]T3gd̙~vhu7 4_ZC- i*Ւ~V}rَ3;4%'''MZgC~`/Bx2}|=^_/uN_.ۜ$ 1~0}X#ؿJCO1M/=>-*>Kݡl0曱X,R\\\{)Sн{w[lOT>ZϪOX={8~8UUU߿?.&O}S_[0}Rr] Ârdä8\$`rd#T =D1}*X>DtwTQy3RW mGQX;~ݢb?Q+0!""""""v\.ŀԹ}{WROCV }* EDDDDD$ * EDDDDD$ * EDDDDD$ * EDDDDD$ O8v;6[H͖4PUU6D9w,9<(Ãrj{$^rBZ\.uXftb)..69rsxPA9.6gj%&&&CHªNcl\fSr9<(CKrVqnA/ :Nfp8}\9w9<(Ãrk.n{4rR͛ٸq#?,ΝСC"##Yl{f?t:"??dV\Idd$iii:WGe׮]8N* o}$m'Tr:|iwί +V ))s2b&Nڵku8p cǎeu8ܹgSRRs=GNN555DUUpngNqƱt?t|v;.|~j*"##ٳC{ nj3fQRRٳy饗UVa?\m^嫰HFAFFN4M\kƺu(,,̙3ܹ;wy:feB9۲21 ,V+EEE|nN0 aÆt:)++#''Gx(Tr:|i+g;Zi)붓ٱc?_>C_}U6mDqq1|W_eڵ-|σt!Edn7cƌaȑ]fΜnyw4MbrXzmŝwމi/4MX,O^YϚ5۷/> 2a!ɓ'3c JJJ3g~/׆ZXjapn:,X|Ʀ#m+r:|iwΓ'O7dÆ tM|>֯__Tmv3vXFŚ5kHHHv ݽ{9a0`?o|1M?ϭ|̙3w#tk#֬YC=Xl555ٳr,k3 8LСClݺ[oz!C石sN|>XVf&ɺJr@Ptz={f_4Mynĉ=z4ƍc,Z{Ʀ#m/Tr:|igIII$%%c|gشiqeݶٺn fh"?>[n%6649xy֬Y 2={|l| lѣG;w.K, 9\s aPXXbbb0MRV^MVV'Nj*JJJ0M?czl6 ^ Y/_Y(nڴRZ>?Ǐ>,tkHHH`ڴideea&ogq㈈`dsee%{>?~B̙3[}>_ODDnZOδiӈ0 L?o 555|>VXcTWWWxb,Yo}UTTDnnnC6{:uja?WW3f wqiKNNN",57|ZA՞ɯ̺u46w}7؋#WV9n#==3gu;|sT@^cǎnrio͖-[????vlϴiӘ:u*#F 99KAA}`~j+2={8~8UUU߿?˿͛7sW#??-[?#jʹVMM ˖-㩧bРAdffsNeݎ#G$%%BQQСC|cǨVލ0:aFa:k/omޮveff~X\\ Nuo EDDDDD$0* EDDDDD$ * EDDDDD$ * EDDDDD$ * EDDDDD$ * EDDDDD$ A/ =OgAHSY*C9sxPᡩ,^ogOH(A/ = FR9w9<(Ãr9Kff&QQQ|>JKKٿ?7ofƍxxJJJ7`̙9irJL_|q6mG}D~~>ɬ\H(((v3Ge׮]8N*k̙wr-lٲ'|?t~޽{SVVs=ۉ#++ɓ'Gכngx||< ,`Ȑ!y睼;:5p@Ǝѣp8عs'<锕r0a?73s~}O{'ϟ~UVIϞ=yyyy̘1l6%%%̞=^z)iTVVj*1 cկ׏?ng]021 ,V+EEE ~aK 41 aÆt:)++#'''/ ʳ}v=\XXHdd$wq#F ##SNaDzL^cݺurvΝ;.:{,%%%X W|Me 7_~mJKK)((7 b={xbbb":鶕ٱc?_⋗$g%r?`7YQ͘1c9r$k׮%!!3gv[<ݻwc&ƺj*>x}O<3fPRRœ9s_l8pUVa{/֭c 0R5brzj***rqwb&_0Mx, iiiÛ>f_CV}ɓy7ٰa7t>_H}w5yuJ5b!==o8{-ZzZۆfر55k֐>xAasϞ=ιG?d̙ʹ :k֬G,[Cyyy[1j55a…dddp76%tz={viZ-m-줤$s=3lڴw2ۨ44ެY5ktxj; \NlnMr~衇x衇"g}l F=zsdɒ5\aR^^~׿f\s5 NcӦMgϞ`7K#//ŋ3ol?[,bbb0MRV^MVV'Nj*JJJ0M?czl6 | V[/2[n_'66wy껃xvo|62x^n7gϞ;Vbݤhʹjn;G.om555s޵kW6>,T@^" qdeea&o6~)]w薗Hl6555^dX7nyyy+VyfbpXx1K,r***"77J\0^vv6v̜9~i=ixbCjj*O=]?0idK#عjn?۷/W90* ȱcHKKӧٻw/o6[li늊 ^|E~_g?NUUbr6oW_Mrr2>|lŸGp \ve?"_v-n1[.`u8q} O ž={8vʹ U6;3QgX}ڋk۷k]7;)))niC'Olpr\sxPA9˹KUsrr{P xOk߷}u.fK}ܯ %5rСCko޼ 6x @6#22 p8ѣ>QF_PVWwLL ;v{Çg5o[&LТת}PQQA\\C'^ &&&!hd3Ș1czL:htRVXA||< ,`Ȑ!y睼;<#ݛr^xrrrx<χZ^";;z)ƌѣyNkݴi]t7n8-[FAA6)S?_LyOHkmW^y+Vܹs1b'Ndڵ^vZriR6m⣏>"??dV\Idd$iii:f~qz<ڵ UW]_ aꯃ | 8c2zzy;>xo?gyƟ|?Vtt4z+?0 _ v>BZZZ6Zw= 'O7dÆ tM|>֯_ވYf}v v3tJɓ1c%%%̙3G{mc|Z 0{Yn ,`穿PVv;v,Fb͚5$$$^T}vލi$&&t:$!O%v֬YC=Xl555ٳz[wޤ2{l̙Ce.k&qqqɡCغu+z+=C ?gΝ|>ZLDRRp0gyM6]zeeeTVV :Ptz={V\"ϳuV&Nѣ7nGfѢE_^uRZ/lnz!z!|>_jo =zsdɒznΞ=wVZݻIIIb2dl? 5\o[ZzY 6ZoDD111Iii)W&++'Xj%%%b!&&cǎ=!m5y {ٺu+:\}ռ;|,_\l'M(--eϞ=nN5#//ŋ3oʻ-[#<„ ظq#yyy}iB{gf&؋b0n88yb3\.Vsp՞|^w]()){nx8|pӬ}΄ 0M7<|,^%Kr[j[oȃ>ԩSq:`;wپBnfa&555|>VXcTWWc=Q8 ]vm3sL~z?L:ްw)5َ3;4%'''؋#ׯj=Sv8MTuZC7dРAߟ+W3M{oa3f?1i~ NϴiXf ǏP]]_;?7|Cyy9N]bZٷosC߮"裏~z?-[cРAdff{<** Y3u vϞ=?~Ç`/4͛7s Lr?sYVuZCߎ;xٽ{7n>̫… ;vJl6VӧOc|Ixfus m8WTu7ܯX}{ڕaqqq366ߍ(E9sxPᡱgt\{Q{?Ennu@1R͛ٸq#k bcc9x :۷ov3u:>o<0 ꫯ>7 ɓ;v,9rm۶|rLdҥۗ_~+V{NkrX,-bȑCNN?8i9:PuʕL2E}%:++sv9tH-[F޽Y|95{`7MSRR1cÇ'>>x79s (Ҵ<,XAMM Gcذa7n XhYYY-zv;555TTTСCy'Xd 111IDD^~O?=##$, i^… 4i:III+L6 o߾9R>QFa 7&&j;c=Û|&Mtp7ӵkWLwѻwoSycǎfq v& yy2fn^/SN%::hrss-]+Vς 2dwy'[likN+:: &3h >^|E6mG}D~~>ɬ\H(((vu +b ;w.#F`ĉ]4yGݻ7 xbv`ijjݝ3gs-e|`7Cj:Nrrrg_"mK.qǍDze(((f1edaH/m-2߿?iiix^}Qvڅ䪫믿VDdر=^ js~m|ߎ!//Lnv^}U>#Μ9CRRƍ㫯j2n8lقv<}=O^^3f ''FII g楗^jpgKJLLlUqPYYɪU0 Əf| ++ JQQ_|EӸKJJs4M^{5֭[Gaa!gΜaΝܹ3؋"4J\g_ZmwތB"##;1b:u 4Eȼ 41 aÆt:)++#''G1}tv%/bرƌCRR,]DŽ ;zƍGDDW\qziӦ`7G֯_#--'|EEMilݕK+TsU}iEի ++ ŝwމi/4MX,ヨ-2?pV0 ^֭[ǂ 0`@/nƎ˨QXf |.]p 7۸q#^.pM7aZ/ث) &Y=zl2jjjسg.Κ5Yf{^M Ȇb:Nx^/g֖K ܓHJJ3V/CksnOPU}ڼ ..49t[n[o塇bȐ!|ܹGtt4VU}|g?֭[8q"Gfܸq=E~`/bXv,^-[ѣG3~xƌo~n_~9W^y%ر͛>}:'Nww^>s 7_|رc1Mx4OvpQΝKQQK,iw^*?֭[~{ےRT+""hLӤ׿k0 Bi&|M&_fɔ`W_}w2ǎbZ2dHGڜغ+^(>imLӤիW8q"UVQRRiqW[yyy׿?jnpv=ʜ9s(**ǿ3i$ns? &`Zw?d 4={6,dggc&cƌo&99ӧOm۶`7C"꫌?b޼y޽8WX֞ ?]vNݎw6mYYYo}Y"##۪ +((`ٲeSNg `ƌL0DN'gԨQuirnH 뮄U}vp54Mطo~)'Nߧ8t bp7YWtIhͭl f?~7oڟbpWVV{^C׏cZ)֞]lzǓO>`n;vpגHee%x衇{VVVӉիW{Q;mnv/~ vMee%nÇꫯGq1lXVN>͎;xꩧ/YسgǏ߿?؋jjjXl>A 6mk֬x<yw.8DbԻX-Yw%GCGCy;z|nclI3<UUUo Qr9<(CksZ^ mQ!zj4sxPA9sxPZ!q>"""""""""""""""""""""""": NݱѵsǢÃr9<(ڜ7ƣV˥l8Nv{@N;&sxPA9YcbZ 8l6.sǦÃr9<(ВU,DEE(--el޼7x\Zy޼y :˅aW_|baҥvvm:Pvu]dddyپ}{ӸgΜȑ#fNNʼy2d. W^Ͷmkq;k(Eܹs]k9NLرc޽;iRPP~G***ӥKV+Wdʔ)Zyx뭷y?bԩxkZӟDzz:ooIII'Y7gXXl}套^bŊn=͈d8jjj8z(=Æ nxbHLL >>QFa)))vjjj ..COdbbb9##$, i^… 4iY]]MYYYinN'MMM%33^/駟&555&gǃv|aINN"d?@24@$^y~zMdd$QQQdddp7_CNkm^s;&&j;c=/0Mݻt:s[oņ ѣ. _|Iϻڵkf 81cp 7z:u*DGGvIKK裏k.N'W]u_Zt)+V :: &3h >^|EߢIi˜_yVXARRseĈL8k V(ei&>#INNfʕDFFFAAACkMsOgr-lٲ'|?b֗^zl"""xꩧ3f GS[iSi<#ݛ/^LNNdddHUUUimW_}u{INNv0p@Ǝѣp8O^/6t>SL||<Æ #??^za޽DGGsx#33oW_}5؋ܡid31c999l6JJJ={6/a 6 IYY999MndժUdggcǏf].EgϞjZa+-++#??0jRTTToK\KssG`S l'Ǒ3())aΜ9k}~_}v֮]|z(K[u;--ݻ1 0h \.Wimmk}n7cǎeԨQY|A!ş9W^y% 6}q)jbbbwaX,~lذ<>L.]a 5kѣ˖-={P^^?֭[8q"Gfܸq=E~&[4[5=i9))$)y6mt땕QYY_ZB)[wޤ2{l̙S[uNfDϟ{tZo[}~yzyڵc|~$%%??t֍'2b`&\~\yc^/7ofL8w}WG]$8z(s`ɒ%6#Fρؽ{7%%%~嗔`?~Vտ T999x SNtaܹVFeq5n|>/^_NJJ ,4MLԆVzٱc{`۶mx^***ؾ};z+i>|8TVVr7AY(Ngn`dg?Çٿ ,U7P^^k׮XVkܹs_RqغϏc׿RPP4Mu9O[ZCᅬm6-[o߾0[X,R\\\o:[lҽ{w  m8WTu7ܯX}{ڕ5jOe>ܹ(Ãr9<4s.]=kjj,\.ŀԹ}{Wbֹާ)""""""Q)""""""Q)""""""Q)""""""Q)""""""Q)"""""" z?pTʹPA9sxh*Kٓ6 l Ȫ`ςTΝr9<(Ãre Ȋu<>;sxPA9@r^ȎK Hbu^㡸sǦÃr9<(ВUDv\^7ۃ-38v;6[H̖4PUU1)Ãr9<6gExBƑKC9sxPA9,HS)""""""Q)""""""Q)""""""Q)""""""Q)""""""bgϞ$%%{V$}"""""Ҽa1G}+K.رꋞj%##CQTT8=zctJII {졦.rtbdffb|qAN>dذa۷zӳgO㏩bЯ_?vJMM 藺ףGz۷q[Pϡ@'""""".{ 22(tn'99إCjj*6[]tgϞ={#GPSS0 *.29vnłfԩS>|(F"**zSSSϧ|;DFFxx]Ӈ3gPYYIrH=6 łir .2 ͊`Ȑ!DGG>RRRHOOjrqߏ8N<v+ "";wt:/DGGpĉz@||DGGz1 'Opx***IHH.qqq-~)4ػw/ 2x7\ݻw]cbb0`x<HHHfq!9Ϻq}rW&//`*"""""A={ %66nݺQXXiDDDx(((`޽TWWӧOIc8}4iiiő@^8}4GVcөu!Kbbbׯ?~TRSS"66cǎOUUEEE8v;. 49}NrW2x`p:All,ɘ^b̙3 muv<jLnojl~|a~+""""v9qqqq={2Mp\|g0MY/^sө-~ΟNS*++)--[n$$$pԩ _YYW_}/)//hGo~!oqۖcvѣG|xxݶf {0kjiq {iӧO| 8nݺEDDDD:Z/ǏG;v_4 ЉnΜ9Czz:̙3Ԟ嵶- n M]|499.2bbbw***ի*bccٻweee:#fk׮Ǔ7|/[2<##T>cN:E^ׯgkƖ6@b$!!ɉ'p\ g!U@VTTXV󉋋+4MʚܛU\\̾}ի TWWSYYɓ'Nii)G[ndzk.O޽IHHѣxBٳg/b!&&$^/ǎyyyۗD, XVZ\~TVVw^^(kIIm|>_~%555lj>7vmz8~JJJg wU6;ը3Q~۵׮|\JJ .T@GDDDDD\.rss/sŬsO#ݝȑ#*EDDDDSS iiA? t * EDDDDD$ * EDDDDD$ * EDDDDD$ * EDDDDD$ !uVÁnf xES#"b3}x]}"ADÙ Y oMV˥/q"rQl6NNqq1^Hkq;{p|S*EŪ]}vx}e8U_D-l6\.WhQDZ՗C l!P@:}6cp8>>GDRs}Ι>wx6Q˙>w{6_@`ςt2M+sD5կN$ "m~E}} }J HT@H@T@H@T@H@t6 *aaLH\v Y Ig="""""ԍXyo"0=7KIIaƌ >xJJJcҥG?[nGлwo?`ZY`Ny79s&#Gltrrrx1K9btRnn2͛СCq\Aqq1_}|i2źk뮻 66믳}KF"u8'/K.7̓O>ɩS;z.ȑ#3goX~=ƍWisw6ʕ+2e2 -3ߋ+$X8]cTg=6=ngdee@||(vtrUW_Xz5?я[oE.]z2p&S%`r-lٲ'|?jr]w1i$)((7dƍje\uUtw}ƍG>}8s ,_w_oҥX6XW^aŊ$%%1w\FĉYvm47C&MD׮]9z(_Yf ibX5kÇGXV8s>#INNfʕDFFFAAAJ 8{ϟ[,~sa&3ol9?$~ӟRRRPvNeE7ن7ZոQo?d1tpoO*0s/a#zF48xV >c07M aFd'1b#%%ſ0 ޽{)++#''7|nL_Ndd$7oO?h:͙5kSLvsIzٳaX,zbbb(++2h  륬.]Çm۶ 7??ٳ:a'?aӳgOq\.ZvmPQQAUU^Ξ=adeeaZ)**j RqC6:Ǐk׮̟?3f\ԩS,^_Wx㍘GiiiөݳLJpc(v9[c{8T{M\rJۮ".Bqj~6^xj,aJ<_ie^$뼴/IYwy?sVZa{ャ[ 0`syW0M{믿R^~e!]L))))?v0yd~b~{i_;3ӧOc&-bĉܹˆ#\޺f͚|Çr\޺)++HJJ")) 8gyM6<ȑ#̙3l۶ M6ӟIϞ=ٷost:yz̞=[[RqpB222km[NYd;W\qvsLL]Si#*;,K?m{O V Xハq3ob?FX=pjCڗ N.//</^̼y=z4w}77nXjÇnݺNco']]]_z[|fЪT; #S/_zٺu+:\}ռ; ¦M(--eϞ=m2=RаPS\\̯k/^5\sQi<=zԩSЧOf͚SD~jYJWױNIcƢ b-ϯ/#,CFvݺuc޼yL:łbo$%V.ٳgUd: 9tN8믿Ϋ_W֭[w!ae˖0axxƌ-܂f#G4lڎ# VȼE_=^ӗ_~I&1tЋ2 gV L:s=PXvrFX /NxpL"GzyoQ9W=xMb,=$:؋.aJ}'1i$x'OR^^͛9qiz9r[tRkc&oyWoDFFrahmuEEEt:]2^SSòe| 4̀2d/*Ǐ'::^x.]ٳǏsaߪEBhj모_lt/mc//P\\kix<~իwygmLJL#g4ÿW#ŘbUXSvA17-K\ӄ.6rC fUUs&Dչ JΰF׶oo^233?,..nvj}iK}V#"Bc}7س&"L5r{P xOk߷}u.fK}ܯ=""""""""""""""""""""""""""""""""""""aHWH[k_*N$UUUdWH[k_qN$# "mPQQsD-5$sH1/x ~ P\\/t"jfS#"m!>'OV*GO l` x^N>nclHxjr/@]sD5ZD哶ǜse=SE"xBbcTQQpg,"ZsD=%sH} !q>"""""""""""""""""""""""": N/"ԯ>GD.i/\J!уYV\.:T(6 ӉnsD5H{iiBVu"l6.H[P#"%=t8TEl6G>GDKsM{ ziۃ= "4կ>GDK()A/ UNDZSiksDBRDDDDDD:""""""""""""""""""""""")X,ƍIMM tJ* E.RTT}t^{!###س)":D'ri=kj'{%111س)<f̘Éf966ll6{/S~Z\q|׭nk bcc9x :۷oo,}iuKff&QQQ|>JKKٿ?7ofƍx<ۤP}b'~JT].k?H7 jܤ}hdaYx1YYY)5 0xVpt:s+rJJ @VxWݻ78N ‚ Oavn XhYYY]]]MYYYKmARR4IHHke…L46 ccҥlݺM)55L"""z׏~Zft`Z u6mDEEE߾}9rxK}매`۩8O<%KiM'vNQ?հwj5+==djjj(**"**L,XeE{ Cy9x JIKK裏k.N'W]u_5s?wr-lٲ'|tx<呙k4_j|??n:}Y:ONzz:UUU:t_򗤧[j~azMYY=۷o'..,&OG}\o9.]ʊ+g 2;3w}qgc+Š+HJJbܹ1'vZ~EBB555|gl6?O?~ʬYp8ܹ> C&MD׮]9z(_Yf ibZ3gW^y% DEEq1?n:6mG}D~~>ɬ\H(((UuZtu4 <#ݛr^xrrrx<4/- ?9|0_|Eڶf„ < 4_|VMjOOjiѲ4iK/Dvv6)SS-hs8'OlrYfɓ'ٳ'g֞ˋ=!j͚5tڕ#GiZ{eʔ)|bpmqF8rzn{:gaBj^zd%ffPS]ԼwsNJ5I낚-coWn"P(0̙fvf8<˙9sk}.ȸ i_II J%z}y2~e1^lt6YEq3 Z`W_}d]m۶Epp06l؀;>@$Ӟ5#KYb }Ϛg̘1:u****pB5ܦM[oӎv"** ǜ9spI׃ӧOcF@@mL1Srʜ+J$%%!))۷ok/"t:&Ok׮aȑxQ;EZ:TQQ/_nڵkq1 A0`Z _}q>ٳ'q HC7#pС;x_|t v7|;wի {l gZ$k4Ԙ\HHBBB_s#==(bڴi=z/^Jes\t ut[PՈĥK,#I.\>}OVcɐ$ ,{ i8%n)Twz|t邸8Bpl?f1p8e2;HAAN:!<< ,8%ں= Bn۷oQY@6 {LNNrrrEaxWpH|ڴi`oNTT"##qu7 e(0Z3g1|p<󈍍̙3?Z [PP^bORD޽0 %It:n߾ . 55Of67a9r[lA`` qddd?~<4 6l؀j̙3⋞Fe|騬ٳg$6]n把 I]`;ic(//G$''#&&i (--EUUUy`&ߘSS\Wyڵ {POWF~i:hbbyy9F5BPP}]i[)Stv60)攳u:+`;w>}:&LZ,ǂ/VǑÇcܹ>}:dYF@@#TVVnݺ3gΠUUU8t!2$IB^^`͚5$ !C@EdggÇC$}+V~v~~~P7{{L~EEEA]7n@ѻwoTTTԩS`ի I $2֭[M6͛hժ n:VѾ}{( \t 7oƻ UV?$IBYYdYիqFCRW\J9cƿAǭW[{y3sn`8 BvvHf 7d1$$$$$$ Hg?BKDXrCD!"oiVmI \a1s[C4yY]],*i"?zTWW}CD!"oq7$3\z;CD!"oq5oA$ PTP*d=BCպWCDwCDؼf`ͪq!"obYJDDDDDD H""""""r H""""""r H""""""r H""""""rIꅕ[;⚙CD`g}AP^^/b޽Ns`` R'"77b9u =zիW="yMII?m۶!%%ԞC ҥK?ct[GŋѻwoAP/_6-;qơK. ĵkװe;v쮴% 2l^;`r ^{5HdsضmDQļy󐕕LST6ۈBreJ~ʕ+.M< @6JBrr2MGrڴigy @CA`0 9^oWBBj5v@)!!!ظq#^{5t Pݻ7{=[4|RP[[jiO?4VZxqBX܌!ۥK@EȲmۢ_~tABZnn.֬Y9r䮬+P䯾*ygo1׹sg { Gtt4||| Iw+V4& ּ ddd`0SNڵ{bccT*Q\\SNvkf/ k&q/{۳6t< @:O`Ŋv~m<#$I={6N:Z{ W^… M]d K.oV^DGG#!!7ov:֭[ȑ#F4\Ocʔ)ܹ3Z-_sT[[YfSNh4Xf ;֭[W_E||<ƌ'O￷رmڴ{g޽{c8x`a_lܸ;v@HH}]>>())B@LL VX?dYFQQP\\ls܂ ୷̙3ZDFFb޼y8q"/B< :vFDDЧODcݼy* K,A֭=nΘ1ӧOGHHJJJ \j4@CP_~q%< D믿 4>>>=zࡇ$IHOOw\46bPLŕ_p }g0r%#N۷۷G^^ 2RSS'Nرcwa׮].艢#G8ᡇ³>;0엔@TB7()DYYYFa3DQC=8@iii1c'Xc̘1Ghh(j5 + $''cڵh۶-at Iiux!11,cŊ8x FٳgcرHMMEmm-7oΟ??ӧ}Ydee5h?skjj*п̙3'O:$もl߾:Ү];t:u]voΝ;q#Ib5 jjjL_̅ $$@u>!"MfHCR=ݺu/nݺe\&==oj5"##q%H .O>n?pve^z=>tqqq6ػ ԩñ`So 48}Ej'O$IX`x3cA.]¹s!C8p dYm.sOe=j>[g/۞eYvچ|grrrd,Z +XngT6m4ثH\~ dY(ӐiZ̜9Ǐ#663gď?h1lAAz=|||ЧO=FJ{7؛%It:n߾ . 55Of6Ϲ7a9r[lA`` qddd?~<4 6l؀j̙3\k\+ d4xݝud׮]ػw/ W^~!22Dݻ->-gϞ+mL h^ ۇ^za8Cݻ#GDΝ1m4l۶ ؼy34 Mz9s111XlPSSI&5wii)ߏѣGcҥ;w={@sh0^1 [nE:bWu0aj5 LG гgO,^ZǏGzz:sbeHJJBff&^z%Ȳl fu• 2XSS}7@VPSS/#m4Gm|j h:HWX׬Y,^=;mBmwNYYYuΜ9TUUСC(..,ː$ yyy_5k8YA0dl[~aH|QQQkݺuHKKCee%BCCpE;w@}  C׮]QZZM6СC sʔ)رcPUUӧOcŊ\???j=RuuuϢ ֮]7n{ݻ7***p)TVV`0`̄$IFEEdYƺui&ܼyZBaa!֭[ waqvgGUUj5ڷoBK.axwa0`0j*?$I(++,Xz56n܈|T*ʕ+gϞ͛7˗/A gDcuh4e;4ۈBR2mٕ6t;Ccm?@}Q)=g|,=6Uz7(::h;?@D䌽af "Wv4!;;i$z_nfy\\\\\\$Xr &Rz,`0M6xg^o@ DQ`$I`@jٶmPRRҨqxZƚ5k裏œO>h`֭n"8t:dYvڞ@ xsssfȑ#ohh4HݻcŊ8q" zKܮ΄࣏>BN,֭t:׿{O<_/(W_ō7p]vPTE]]Zn>} ::HJJBUUUeLǜrs3쵣cdo4׹sg  Dtt4x ,[ nf''x+VkoGADD$Iٳq)jm Bq!11(,,Ν;qȲt}:BBBPRRH,X6IAAA@||< ~_uܮ]{{^>߿?dY͛Rܺu YYYBpp0}Y0׿PYYBO¥K "^xsMT*,Y[vi 55{ "..=/WZv-1S̩)Wzz;`AArrrpezcvWWkT ''Xh W^y0]ln6m ##⵨(DFFvo EִZ-fΜcx3g  ;vč7,^7q8Q ) >>>hժdY8oonyW 8ch4ذa1gڝ%Ƌm1wqzz:*++qٻ2kn<]A$(J׮]k0LAAz=|||ЧO |24W^^?HNNFLLAL_ۦ)L4bN1ݭjL;Qڵ {POWF~i:;].E0aQg:7\/ vWCRae3ݴZ-|||0d㨭EUUDQc=fsR YcԨQ8~ aqq1lقM6aHKKkjA"pvz8{,AԩS1l0CVG3<'N 2e {9jtIII޽; |.l۶-^uCe_fS,;)TS画Ν 448w]i ^GK,B0(BeSzɓMao&^y <[n.ٜNñc0b̝;&MBPP0=zQRRF.]@eܸqlhɘ0a4~wڞ ̙3ePVVL4A۔b=z4.]s皮;سg4ݽ~' DGGch4 l0 ӟ}ZñgϞXx1Z-?t >s!2LKe٦3]svmk$''㣏>BPP}]i_/#99]vExx8-[f1,ؿ??pn݊#""SL믿n:MPe?~^e39Ŝj2^; V4f4?>}tL0jYYY~jx p-9s%%%¡CP\\l/C (Fyy$Ixp֭[4TVV"44:/^4usP(0tشi:`{͚5jѣ&MDয়~¼yPYYi'N@RRN>t:bӦMXrevZ9kOիW#33$!886Ie[6m͛7ѪU+bݺuurEvv6֮]7n{ݻ7***p)TVV`0(**?q\ЭZ  I 2V^7ŕ+W,>Ϟ=7o"77/_:pv|2^u۷7oބ^Gmm-^ ( `ʔ)رcPUUӧOcŊ]u/**VRB@YYN8e˖av)]KDs9䔳v:wYQUUZCPҥKؼy3}] ;R E``xSW}ߠ w-((Ü9s={࣏>jɻuqk"ǘ9M9E- 귇~o0f7c=67}eh}MDâRz_wCF{Smm-._ Bh<裈C>}<|"Oջqk"ǘ9M9E-1RPTT)ZXŢfc^Iw_W^@n ;m"7q&9EtwV"/t2"&fyKSNt%, %, %M^@:Z"r+"4fyKsȔ&/ ٥2y\a1s[C4yY]],*i"?zTWW}CD!"oq7$3\zA"fyy ʦ$ eeeJR,&zZr""74nVCD7fy3V""""""jX@KX@KX@KX@KU/ޚn"r3?aB@PPܢT*VRP^^I!;!"oilxC8JDT*t8fy3ռ&/ D1Jv_g'1s[卷4yRz>(W9Di")M^@ry\a1s[C4yIDDDDDDDDDDDDDDDDDDDDDDDDDAO+W^BXdYvڞ@}X* Ś5k#Gx]{h$"^}U<.:hs E]]~!::|Gh@$t+Vv0 [h0N:k׮RDqq1N:t|4{ˇҲ8ږO?EMM 1|pƍ?h ,ߕK. (em۶E~ 11ind"{_;O`Ŋv~m<#$I={6N:Z{ W^… M]d K.oV^DGG#!!7ov:֭[ȑ#F4\OiZ\~GΝ-IbԩxGjG"((SNkǹsjǔر?4T*g~̚5 3f̀?p_~h߾=nܸݻwc߾}e  .DϞ=Ѷm[vBZZ)LNxmuuu8s ֯_o1] `xjO>vBP`ܸqHLLDhh( sN8p,7XꜶ(Ν\?t8Zm㏱w^`ٲeŀpa5=='ODAABCCg"""nkf3^Ƞ'O֭[ qE4hȑ#tyL^>g_|Ə_~?!C@$|'$ zu) ,X= P(p|4hv[na޽ؾ}; .]mo7nĎ;w}O=F;mc~;t&½|ꩧ7h׮io x'VhiX ;;`a!!!())Add$,X`:g|͛PTXd Znmw8w֭[# PRRrGhPPPAB_~Ė 2_5`РA=$IBzz[L^>UUU̗;ٸsN]v;v,N ___9r?e=ζ1Qѿt:uuu̙3ѽ{wTWW#,, o}x׶7۷oLGiOd"+Z\o>ddd`۶m(((+Wj󞖖{>EEA^^LAqZ̚5 'N/ N`"##ѪU+ |㩭ڵ^Ƙ1c;fM>՞$aܹ7nVXa3Y|r :k֬,;vt=Ƽy / ;;(Zrr2obƌjر#L ̞= Xz5dYСCMv_Nɓ1f^ !!(6X>T|w9sl.3w$;v ǓO>l߾2we^ƌS .4}h3tdЁ I:t^zP(p9By*-ɝl,//ƍ!2߿?*++aӑ;|ɲ$=eeeeVˆ#QSOٜ߻3;w?OT*vڅŋ#22<\ TWW7Bs9hPZZjUUUG\n۷o:xIOO^Z69IpGM/ӦMCFFۇ[BRAGh;|$ ZBN|}}c;v A@!bJ;ZO|Bk0;`AArrrpezcvWW?2ydH pf3^ɠK.ܹsEC J!2oT|M駟͛4\3h A`:-5((ޭ-$$:uZ`ᅬTSm⮁'''999HNNƢE0`+=BiEEE!22ׯ_~cPh @kZ3g1|p<󈍍̙3?Z [VVB;ƍ7np(BAӉ|||ЪU+Ȳlq l߾yy ~yt8Kۆ P]]9s4O+e@Qݻw[ W^^gh>?HNNFLLLYwڅ{mׯ"##m^ИyMOOGee%Ξ=0A֚: ۇ^za8&LZF@@A@VV; wK/Aedggz fнAPߙξ}oUV_~iw>=izaܿ|$DTTZnPYYPt:\xŽB@nn.еkWbӦM8tPy25k@բG4i~ Cee8qIII8}4jjj鐛M6aʕ jf= V^LH`TTT/Yn:lڴ 7oDVPXXu!%%垝kƍ޽;z :u 0 8~8\r+W7_rWZ?$tիqFar˺MA:*jo .]͛`0=pYܼy|[ 2hV>lZWg:ӌio0__Fsw:W?t~VWWg2** n2Mgv/*猏ƛ׿_EGG2c;?k@ B~0g`Ϟ=裏>^a'I9 CDg׀~o0f7c=67}eh}MDâRz_wF&'Ϩ˗P(G}qqqӧ^Ct/6f"{ycNRS, E͜-Ȗ+ /[nt """?l!dYFFFF.DDDtp׮R&"""""{گJDDDDDDU@rđG%]n}ok\!X""W9fy3d䧰 w"4G!"Oc4Li9TDt:3e^pnSz1dخX n:{|||p֭c> Hٛab eYmHDDDDDt, ay #حE4!M[mIIvJBmIDDDDDtR(PT())숤k_o;1+3y|eeeU۶mZj!)%""""""{DQD@@ZW~G fͯt^x쨀~YA sܰ0J$E$( @';wn/X"V:FzgƼU4N뢝JJJ~ . hΝۇuG :ViQG? "Z (lݺJ\O J9$" pT(_za_#G@})e!i]V**Ѷmۧ}}}A Q3W*ź[n/,,G}9:h4H_SYEZ4>usҼ4^f=.SeZ*XoGHz\~Y+mL`VϙkO]5yg~ T""""""_֧}VN: G+Z 6Y-8muCDDDDDDu/yպtcوD4z"[>]lwvTV[ťEXMԟ^jQg=?g݋qu4zADDDDD;QH{%`yp^/z^5NvH7Zwc~H7!Ú> $"""""U@Zju9SW]xx/`{~Kz8ADDDDDԒXv J[h=ß,^kl/9͏BߞZEuc[ţCJXjslհ3)r;âu9}^h~8{z:"i|^t2>#E+YU騲8:uՂVֵl쾣RHZfqc$""""N϶wkv^s^[Q=GG @tdcO-uTD6uGQ=[#༰tunwRD2Lcqd1IDDDDD-+ne/E$\Nvq8gX\k#]-\)3>ǎc\c^w4,:HgG*etfB'""""""] iy{Ea GDDDDDRzK#m_DAb%/}7\cRO!CgE' C""""""ۜ%tu ލSOy#Q9;Φq8xKDDDDDt?j;yKab8]i&tEXtCreation Time2022-10-14T16:01:10 CEST2%tEXtdate:create2022-10-14T14:09:43+00:00=%tEXtdate:modify2022-10-14T14:09:43+00:00q`tEXtSoftwaregnome-screenshot>IENDB`lxi-tools-2.7/images/lxi-gui-screenshot.png000066400000000000000000003774701447016333500210500ustar00rootroot00000000000000PNG  IHDR4+gAMA a cHRMz&u0`:pQ<bKGDtIME  0[#BIDATxw|[t,g aW[F KKiJ)-RV*3 8x=8!3>K^I9TazB!Bqa ;Qql/ǩXB!Bi=\v=?y/^qB!Bq;RX qGM'G %(!S!Bq9ڞc @;9#yeXB!BzAO}!k|G G[G!B!4~t$"{ Gwv]zB!pGMozj>4|H!B!ęx{R!B!N5c8x/uxhTw;a=@dO!{ Z&" #FeX5MVKBt#&&f :&!8~kq9[ I``Sk qd_CQ5tuT#FXקz<^/>@XBbcc ځnB3JBѠjt[nz*|J=Hu7:nW-Cv^/~wBX,nntB~?^ۍV ??222jO tcw/z[뱧9£0O8en s. ' B!N&>׋b;r7=lv= [ <cXKB% ' B!N6@ǃlNJZC0Dޓx2׊>(nx*t tsä.33sf[p8dB!B@ f-̜M/k/S>NO@r z:95cCDD. kҗ?Gؐ~OjփDV&݁nB!$p\DDD< 'XO0 t\#tמ?-ݯxǎ^K ̜SZ[[eNh6G琑[ nBS]w7fnx֬Y3M>|8~6ydFe{bb"SLᣏ>&qy^oc6HP?9Xp!:m -bƍ|t!)GŽ}UUqh@vҩFu1~@?9 -&&>SUUů~+l6@73ydƎ\6lX=묳S޽-[ C8EDDpW3w\RRRpFwEt~w.4>́Α TUIjZݰ}9gz=SLᮻ"##@ k Bh0͝;Rzz=Ӊn&m|jcQm^TNv#ӑOwB~sx%Iqry'ذap8|W\.y䑁nAV#SO=E %;wgݺu+1l>Ánioɒ%7vn}f4 ;cF#}a m^m)z+eۑ>&B SƏϧ~:OfQº m:m.u;G7Pw8HttHK!j1L]Icc#FQz/Ν;HJJS__MEE;w$++kz 5]bEàصk&L`رlܸq~Z?HqJ0&ł?.~Ҧ:.i_CY /UXQP =t,礴M+N]wujkkye]*1j5v999w)n XcOJR n#Wdd$@u7@ȪNLj駟JP,Fz^sM'^ohz[zoªW3sR;3nᨎo$?鄵uǎ??Cd0 ^/CPPP]7ntѿ:-裏vmh1Hq*;Cx衇:u*@͛7HKKcڴi3Ž;Xh/B\'''3vX<wf)x=I~hz"}c8z*IRevoO{ 'M/Yۢ%_b-j.2;bcc:#ٵkWcH@@l2~mΝKnn7Z[[KVVWfٲec_ZG}TWW~ze_BB/jeĉyf:ĠA{x駻h4_ VO{{@7wx}}q2e v?u… OhT*O<_5}Y}/f޼yOUM}cz[ƣwtMJ1,F V.jfd:>j9Vnn!ɦ`߭j㵭vBcø~05Nl(rTyѨsm,40$ZV {*\[{'n@o"ܤӫy~c;Uﯮ3fNj/ x_d 6niRSSy/ER… *|>}Qquבw݋^gԩq :J}فnA@SN;ݗz G Ѧ@ W_}}݇N㣏>#E^?q| O _79R@*X0rM?:ld/@YX-/_͝Mj `KӰxԈ( nffP `w][c֫wxU*0U E6x6 !_n> v}]fϞeyI&1i$zCCC@5k tOkv'`Μ9̙3m {ec? )۹ۏ!N9zX}*iŊw}@}ǟg%P=vS۹{m's,|l* VK p ._I%˭SͼpiM3.A3}LUC|?aXp5-j,y EnV Ͷ~f؎F,wtSnf0KG%@m?rʂ'W^yW^ye!za.]5\ܹsIMM񐟟ϊ+xwv?[|9gus=@_$r2́*zSM+V@Rq?ːx{w^ǧ 6S\\^m >V Jj/FEI6@U1Z*^*8׆Q{c,jojHF5NB!׋^qxzMG-ZМB䱶x;%d::8D2O\x{67N6y0`;z>s܃tw,M?#w{ykk&B5-ts?B!8~N9`[@˹Mp`{"ۤR7o^99?2_]Ic_8!zl>7+۔awL~&ݕ\߆ \a3wϴ0>9XJ{&{v Sɬ%66ttLvv6555|!B30raXѦjM@zۀgbŊ^86g*Z+}.Qv9ˡgw@?Bػロo}嗥'Pll@7ᄊbɒ%޽={ ts&h.m~/e0vX}Yz)>n= h4s:NZ[[MǹM65ke?/a[2WVy^}գ TSS/ /0g(Z7_|-[80?O?e˖-|'\s5$&&_}vlG}ĝwމN#55-[C;T*W]uo&˗/W_e̙, @BUbb"?3f@7%$$GqFnO~rsw0x~}wy}Bz{ ߏ8|A&L0YvIwNiӉח9¨Lq<>,>@7E>5kwu;w䭷bȐ!466Vyǘ?>vbʕwaժU̘1[oW_}5iL:n>#222hjjf.B7M9f:o_k())w#rrrXdo_~R΋3磵rV|>(tcGd!ę')) J7|K/5jse͚5'?T:55+{1f̘3:@&$$m6xN-M7Lrr2EEEz+wuyyyYfquבȾ}xg)++S??<n@?'k___gǎ<㤤Rزe O<9{x+WgӉZ!q:ҦئE !N k׮;3^ȑ#h4\V+ /DќŠ6mDcc#?xW⋕a?0@W_}/ȑ#ٺu+#==￟d~p222ؾ};|ƍ㪫⬳⬳>^`޽Jw_FUW]EFF?pݼ[ :h4O>z S|̮JV^c=Fcc#6l`Ȑ!<۷!Cشio&Mo&##'xϟ'>c[lnf6lׯgʕ,X˛oɈ#'`ڵ\qL8Ǝˆ xQGRRO>$??#kΐ!CXno'Oﴮ;#<ߌ'n^s[[[LiӉ#=BSBYYW\qW\q^x!?}xb/^L  ??_N7iTVVr]wq(=[C Nǟgv+ܾ};|,v%={6fBONMM dffyfVXyHIIaҤIt:^|Evڅb /$11Qy\{9{WXù{~֭[,X>VK PoE̙3=s)s^R111wh4rss⋹;3fLn7jKYm yf˖-ر+tvI ෿-۶mS ոnZ {{C 8wmjfΜxǎ7RPPaøy'z-KСCM&[o]Bsv;N}zx<\MHSAaCqL BpSNc޽fbbb(,,d2w\^|Erssjժ~' &l21DFFRRRΝ;2 fb;vqUWhd=niѣ9r$7ofĈdddA{ǎx^nV6m9CII hZ|>K,j{c>|8^z)YYY$''石i&.n&"""0LRYO~'|l"QTTNGɥ^ż;\x 6 zNʔ)Shll䣏>#MMM<#~y睴RSScGn{{=G?* {=&2m4~6o|TUIO5=?߿_,NJII կ|)B!O$@ !B! B!B!DB!B>)B!O$@ !B! B!B!DB!B>)B!O$@ !B! B!B!DB!B>)B!O$@ !B! B!B!DB!B>)B!O$@ !B! B!B!DB!B>)B!O$@ !B! B!B!DB!B>)B!O$@ !B! B!B!DB!B>)B!O$@ !B! B!B!DB!B>)B!O$@ !B! B!B!DB!B>)B!O$@ !B! B!B!DB!B>)B!O$@ !B! B!B!DB!B>)B!O$@ !B! B!B!D; 8  B!BСC Ǖ@ !B! B!B!DwXU~~uIII7\yBя"##7nN, Ǐ'!!nWqg~eFa\vePPP@ tJb\|L8ZZZۙf.R͛G[[MMM~FҥK7ozZ<*)StRO墱7O ˹㉍}z!j5UUUG|/R]]mSSSYp!i\\gѢEl6*++zݞkܹ\^zfN}F*++_\@z.=B!NZ:ӧ31ctگj׿5W\qE0\q}vW_ҥKٸq#cǎCHNNfڵ믓Zd2sٷo=SNEדٴi7x#_|16 ~%//zsBaι瞋`ଳ⭷bT^jh4#_iZcǐ!CˉbȐ!\qwj7ѣϧ4 :niWDG!#,, /Q|INNs7`رݞCryg&+K/MNNIIITTT( RfTTTpqF>3z\pj*qaZZZT*IMM%::T!*R>cyG3f INN.68ioo`0`ٰl]޻#""0477p84hvÉRz-z:G)g455)f3Ѵ؈FAv|h4 . χZh4t:Q$$$`0(--UzgCTѐHaa!6 FhiiwT'xȾ2aPs`[#FnJRRYVFng=Ȗ>#@hA `֬Yv^/[lh4vxp\ʷ|>< aB @ rEkk+^3grR]]Mll,/KryzIHHc֭h4*ƏO{{;鴶~zL&?T| (**b̝;@mm-TDdd$YYYޣZ-sK. ֭[ZfҤIC:׮]ƍ9s())aʕdeeX nvz).bRRRPT 4~ F͕W^IJJ {g{!22Fܹs袋:t"ʾœPW! swÔRSS?>O?4c`4o>PWWiBs&vI v m6뻜o̘1|2_1 Nʣ>JLL `׮]hZn?Jfƌp>IKKL8+¡C5jӦMt -[FFFСCs{$222(**bӦMDDDp72uT^{5=z4F⭷b֭~<sӧxb>S***fڵL&n7ӧO/`0x_GVcXXp!\p/ٳgsRYYw:NyEEE G(<&dZ.N1wP7ЭBVBBӧOg͚5466 {sxSTVߦSofhPxOd"''k< NۡNB޽{/[Mmm-SLj}kݺu̘1p  kjjp8a20L<\:nn+_ >I&1qD^/i&Nfcǎ$''3x`6l8/_ή]Xlw/2)))m۶Nn*JKKt:QT466HTTf͚5=hʖ-[L&fΜIzz:J7͛9t &&e˖U"XȾ8xYBBDzJJJXlddd|>HNNVT*Yn]|8N>#eUee%qqqJT*Ux:}a:VTT*V+^~gvh4n^/]tUUU<쳜s9\~dzk.JKK`p+..fҥ̘1zt:]+/(sٛfҤIoc63g+#b v؁$11Q94:l6Ovy:*b߆Ǒ5[kq{ n@T!NK999\ve{R∉gee}vƏT馛 ^Uдj*ϟd`…l޼6Ǝ_ο/8ͅ^HFF~)EEEVBxҥKIKK#??ÇԘ5k>^Ybȑ$$$PZZhh4@mm-͸nL&v>:1F~XnÈ#xc*++a֬YT*ZZZbgjjjzyq:hZyj4 ?عs'#GZ~_'0yd~bh4SOxHLLTz$_y|>wy'^cp:<!>K/+?ill$,,Z6oe-}Gqx^º *(~֬YÔ)S|?a `pBU~4~{9;|ĉ ʰq_`Tq<`]WOCmBFdc;STz, h4TUUu:Gtt@Ra0bBcc#. JСCaS\.1(kEFF*sە ~r\222RN"'J7ߏjU -eTf3jZPNxx8^Wp8 `vЀnGf#ڊn`0p`0֦U -xhnnFRa4SdR` <f/III8N `С' g۶m3fx;{''tC%@ecC1} #̳!mJBLRusFe^%CQZ鋰q\h$t}4S{t 2/{ /}!j|̳AoG#g]9^tuo[ #xOg /=P7"yAp=B!IM(<p8sAHB!Br$@d2X3Hѷ9+~C0D.C(D(B!Bos/ka5`LJJrOrxUV 6ܷC{4APJ1 A[ dRHLLdĈ466zQT$%%1o<233>|8w:VV 8묳"ϧ ŋ9묳l+ /fΜ9f*++ŋ0a2e ǏgĈdff`ǃJb„ ze_L2FSS>3|pT*U̜9c2hjj(ONNS錌 q\8N5kgu477wV:|p͛Gjj*cZf޼y 6 ˥TGV1 4eYNGzz:cƌyѣ V˸qXp!ǏuY#&d4|pѹ0sB?z]B1~$h}j\cȜBXq-&^\` nSB ꋡ/-BZXX{aȐ!l۶6t:ƍ/.RՒDBB5559 .+W*X,|\ylܸNPT9^Oee% .dĈرSO=Ekk+EEE,ZD8~3x

JEJJ <h4n&vڅ`„ p8ikkH9 ekGG}`®=>Lx~c¼{V͇m0B3frb FF=Z:kn른j<555CexbaҤIlذfظq#gu@@t:H̟?+Wx<{EѰy.}'..N0h"vEyy9@@ !*++ꫯ袋x饗*X% 4qa6ٽ{7f<֭cɒ%$$$PRRȑ#ٰaT*juQFDII F+_v;Fɤ|8h ju(?Y,V2-rpXV}c|嗝8t:'~?DEER$%%>Á~y@_ƒV`o=8Q ^o'0oc+`ӐTBvX{<i BҘ~Fxؾ};O>$:_|YYYL6 ζm: kRT$$$l2s?OC˧~Jnnn \~+J1SRTT;v,Ǐ2ߧ￟C;}X #99Nߚ !ĉyw7n R fvNZ222=z4N'eee@VVv:jzVQ}y())!0m4ycϞ=***p8zt:NT9:xk׮%??˅b!11+WrAj5IIIBLL ?||22-- CEEN\PՄNUU^j1L57xCiTTL>O>~:g@ ʕ+Yp!C?#)."*++),,Tz CCX}>6lPXf \.Z-:T/^Lyy9ׯW\aa!f"--;wFNǂ cʕy}U[[Kcc#cƌO?d2A}}}Q(!z|>iii 4O>frrr;w.yyyFNի;O gfq`C/І`LwATZpI|Ĥ}r8 -ݟ/"W@ౡy()8EGG+U f|vMTT^z)W_}ks=$&MfϞ=|ʲ6zTA|XXcilljB~1~xݫ1L4PWW'66dF#cmm-6 Jmm- Z-vмŽwaZIIIjz|{g[[UUU-f"##q8JDJJ |>)**RWj5DFFrn9d N+3 60<`2TߺnC8<Lt߯z{jQx<``hXPom E2aπA0 P-ػ8|.DB'9\v#d {Wt #R` 0:HTP; ]!B!@gN`\mYI=9a0`,[CXe00j>1x.k,hP'8_\p)0`EPx)Q!⌣>|8;v7\.[lQ?hdƌfmFuu2_h42a㩫c˖-8Nt:&L 11rrrrp8vzƎK\\+U]9r$~.틍E&ÇFuu5yyyNFF@pRʈaԨQXV6Yf1k,pvn7Cb`4&**|L&SLϧۍ墶xnf۱Z۷O :e˖quױyN$Ծh4RYY2se+~:RsCrQpOA.[0'ap@s*󾄲JKnV:&C{}끯`Pǩ7k B!gp.B^~e˩;?oV+f";;+Wv:ܹsjlڴ Ebb"K.+]tv͛7S[[FrƔ)Sx饗ؿ?vs9m۶Ԥ;6l@II ZI&QYYɂ azzFP&$$IKKcϞ=x^HMM2diiihؽ{7ٳIOOv%K0e/_ΰaØ |r8sٻw/^׋lfڴin6n܈` !!K /VIHH`̙T*f@ +@7`T,4*8v)‚=s SD0{5^P yJ 3VA`Oy`~7mxgH!B`!;wR[[޽{ijj"33CQQ c2ns=իWS^^Nuu5|sA׳dKhooχAףjikk#66NӧOPUU_MJJ YYYDGGSZZJii)(eIhiia͚5DDD  vNUn***hmmV1|>T*zQرAss3mmmnM Z8op8455҂baʔ)Y JJJXr% ,CW NȐ``EU%9^ VMmr> /¡fMǬE ط"8d{7h& ԙSϣG!B3N#66S|͛:t(wIII撗<Æ XXYYI\\jsLTTeee|ᇴ . .z>NORRRUc6IIIvw $''cZ1dddP\\ڵkK̤lgo~***Xj q!''ݻwύ7ވO?LBBYYY\wuz^/_~%$$$xbFדHzz:_=Nss3)))*G]]hZX,YF 32:~&X& !r`T =u҃Ataڐ%=yQzB!aT*z^)-`V 477Kyy9$$$t9`S h4 eǎ̟?AjX,T*HJJ"11Nz@ tw_JСꨫrGXX* @kk+QQQb0:=^W9gvIII!..VZ{V墋.СC FFASUUž}ɡݾ&Oƅ^ȻヒC1̙R/"!D i( myHC=ςwY*):>HsK0<B!D0(C>j56*|ܹnŋsu:O}}=111TVVX,466p\|7TWWIIIh4x)((`,]| s777c6tnL&vzmV+δi6lfcǒn'##^OZZk׮e1c2i$|>lٲ<ɓ'k`̜9:(//gݺuj4 ^z)j֭[Ǯ];w.-/:֮]J.@ &T*F#L2)SPZZ5j^z)@={Nuܥ2jz6\l >· `͟a;3Øa═ Vp4>v ^(B!x+VPhZeI]vt:ILLv+\[ZZ5B 9x aaaۉVڡJh6 XV\. #Ͷ6gڴi@w7;; 6P\\s=G~~>NEN7Q`{ÂCڤ`5UW/kxp`U2z0X@VokDBφWCg%< !BACQ\\Lll,6l#G2qD$&&oR?>>YfX,DDDp8fjelbb"o`߾}@p%Ki&e[Hjt-{j |A*ז̘j*7c B!PVVT$믿ɤsNvbvo>|>8p۶mR^^,֦Tkmhhprp:n:;kkk ǃᠨ;wDuu5Gm6 QTTVVRTTԩN[[:tF|>vFv́p8RYYikkG{{;%%%رCZ__F6oL f)KQQk׮pt:T,--e͚5vp8|>ٷowڵPXXi> 0t ߅ж1¨8qJ 㳿b8˂=@p_Id*Luӂro0?P)<_4T|)$@j_>8-Kpt=X%Q!Bqjy$C下 iaN!R Bd2TB!t!/烗C!2)Q!BqWU{amw!G \\ O£B!8-l6222P*~Wb0h "##MJJ III:DMM21..tj5TWWw) b0S^^ib!::I]]ѤvMhdȐ!L&jkk)((bXʢw:VR)U*yyy477VIMM%55JEQQi2GUY2@o``L_(B!N < Brr2vY`iiiL&T* t:233IHH 66ct:a̘1bbb6l^?;5+JNN]2n8.t:$%%1zh&33QFqbbb9r$ :dOdd$CՒ_RŲe˰Z1yd zL<"""1c )ǟnxO9U!X5} H£B!8mٵksQz,X@BByyy_cx<7߰i&RSSBsYgmزe  bwll,#GdѤwڗBvv6 2Omm-;wdΝFRRNFvijjb…X,.VZF&L@JJ [neǎr9)))aƍlܸJŹ;/U!Ǣ|wN (NPx^R!B@UwkT*n7* ѣYbn^2 ;ܬ444hmmvIFѣX,l߾#Fزe QQQ~ill !!ijjϟƌ3p\2c j|'s=۷Oy4vEYY111l6&NHdd$CgZZZHIIa 4OAAn72|:^/ l۶}fddơCp8$&&* BJJ ;v ..dddkuڮj18ۉq޼ydffzj  СC@pɊ bdbbbHJJ?@LJ~1(Q!Bt:6f2=@ȹ˰aÔ&8, F&''3h VR\'b0f^/;vT`'66#Fž={moXXIIIRVVlWT$$$0n8֭[Voƌ5/͛7R0Jh Vsdd2 ԯ DZ|G!Bqڴi۷o'33޽Zꫯغu+:'|DT*<;2f̘^`0pg3m4jkkioo=Ǐ1g&MDTT&M"&&3fPPPŋ?~U*̞=͗_~<>VK\\B~?l6PTzDFFdnn:/U|J£B!8y<  1XVj5ZǃU TWWS]]N#""CRSSٸq#%%%f#,, MAADDD`61fZZZϧp, FQt$$$`68gz=~iHohkk/&,, ?z#F(!5رc+B!BQvv6z"##F ;v,&pjjj(++#%%EYbΝ;xbqqqR8shoogŊ)mp\$%%f6l ,ZAqF dRRӈ/^… Yz5&MvSRRBCC>CUW]%\9pݨjx gʔ)|>V+w藪_IB!BQxx8IIIz ~!EEE>f͚Ebb"ZRSS#<<]زe uuu['磸[p8jÎ8TPRXXTY``yy96VbΝ|>p\444P^^NNNMMMo2sLeerr2)))8Nۉ$!!Z^{o_~ .CpXöuUͷ^8qи` G!B!Nkb2~ǣ,V1xR0slNN!B!B!8z v淋ꓲgGq)Bq #;;n;rrr9mtTo9Nvv iiiXr---u;WO)Bq h4~OsssaÆaَ0^OUU7;DDDrv⩧vޡ}!R!j4t:)--񔐐@EERAr՞S- 3gdΜ9'zHqΌB!)D\\>GCCV_f׮]eȩj=aCWu:QQQvNhMÎ;z]NRɄ NXęIB!)JVFLLL}%#^Odd Y[[h42rHimm=f3---lܸ޹n祗^_6jロBNB!)JdQWWGIII>fF,,6oNII FT*N˅Nd2)ے=!m RQQAss3G}}}={EѐbS$@ !'VTt\> T*ZJ:Nvw9Fh4ŲnQF`vvB7]?6h4HDD>F}^"##`0Nmm-N@ @DD@ ˢ6 JKK mmm߫T*, qqq]v;%%%}Y;N'EEE߫*dT*EEE466Grr2jv ke߾}]vM6_ OS{ohf)ř:DDD(pMMM>*JM #@mmmpoaJ` 66Z----TVVv6NGbb"|>jkkOx/HBqtddd`6),,fHRRF***:LٮRZl&HEEQ}X }>|8@z',,^ϧ|x9r$F9墹c.ĬY3gx^6ow*++ۅ1zhONff&aaaTWWeV\IMM sǏWNII v)S9s&_}k֬9n'jmPcyy Ot:),,={xTϟϔ)SHNN\͛7ժ jnnfݺu[g֬Y̝; L&eeeZիWS^^f1w\ΝK\\>NʝwIKKq 9rE}}@0`\~+>S[[ˮ]i֭Z=7nUu4iܾ?|:Ə?%%%%quV޷ꫯz=1cX`aaa8N"##ꪫ?>ox1b7p-L7ݓD;Ovh6h4]>Dl6F#mmmzDDDKMMM\?   Ad޽ףV ?{^JJJزe-:׈.ꫯ=fn@ @XXfbرueaÆq7RUU<ƍxɲexר">>n@ wͮ]szNe BPCCCSqFl6zWcc#FG[͘hlldϞ=)XJ͹544}v-Z)))v~hO:,Ξ={v|:kT~_o(aqq1Bᠥ{LMFVVVԣd42drtRPPЯs CCU*fqTz|>aaa]¨pW555ʿPc֭s8hР~{NfK/ƌ3]jjjzOKJJ:]/--es9)@4SRRByyydcccs477avE|| mmmuY=ޮ=6 =ݎFVe :>. RSS!^dOVdp(_y3z51B!Diiinl,""BCCC mmm*vzj4ZJa@۷o瓙pl"##ٴiI]mQa4mXOSS?2SRR)))XV:t(Æ cذadddhDc4aРA 6 ͦTxf .R***z3@ !'!Kss3III]A>|v***'..XCQGFł<抦 خkhh8лn:mŋyٺukÆ #,,cZ"--8JKKȆS 槅=-f0”Ӥ#h$..H{{q]Tk̙JQQ{Z !&c())Qj&NHVV˗/ol6dqNVKRR bJbMM *F׿5?~<ټS=$@ !':fZZZh4)kvDCSSuuu5X***&4$ᱣFRc*=z4^mmm,+WOxx8:>]"-- e]СCy뭷ؿq}^;r8>8T*IKKS\.JJJ9G﫵ݻwcZ?~<&jvI^^VbdذaF˂r8?^g"tsssٱc nOV8pLBoϓO `ժUL&^2p#F`„ SVW_yx_ί 4i 4={|:OJ {ܿh555x<ӉT昕S]]M{{;uuuX,P8҃)N^۷o'''6f3'O[o?%%%KRWW?cX8s7no&| $7ߐeɐP)dzƎ_Lnn.OVc4q\bە̙×_~yFύ)BB㢣X,J/bסsuuuՑA|||^FχESx<:͛w8jDEE)Z<Ⱦ}W(..?)?桇b|״z\Ef1l0imm7䭷b߾}9=@\\& Oss3?n=vǃW% 4^2hMﲡ:N'6 4ߩjf3>ϧjjN'fYn0hooW^{ǣËCuF?9ӧOgʕ޽,\+˻X,&N^gӦMt:z}%NGRΕW^ o뫮z?,]ngyk͛7d#R!8IHNNfa0FSI]]iiiDGGwY_/Tfux<~, r|>O~,X={P]]$==z3uuu<#)FRZ$$$RKKKO;J"*z=.KR"##, SLFƎ֭[4h 6pym6j5ǏϦBfϞͺuHNN&99a'ž={P*Irr2]vwcݺuʾLL.ZĠA0L9lv56 p;o*j5{%77z:ill䷿-w}7^{=M !'Zۉ&22JKKK PSSCttt"6L&1-q"7XV\I}}=frrrhjjb„ }^{4t:фv)++c߾}%ӉV\.Z[[ihhPzcbbp444O)**%K0n8~FW^mFTT/2e 3fGjrws3x`~_\c/_86hzz:<O>$կXx1III\wu\`00}tn6v_NQF#Æ d2+_X|9L8Nw)BBk=őbOY4 >u\#::֥L`Xh4477xرc̚5ѣGwCVO%Of3 TWW9IDATׯ=U(UVVt:$''KQQ^SS`ȑfnXZL Á:UR c|t:9-[F~~>TG4,Ws%pB^x>sedR*V{<4 #G[oEKq|bevhYаٓD)Bļ^/$$$FO!P[[KCC]*qSVVFRR#Gd޽7:/K| ex$-]0nJSS---|駌9nflقh4FUU1-BWhnnzy)܅餺^Ojj*cǎ444Qdee^'0vXhnntDxxySTF?{um+A{E(QE_8^Q'8%YWPb{/ @{XlߝŎA.\X`ٝ\.~ǃF$|\dvp:~ s6gZӱfzl6lœ9sطo퓿c֭&Z^z-nv6nȅ 橧ݻw{x,#'##}k,[ JQQ_\,k> X藿%n:~x'hhh෿~Fa@ @pIKK :!l0^NЀNҡMNN6 ZfOOϤô^/]]]1>OIꚲ̟Zblpn>#~ӟRVV&/gHYY{/˖-cv9"pqMMM 8( ˆ/NyO˥sYyb111c,Ypo>.\@cc#{ӧO`֢Rؾ};S__O{{;;v젵sEr|eee444 jN6l ov;:E/vuuqEL&k׮O9je@ @kk+eeeC:u NGaar†hO=wqw}7~~ӟ^ŵ z :A wG5[=:۲pӑKQ^^>Q O=dc~yXZv*RL&( :;;cFΓxQ*(q( cQդFQQѴnݺN>=%UV9{옭jL9rq\]q˖ {9-[Ç)oͯ~+Νݻy衇ƭ0< Bn^z5 ᄅjh +IҐ1ژc- VMSSe}g̘qYJX,:ujߠ߁ׁA?Ҡ ;Zx @  cm]ͱ:O*+b$MyNF)dSa@O| uz&Nc>|x2&cd{^:::&y\4˽{=mtvv^ST)@pP(P8N5/j텅QWWu  \d+Z €@ pL{cYY&iJ[ltvvP}VOv*P@0€@ U!\oL0 3 ,=ߣ|3@ L ~>C^Jax3g@t`j 85ȥd'aoO0@p"\[@ @ €@ cj;V"@ &@p" H AjJ2ƦI5`$R466a ]7€|*T*yvJ~fxN"#_bBR@B"3@p2"HW6bccK/S|D'l!59A3USATi̟Rqeb/!QQYŶ7TTHKk+58Z@ $R a BMֳ`z$I@ Rӯa,ߏ˾3m7%KhʑZ~/F%N{OP̗??z{<}o?a&>CKU;6B'RSR(,*bHOhSVQIlL #^gX9xd:tEB`fVw¢"vGB;&+yx^Jt撒38N_͛{{!z7 4*3Ǜ{ ?_X?4~g=^dU;m7+{&牯`6?x7YPE4jj  #.6Ʀ!tʞENm]ݔ닟{۶ނF=GP &:+_b4HMIA0;gw/MM͜8uQx<1mZɞI}}uWVzHJLh>ݴa=z^}̌t6_K]}3Xr9(:|e~M4N&ҳ1|aFGMߓt&|:w@c}-zQ95c_b ~S^|OtEDRDeu5aa4d:9q}}-hk$-:u:RSSiA][8y5u)fX=ƦfkSYU&91шlXKFzZ*6n͌ V\R#\,"InxB=.%[K10$d4wxju)%G9I#\1f?o7N۱iZfr2}_{},puOO Xv b@*J,X-?>e6,;wL^,q~n< V!9)[ts8|8{9kjfnNJʪ*<DFFb3̤s)"$~>.Xcl}O/p@ 1E7p(", Mg JO?ވT1F$ IDѐ3++WcnWGooN̟;wT* #O$$0o\ z˅t%<|h4$?/Ǐ?>OEe՘̙5 Jԕ]nAXXZLZZ[y/qDB|>ᅬK͙{s狯ڵrC"7jX/:ŭ>-^?XOa {P(޺QQΡ*==<]E ض}^''gNL ϞFDfFI<}ʢ 0::()-c=~Ҳ2zƩQkȞ9MuM-NgpVLάYآQX-/@mm-%/qzrfegm6Ÿhmk=_:r2$܈H5H(D"Ǐ@tb> m{%|HZ#= ƕp>7 7֪zQΦUWzz9~4}'K/?v)[ѹs;h4QHO'%9Sg cтf$I9v\֕ J ^/U58v~[Z 5x}>Ξ htuus|1Mͼcp[i0 A1^T|YkY(*{gX%oTڈiPw&`j9rB /w #˗,rMi^qu;`˦ӿ%))р ʱcTWۋ!0] #--v,_[WH`T(.)ayV %}>Ξw{;o n>P) H@pMpC}n t }8y`n?~"|_lD.׏d4cQ@SsID__eDEF'/o0;'ll3rn OI3VzXx~;ЀaтꦾZvۣ݃mR[W;&R?R \(<R8>δ%83ۂFc1tPz񎴏M[JGk2>SU;>шfunsH^ϼshЧߏLLHJbBm{ n̟AGںzvZͻ|HMm-nvsaL++6 n% JbTHlt (@Hc@LοƟZٌ@Ww7徻bEJ##7߾j5~plZZhmk 驩[ZEb>C?G^/>O~W{+'&O>'HnB ) Ta(~{Fms jRZ psi,_.yv{سwߧ:dB o!L$%p9=ɶvP^Q|~BWu m@d]2'AC-~?Z`uYKSS3}Q1MX޾>N:QӑXl)ygDžTUא% l_f#u%66RI{{;BW m@ܗhN1'˼kewݬ]w`6_`pg)[Ee̚KY8>iX-+K/͜9y򫴵+\|dlh;:him3D njUZ1o4W Rc^t-pdĝ\VN:C5kxF tPrѨ5\.v U?0++˖pAPW+ߗ_!kF&sko:=w~lQtvuڊCLL ހ\|/޶6eˡ`,37{;<7s!/Z~wףjIKKjrqɂVXDEeMS>6G__vN. .6XG;wzIHHȱՏk:VZn">51Y8ftqŕOt&J]9snP{ }}^KR8 7:>S?6 wKWyںzZ-)DFF%I'OvJ~?U4 HJJKK+' k#3#KپsĄ?Auu͕JM[[;BW o@jU_^lfo3n 5iW xQP4jh#K^%UMOX$yl;`Um H8-7o~Hx$Ir^9p0ήP{GccӨEv`*jsno`1C~>$ Ib  (\hzPw]7Q1c ȔslTTV̳foc B% cݳo?nLzZ*{jJ A+)465seހ+Ln%NJ¢`5Ы%)3C;f SK^^Q陙z<],YeK`XɓsA}OtcگB %95W mf͜Va*UJRSO K[[!5X;q.JO? I%5Й:n>kcĐB;ٷП43WL^BYG6^3߿!-`%DXtuuueP]q8?xg}}|se;9)5V^"t%';'R$55%|ʶy)^`ȭ@ L3€0iJ~hrc3RS( 4ru"LgqWCuM x/* ߏ (I C>Fn˗ H DUu5^T[XvjKƟ_zSۇ@ zj=~c$`0`~A `ЇUO Z[ZxϾqu9+vu+GCBh0R]S{Q-[lfU?E]?C & z Z1oŠC?סߖ !OtOߞGSu-P(٢Z,\,pzEeУ"#X,rOGWw7]# J\cKvVtclXS+V˯qbjCgWק/@0AB, NZ~7w`u`Џ4'7H#ImO61+ ڦ-X{R]좳StCO%+@0|F: @ F@ @ €@ 98w,y }#qL]6c!7 9CRykk@ :^ ~e!*@  ! H@ @ La@ @ `BR @ B@ @ €@ @ @ &0 @ @0!=sO@p7@1C3g@{vG R/ga@ Wf̘L)"U @ B@ @ €@ @ @ &0 @ @0!)@  ! H@ @ La@ @ `B{@iMt|tR_QwL UqS[V<9D'XPy1rq),=ܫ롦tcZ@ b 9øUNȀ'7ýj€W1,ӕ 1DOp5 E@ @ &0 @ @0!)@  ! H@ @ LQDG .APjѨUx<^<^/ %HOrST\¹R|> NZzP@p  ׋KxsHvs"g/\uEӢ"@  XLFu M56$a clZ ^RJ~?̴TlQ؂?݇&i@PhZIl4RD]CIffl^>;%e>:ڢhimY`@  ב̼gdV9^PHNwOTJbXt2inmΜ+$M! *:i)IA]DpL!}vRE|K5-U`@ (M&sٸf%x>|~?͔VTb2i4T`1 $=X4/$2SCk{'oP WH^L6YIRB^O]C3 L&#Z ]Q(t+)HO%:"Z; a@ @ VAGi,]00qآj i)I,?¹$%ģjAPt@  $YA]1$;HW4j5)I,^0Ǣy$tPU~+iEE(bԁ@~eՔVTi%d"&:U;k&fXM^_Ւ;k&H~?q16=@n/P[ RIaG@e8UTq&lQQ\ٳ0F2 fgg#>Ɔ` M T7 ]L+€7$ ^OdREgw7NJ+hDӑ@rb b6T*%ёDEX$ BBrBIY]=h4,f",zwv3BLkRtJYe21tZIN+J%QD^+nVJ*AQc #j6+0  F!9)% f6q:T*%*@ 40{_JH$@"8jbZ͞AZr2+*9p]=} &Mل-: ^?2.{O"JP`6=znw[H 60.VTRY]B@T/KW$ RVCd%YY$SZQŁ#u<c4+twL^WL&bl銏q >ACT` #oL֮XJBVFeոnf *2"4IsXYp>ɉ $Œ3sHblQ76a $%ijyjRF|QYSˁ#'$^P` gydTh0]سgNB%,YYY+YiVTt~ٺ֨IJJb|< q1Ξ-*M]ǦuIKN}GemoRB <<% 撗-^Jgw;DAta@ Z-:i$b23HNFX_@ !IACTVV<jbXh>03a( RHY-d|UVst!] H}v[Y4osssT& s}*`j[T$Y$b6 3In&<,lZR]QEGtյ8SDe$>6͛ü#JskgO@ P(*^/v;ZN.Z;С@ 墣v~t:-V+h"4jZ&:2"#P(H颧O~륺mQ{'#Iݽ9qχFfVVaG@pP*PTx}^vtZ-:[Ԑ\@E{GZ"#tbA+*0]q\ ϐx^ضk WIޠ̜!te |>zRRRHOObP(顶jǔd2MBBaaax^|BP*̘1 , JN)**c#99Ll6jNKK ϟpLx;oFFɄꢪ:nj$&&Idd$JꨮnOɵ|:|>ZZ9~,R 3|~{z(܅R*kc鈍&{FyIJhPIYe5EK(*.OÔasc\8I آE3݇l6Dbb"  FJKKikk}( f3)))ZN 째ii4bR477S]]Mgg0mPTőNLL F륣MQd"==d, @nYW\.׸Ixx8TTTPSS3ec|:|~[t,R3~{zJU ]=|~z-]&91aT]iDW /?5υ~'qdG8._ qBWa@^dzfnfΝKll,JVΝ;Ǯ]سg555ZMrr27of˖-̜9hn79s{;Ca0<7rm`bbbPT466RVV;Ν;|8h4^n%KN*oΎ;\1qF6mٳl|>ZZZ8}4;wdVX͛Yh (J(..fϞ=޽qʕ+h4vu0֮]dB$عs+ bbbXfl~G}>+~:)8{6Z۸iJrf6CK9FIY]=x<JX6֭\FVfڰ< w:z?;*00TT*LF)/tƍYt)f">>pyR{cΝ;wYzٳgsM71o#G>xbbbXr%Z~uyĺu0Hnv1 ڵkQ*GM麟3iikkW5LWz(Е tvu%F]Ytq{PVUMggMẄ́iikR]1 j3OHŠߗG9}BB—'əj:;;$I"==|V^$I:ujT[n韸뮻HLLr!''իW,JNN_27ʕ+1 hHMMeɒ%̞=Q=u]|{c֭DEEt:|$&&`ϟR14g~0|8wnT?pr7믿qyZͪUo~íJ||<ʤJ5aW(T*|~?N FMfZ*I T$ Mye5B;T@ 㡻ܗ ^gri:`OoWsm% {m)LIm;91آ"z#$zR{e5VTذjmH- KoBZObʫ&7yyi?BP`Fr.5wCVXADD>ǃN#22L-ZDjj*---TVVNzaaay;yyyFx<Fl6xT*.]~o1w\L&== ʜ9sHII^9Gnv\.J%/^L~~>TVVNC8III<|fFjT/^Lnn.Jrr2wúuPմ#Iiii,Y<)--~b> ,aL=))?񏲮̙3^{mTV*Xgy[ȫzfKZMfzVA]8z ԕ>:{0u$ s:vnӕ*<# Im;)!DGzeUgU)Ul]E~rnrh<ސM SVY=m}>&ldd䄖Jz=MMM.}`[L^cz6oWUrrrbϞ=?J%d|_~Ba{'@VSTTijjj2o<֯_ٳwKqq1G?!455oRZZV%''n8~PVVk6, ://G,\~HAAD6mĬY?OCC=P+ă>E9{,{… Yj<jFêUW¼y󨫫c޽9sG^^k׮e̙|s~z|M?deeJf1k,3HOOT*̞=D SQZIM V|HO%2:$( Ir ii̹ daA?ՅJ")!Y3i~%}*. GUmg/kcnl"V/_cǞTOT*"j7oXClL4n*Ε=#,ƧB-+**T:;;_WWTTTPWWGcc#v]^gժU˓O>Iee%tth#55ϳg,XիW3{l»;d?;3'x$Ο?϶m8wfkײayǨ`߾}c`ȥ3GިT*R$==}Ts4440XXHKN@0#=Ku%7+וΜ+fFzV uE"1>vHH0ݧ|Ts"hj gղEx}^ںIy"J%1Q[-cPVYCQ9LX0yywMnn.ЗdOmƁ8~գj5|_h4R^^~3ٓR1c?яxGIKKB ""}{t:&&z) O=۷o%V(Zw%V)((HIIgtww; ; pJUUO?4*]]]y}Ǽyزe gΜ̝wŋ⭷?˗%omơCރ顬իWc2HKKuYNGzz>Nǜ9sF5 U*s5Xn$2Ry;`QKX1!~:{zs|磡zrsjDZ-8^4 }>U5|{Ne~~.Q_JGQUS7!#RTkcl^xNJ*`ǜ9wlȈ>O2x!''o~<#f,Y7oIvsq~PRR2$Q2w\z).f3~;>,O-׿un~?.@IKH.5</hZyGxꩧHHH ;;[r&u{%==jy^~eYfΜɓO><ܹsٲe O7ow}7iii3?Y,:x ~z9spwp1'Ck׮h4>Z!^c$R%<t:'1hhjܜ YDX,8\N ף壏qDq1=^%:2u+Rp^*k'+q1lX7!9)ŲJ>عgϑ7k&D-jOu5|*( VX%K8poƐ:|M:B ''5kLj?,]v;wMMM VXAff JEvv6ׯs~_ M?9.\@$?>*'籱lݺN'{0ǫq8rnhDP*zdeexwٶml<\xW^ysΡP(XlsEl2T*O7W_v È6m4fnHv>EF|$I^gc{^^nD"#X`Kc|fdf6 Y&XIOo/n Iw:R :*ٳ.?gm^kx^jxonv;H}c3 {qTڸynZOJR"q+ͤ$q{(*.>d㴶s)xw%eW}# y;wW^y`D&ݫN$:::8vذ"93g_J~/ww)!_"@bnHtKuu3ĉf""&71T*ٲe f" ---W_BҥK?Veҥ,Y޽{yw\pm۶ގb!??1Å A#B˹#a03g]tsH( 必EQW$N'ݽ}ӕ建{ ёΖd> ;y|{& rd}v;q166[m74!] F,箭IOMp"o{'N_>Bi9n+B3gG?gΜQ4/\Ç$$$h~Y~=ͼ{üy^ [l"o0غu+JÛo9bn^z%Y!M苴sN|>z-Y7mDTg"##!""^=J}};ƹsdff2sLtz=٤x8}Y^^Α#Gp\DFFEX}}}CDGGdbܹx^p8t:y&x$Zx~JnGzPZ-:O9v-֐Z5rт!ak W]8sC̹b1`|8y$gc0t^*JKKxG1L|>y $X:$kVbb␈ҕH8v؈Ў?NQQ@ fΜ)+>>,f3={!|>***(** .slPTXQuh42||>8ZCR4]M &+ϲwC:vRzPV]{8Ux~%KeZR9lu'aU}7' e]q{wS0a@^CJ:BדDBB„ʹtR$IǏn@x  Aٵkרܽ{|曇qk.N8uH󉈈ӳ7\Q*0b"voo/ !э%==Hss3#6z<hhh@R0s{)^vyh42\.OZMBBˆ{ (, $0e_w'7RD{gװGB^l2ьX>lFڨX$ZZ]bʹ rM⋲8adܼ~ #n/*Ke:9lR۾c q\r?;8wzSn#2 z~ H]`[1IWɑ+p_xFz{{1Ct%##3fxQ]]l@FFF:BJhzncRHLLSWVЕKTW:G(u:L&0 BNlCA]qѕQWZ8{!nsJyo?]HOo/ё_4 F^šKure}7GO+'.RU;z|pD5DrrlVUUY ZOgZ&22Պ磭mNSέS$%%ɍkC-Ip:cVx+))ɢjq8rZF$Μ93jhZSS===\f3VZ=<3fկΟ??f)F9T(&&hHHH >>Xuvmmm="SSS)((qYId/d~~>f,=:d9RIXXqqqtwwsQ<gd2DYJ`* J%~SN{njyͿAOHjRϑ (U*,pcsXRa")>a7SZQ͉g/tl1^҅EE?;jcq}7Ng#I)^{<ˮJ:!#+'q0J?~̖JW`N?W3f̐#ayH[[V͆fhbbG=ny$Ivjjj3g&3gƒϷl&>>^qb4INN=ƃDT"I@m} ]ѐsIMDWTJ%0㰆ims+*H@j:CwzRѕtͲE󉎊$ov6/P]70`d9HLVCƣЕCl!9z2x8d@N({N#n~?*pz=(aoo\.t:Zzzz0l6J%.Kn1>>y,h X, hW=gmcbbd3..lWWWטbz{{*zc|V%99NرcH0۩iɝERB) g[Ti5jz#,a̜AfZ*zGiEբ_^_l^mrr2VcJOO+6M6:ՊJ3gFF#ͱc=Z Pa6I8tui|4sA +g 1!OtETa0kf&eUqFו0393g0#=åSVYŞiJIy EPWR8yQtEDX,xaaAgX!L΀4r()qw<A{{;)))( ~ܯj4~?===rxjkkeodx<Ϙ Jj$%%<Ď1m:;;弘zɭ6z{{4k&7> y #;;[0LrjHNcѢECgF zh:* IdW( 2Xpچ`O$ RVb 'oL.KB|̐<_hj&==}89nJ.a A;]t^4(#8qr9z0xUh4̙3{FQW!U(̛79dLp$d]S:;;e=lrk8t~Tt~\.^FAьk@9s~̬YhdܹAVŋy7]e˖A}>k q ]IOc٢;Tp F5bbX^AC=AGg~IԠ\z! kPIȠr:c\.Y4̈́ hZzG,|3χl6ak(OeCtEьXMRw\x?1 F8fe17o6#ꊒH+ERPTLum}vs@td33t%{p]Qub9q]9ws~$.=1CL# kRZg#礌pJ5jKQT!8B JR ˌМP`oy!8 Z01yh4~ƫdz囯FjyJ7QJgg'60҆4 ̚5 MYY@Nuu5f"##V;Od"99@ @MM̈́7 j8V/[̲EHCgFѐh$%1:{zblѤ%'kàyXo/-9#g#HIJJ Z~*ym}wG^( TJ%GӨT*曹ETVVss<)#rƍƢT*`RKz҄'%%3gcǎa5xczJ(hwp/ʺRUUENNΈ*&IBW֨IЕ$%ax޹TW4 q1MF^G-DccFRIjR" )Ir서g/|!dh}>߸FJ(h4lI(s(J(((s F̙3ټy\_\ݟΦvH˿ Jg4B^'55\hȤ$Ir?9sdr˺v9urzLMM|}233eϭȫBJRBPW~?N7\WT*p&cDuDW,a$c(tEpm<J3lL Σ~B"Y7#-n޿\Ɇ\T Ӊ|^C) j|c;шrƤFEJR)h줦N9=+յ#fksBPWB-ܞ'tEpk%C38T!!F`s0B1p o<uVW 嚐D`C1v4xqe.0QcKe69s&J@ ` 33S U[uݜ={vH!? ЁF͹آS|  c6HC55u=xbm%=% %VTrO@0T*VXފV;v z= , O?={d_?Çs9rssYhF|+^HF ॗ^dy)q]]tay/׿unvjkkCj3*3ԑn `Nvv+z3fȭBx(**B$4 />|r@LL?s.MT2.Y07ت+)aA]k`UT3+i)PJiyUC@@6VB":2X^+!9\ $X .j1x 2 Cᦡ:ryuݲHɐ;6?,&:Jn7:L&}}}pBm(oʹ:%KS,^I荊㡼ۍF̤$۠s*?LR@nwFeu-54cή %Dkt1tX,aH))nf,XdϞ=0U(Jk, }}}ڵz˟f /0|J%[lJ{eٲezx/+\7~\g}ϭފf#!!Dv;x~***d]ILLl6ۋdbѢE~:::"B>o*yҥK +=TTxiCDJRetFAW0t+:kxJr{gЕOa@^#~?@`HhA?V~_PұP*~$I=~uB1H ޏsK_$>:N6\.ׄ<{ V+{e>8;S&5nhh ##0)**+\.***]jfϞMff&χ` %%OQQg*ە 3,X"XPMdԤD"#"P*~ntZ-F]$\n7'ɄѠGQCjr"5QU[O]c3R -Ͽ-* đ9u,m:fbʥx<1 -)c6ٺu+wq g;PWW7X,lݺ[o>N,FCBB¸urrr7ATT׿r^:ZVcII ʶmXv-(J***سggϞv' P__OffXXX(rݔӕ*1cF*SXX(#$z씔UVaDTR>+Z81T!-%j{m%ё_,"#NǬ[ {wS,>S0 B=^/jZn1Z3Hxx84{v= Pxjjm( XeA'V3`<iX fY~J`@ь:{&v\.\.aaa `MtwwSTTDFF̝;"F#89e,**HJJ ;}&Ksx#33ɝ%it9ʫjh^>ɉx<^J*)(:g 222p\rDCaa!444`*+iԕ^NX[4ϑurӅg|,GYA]E`NeU\(at%&:u+slX-tRP4<>6&MkWq n w~LM]Е)DѹF gFXXl DA~Bgu:6meC}t?]]PFy6hޏu%I^Yqs)h4HD]]݄BxBj9Kdd$rxSwwbi4*AP&tm:::8q"ط(<<9sVZX,N'C].\r_Ւ'@P3+鈎$l& I8.j8g76=/ٹ im>*J"jfpO aJX[VHZtTԨ:(ZXz9m@Jb<*rcORRwWr}v^y W1J,oB?۷oCB8>y7!]EEF t=tFy˅2{rt!m"2r( ,afT׸DG~rni gtE=+j gݪeܾy) dQ u 18-**JX,vttt|v}ij5( ^/rV~܎c0H9^x?$j u,zՊJv2ݦ&00lwcc#---Ƥj̑]ӉQRRl6CXXYYY(J\5@>+V`0j*9Wub|q8Wrj(<*zzzA;gC{g'gK8W|J+8~`*E_¤euRL{XH TJlQlٸ{n"/eP(DEEqs7z9{,/ǝǜQh4wZr)-v+477%czKII111dffA-x׵픔0L̞={41x8}\Hgʕt:V^$I!$cp:XQʼnBʫk.WKWw7'⁀D:;(*.lE[XVB?Fͷؤe ֛֑8^{51tp(r{-&uz#ΜYWjx:v{(l\wm%)>~]QAUd5DSSl:rJ(bcc tttptttvjČM3 ro-LH@!q3ϟ"~?uuu!:k֬QNRICC]f͒]J"..~?MMMraf$%%zm #Immm6 n7jz{{=x|>pB7o~),|$ {?Kx{xCg~IT51߾mPSxE)[7{K>@b\͔&'qrgd3 3Vb9~ӅpRQZ^_>ʼnEn̬Z;nDRb<;RHN㦵Ȟ1-=jٰa?0믳m۶)ݏ``ڵ @ZyaFH|>ـTTCZH\J||^j@$%%!I}o&{%ȩƎJ#[~?Ͳu"( fΜɊ+PL z<YW4+yyy\ihh=P`l…2|$IܹsBW&H0z⠮lx?'Μ}b,|~?5u ;rv浿|;1@WzܴG JRBJRV/''+S~T*آظfׯ!륤>3gqRQVԕr 3Yd!w޲Ą!MV1+kƴ0 !***B$RRRXj%--pzzz,D(/!34lZ~#g@0up햛k4֭[76 vl@Cf#{׮];jQիW˞ÇO*wH6fΜIB^Frr2&v暚 ő6bHrr21118N&͙3g`… vSSS3,%T𠶶ZͬY'==7jC$~:;Ǩ!nVJ+(>o~Kع 'چ2[@ 70'7o{M%&p dgf`뉵E~MkIvSRZ{wq1n][^zyv&xDFX;賢T*&׿glXEE׳n2:{%3-[6| l3Ez/qB)b٢DGqM0L?zi*z&-C=Ė-[z߿^ziRt: fϞM__C1RIJJ ?8 ,rq~M==_TVVʓ}˖-Vl6/|J筷b) ֭[O'{w֯_Odd$:̙33g9rdX3g8y$~e˖q]w/WMLL[o妛nvSXX'ꢠߏba/7=ΪUiu=GTd_܃A?ȳN?Zy鍿[QZQ5zc آz}QVQ;Baf֮\c2'MA{1466sN***'""bG-''|+r-*j˶?uCKx qJBW. ၼ#++3fON;஻BVsaxa333RҥKlrWEvv6QZZJ||9,T#9o2ѣGy#99}k$''غu+{/x &5NKss3$&&Etu<l(j4,X M&TJp1 w-lXs /q*=tI3RVY?tkël6e|VTG!KJ yM&>Yfe22y̝;s玹ޙ3g_9#-- 6e˖#eff} JswpwPސ.g}~3gi&8N֯_SO=Z 7Aff&* ׋j/K***&|nz-.\HRR?gѣX,y֯_B??nhXd ӃE2{l~an&^/;veJRR+.kԂ<^W6j5 . ]1{-_y P*|{IN痿{Ҋ*~?w|<i&'RVY{wsԙI!ťeHӌl22#='" k ;Crr2<qqq|[[LjK/4b(墻шnUg%;;%K/~ @ @__Ν?~^~eV\7Ltt48dCSS?)--1f<|s#99\~?ݻG9fqM7ɏ~#P"^xN:5l~۷җė!礴_~w}>={Z e륦!Wz>|/:h4jV/[̝[n[Oj>x1Ѥ$O]ׄ.{,Nbk\.0|ab0b5l܇fC HIhnn.oHHH|4557|seeeR$ Z=3+PYY9Q /@ll,7o&##r,;w^xaXNc˖-|GT-JT*>n1>}*-[ofWN²x8s0޾ $ttu1N]S^U͇MFjtu0 AJKKHAA=rP߿~(tgϞOwͼ[ü$qY{1c6Q|>z{{ٳg?կ~|;r@ ŋ<\paLQ'8L)㡶b׮] ]/{Xj5@@}g __)((K_YYYhzV~iv=<mmm|$'N'񨆳$Ittt ]\(J2RS`/FÎ=ٶk/˗, '+^z>f61;{9w TJ%q6&r~a۩$66vR2jkkBʛo9$SNZz$nT*~!<Irr| MJ'?>1I-&Caa!7yǹCV#IN={3ό*T*ikk0j\ 3TaW^_+_.rq޽{ԕ.].~Ci@P_?%eѨ|FѲsAÒɚ^}kӣl6}+EK\Wl6&꒰yt^C0/R1~^~[.\xx22gu-%LLLg-V1LH4nrBd"11Z[[tF!))d$fIDATn7*vm6233Q0,J1$&&nIXjƒF w*r7$IJ$]WL2rO0d z=?w_DG9I_|8[4?EE-f⸟3w;wUD&5#3{r.G{RVYsYYZEb\m[n1籱^zvԶ~NWP:-QsMeO] (IWW`Jؗ`{R$>>^nU^^NSSӘrwqLHBBOXWF,DUUհtWЕ!.%̼= Vÿ/~$3*k|ϟ~?9waCt;E+.OެswlDEu-}S@9Y2Q+-m;T*Mذz9҈w8D 0|E ~pP^^>l!W4ETqJ_ZB_~t<@m7R^UCwϕF\~?NkT]m;()\%eRI\l ܴkWЕ)C@p=ufcw @? I$~Abmǯ~K~N6wnDzJ2JJS.p8 I տ>f:@c y};|K84TW_zb@N rM769r8N~uEԕ^KWN*W)W:O|a\n7q:]h5V,˟_{gc͊%~F-g+|~khcIN_x [q] o0Fl9fp8 mR~mvqvnjcdYmỸ`48U3=շfG:#֭{asg.\nJ:B_@G;?p$‘c9֑s;>(y(+..]-o2.>vx䉧31{s<˖L뿧(( 9]q)\~ȕ7@eE9w6:Y~sBtt3ֳjT(Iw(J,]l2{y[@yy\~ ;v?w=0_y)7\}{DrVEQBB G-Yl}{zyM+.Ѹw?^q)_u9ZQPRQ%QS]'>FF7Owqjj>~Lo)p$7\}m3sPEQ|P]Uɧ>|+cc!}*r/}O+}~?J֭ZW#_O=m>rAУ}*:(HEQ\X ^2@glDZNL/8. N ?_.hD( v;^g60M痿EEE$ˉC|FPU EQrm|n}_:c|5oUEQh<)? z9*(9bxd|CQE9IB}*Wܢ9((('TTEQEQEQ< ((( U EQEQEQO(((xB*rqh{9%z+m(y@SʕRr ('-X b| ѹQEI];ѹ9uVEQEQEQ@*(((PRQEQEQE*((('TTEQEQEQ< ((( U EQEQEQO(((xBHEQEQEQ@*(((PRQEQEQE*((('TTEQEQEQ< ((( U EQEQEQO(((xBHEQEQEQ@*(((PRQEQEQE*((('TTEQEQEQ< ((( U EQEQEQO(((xBHEQEQEQ@*(((PRQEQEQE*((('TTEQEQEQ<9D |,r8 ځA 屔,8t9Z`5@5p¼3J? sLndc~}_<1/8;WMfA#wPtG5tfP FdY{Wn?~k.XciցW2L ňl\f70p \>  fr/rGJ;[eo?d=='+_#J'B bPX|5?(% ыA<^\ɴDY@}CdʕV+dRy,> \:<D@!ScO yxFThxW l0r2V 6U6l=/g-bȆ,;B" 5M=~Hw{GS>() Q@<8s+ޕxB~3RWn |Y$R&kTW ;(A xS92Z(QF[~,J:lChMA P  `'K\0^n%?4!ѫHT$bH6`/fb'ȯ@,T#!Gd9f1䣼6!˥X# 'I^#1+֜VG:Ciw_BY<+~$V>^{ 5Bx-r?e m2׎7)MQ2-|Hȿr*Ⱥ QȂu6ފ;|H.Sy ̬B_gyz r4)a$|fEօ7Xq*JgXuIn vkD^?Ȟ2 Gϐ~xeTf[ ½Q2-Wj$WzM(@*F_Rq!;:f"D tzƑ8_-^=(e g)"gDpwk|ŶNd! "$1:_|IbD4X pR9-zs,X~ƚx "dC"Yʥ8(F6""j;#B,'Fr7h"(M!k_9ĨS}KD4{[9q@BP]DcU 2=)WH|@r_-=W$7a.Cc]xt (0N}R&yH:sD<&f){IBxݮzo!DbDZ Q!m,/_F<ϬG"_* yqk~@ ?EB! "Sݏ!b tԚfe!NRqTTfO?HENA$u^"f[ˑ\F:D˕GHGqW{2$\.DVn<>CUQ!7j;l\>oɄN*"m&txa7rM[MfaZbxVߍ$w !P DQj?"iy&O9\̜^%/uG6y (Qr3"kxFlJdݜq,`:Alb0b)j/׼@LreUuNZ'h^}PRU+D.E<NG6%^{LABh">DI=gC=J[RTkIn^11"ʦs5؄x[橎Z0Yb*>[ 1dCu$4w5'AlrbȕeȚSrE R pGŦ#ON(vKgq>DxFSQϛ%qG=YYp[=#%M0U[`6&!q)"Sߊ:è9^sO s^ĘA+exlrE*ʩC99HdEK)r;nʒt\nx>al:=VDMx'fLHڄxRi,A|R_Efh{ƭmcu^+rfX3}t VR<^!Q[(gb݆5^CcHB҆DDq1&cAB3m`5f8R4(y[0+ 54eH= g+(l( "ˤ@>Ij*6an1q wRJjQN7 kS#A:m0\T]H~+UTTRc.*Hvޡwf̹XcXcx QtRa )$@bNL'>Q< ,W2yYGH%5Z2DJqTTxYJ[ĊwǼqFs,c S2|}k1rlY sDͅ(HpJG>s&H uYM"̡1R7LFISo  {' ! ԔLQYQ`Q."":EfS:̅ @iܴ[x*ʩR"@0ycI Ϩd s`c1%ۥȝ,Ƽ7_DnzA"vxvMY(ڐ%Щz;?l.4ƮL1+C=Y<88|.,ԋ%ݔL6Vp*ءGl0MڐBHȕ6̽OUdU SyC'I/5)KU$ϫɔdpGh=-䦈NGݛ^!Gű/Cة\$Oz)kܞP¼UzXe VMfOJ*3Ut;[ B?^,*^l/Gdy*DeŤnx(d`^?E :CV+YEH%5Dzd gE+,dUǼ(!Qi-lu$CcDuT:a *\uJHXM}aS9QNm3=78T&N54 c~VIOqsS m/ ̆Pu::7ft3/ϬF@6.դnä 8$EG/s rŴOZǧB̆C[(%!S"1ge[B"4fxZpSjGɌi A 1+vt N8qKw  } , {^!|8Rb|ŵ~6cS ! |WH1 ^"rrg U/"t[L)c r* D14-T{q'TB.Z(mCNVKI@fҍȕT+QR@]^+c< YrVM޶ V-h湌~Eӭo[LX&CoК_~c.C6Zv> |5߃sdSLR6MK0#wTDrsFrDQ3sKE@6N_-x f֮9u"TceJ @3U5څ&5΃tL} 3^cD}dH$ʕň\90!;Z0/Hܙ/|L)-$9,>Y%Tofzqqv q6dl1dCmL sZR̅f݇9eR,)ٶՔWj%frģNwtzŏfO[1$\1|ED2,!QȯY<eU 1C0B'VdѺ(Sv:zB|'A!H&fL*晄[AL4$c" R>|6[$XpMXOCg[y*85ŏ5n[0{N x{^|smÔS>ȷ⽅R1bSD01yM^Ə yo^e|];1ɦīz p167#23)&9oُp WB0V'G2rn-(x%-4UAȢ?<#LTc>\J- O I gpK̄zU6vh:H. | t3Yq=ninL)r9y!F]ć(W"a1aqiosš;Czl/KxMlARf+M˕WP#TTfg2("Йf=V#:$rCgBr_,A BޣMYrq/vT(Ex}F$<{U"VډlrǑuW=QbfTw#$O9lR撗I,kCkaċS38p7V^܂Nd_(g ϓ.F7p/\Fb (:O[/GHΦ*?2īx9ڇ(U{57^$ $|݉(ΰ$9d]G]ݶ[ѢxE볯 ۀ! sOvb61T;g8i̜M.9\Ѽ =!!!)"鷱pc0L$BbX nv~fLz9,5yn]SNaŘqdt+HK@,=8X 2d`P2Ģq$WN]*;n.x>A C "o\X'ՒrhC6_2DA;"jFvu'qop۠ʴCd9( sx߇ ^X#kfK@O#kIܷ{l魈ө@.E 0ʕ^DztIQK.ވYd37.F _+#_62wǽf|ͥ / y찻Y߆X^HޘrjR]ZU8HAk\:gxl!!࿐g8Y5\>%߾"m~=oc 1Fw"^>D[Dc1_sLD"f̓s~zZ;rz p;~-fRAvo1XJjBXM^LSL!x a aŤ̻UZpr+ kbΥcȦi>wC?!9p09UyGU0ҵMA$z/R&U)@*ada2 +g6H;1JB_F%CGI7WnI^w+PC d%em_ Rr>%"wĪg"V`72la?!O'{ M!^x1n@ք:@dC/SD(; qvWeA| QX^`Z1;(y 5 bH<ñc@OsrW$ -ay֜ o'` S\ck\Ig.ak.Nv/bxƐu2@!$#JL|/C"DQڇ $qM/Djyi=w2Q*>IԊ`"y2P(ѪDCc+6dT1ȺXbQ;ŮO^6t!fX4[(|Nr3˕dA*Wr*JDVލvnsQ,!2r0fGWfeM,#3 i#l㹆]$G䜖~ f $rDlD})<]̭0^%s^x=$4{&,DzLzs%>ϚWBRn6|H$S^t~q+>Dv;[^hZҏR Ȁ;IU I7Ҋ'K\KrTTr"xL!d "|>S4^-dM88_;S9T(0p\z?f,/|HULy0B6:v>'EAsf*DՒ kS=PJbWk%9< sq$ȥ{rK_b%dsT nX^'@:^o{+E?;ՏCJ 2N@֓ʰUʀIƕ\ۊܫ~;f Q$i6!`&zݩ(C6sid*J<>$d{$W|xSk[/RPY]Tie =-A\+A 9J{\Tn [ϡs.V#GH+H̫oGA}Nr&nD؊K.f\i@;\iEK\U[Qʩ?AvN9դW68ila)_esr˜IP:|<٩#{!}A!eXAΒ6~#zyri|+AZg82[\h+;rmRnȾ!y\qv;g:*wDt= Kɴ`}Ҍ,*K͈I?fEq\(nUTg#XOt P\cP(N",BR*%Ѧĭg،(NNCEy0 ?וs.F)S1W&>D9CcX%}#m_^Y_t8#Ue*2r>l鹎>D8$ª 3eR]ɔ31Z%V^ 1]gR:YJJN"Hv59Ֆ``E6siC cH'I`S9*A3F#MVdv&ӯΣ1 TX:FtMZi2@ :3xjĵ}~H|#sW HD3_K4^xc%'F}>s~H>,jN2l|o)(RxQSU /5F2 bevn.A6s0#33;KHL~-SQd|:/N9 "{ɇ^x=ߏpN|$M R8EgP9S;r}ϮĽ#ȺmHaȞ#u|Frg+yFs P |ΏvǑzsl$co!akbV,A,Gf6rSIl@dML5l;l7ryZ+1İ|LIDH%>7N^hn$GKa1d3 y#}zܖ7V1,f~;f%sn$ ň휟z8 L) YO)3H|k<>{rWG ^{iAd?2%W.G"1Ks_Ky1"DDybaS$|#D9K:͆sE\)Tcn>;Y;^v7Dz*JCsh( Tn:[t=XtӑR G^cxo7bM͛z+1Gҟh-@<^rDB2caN7XَX {=E)l`7: q~R(TG׈\y;`"(JBdJ<+G`W^[˓]fȺ_%4Eݢ{n]Vཎ{916$bԓ+V\qD *W*J!am!BS^_^J;, | C~Q c~3p*;IK5TƲbHHSHNPxHx7<RtnEy3I$C^N<ŝ=֟3i|Ώ{-l4H)d.G䊳7_ R` S*Ar?ȓ }Ƈ# O&Oq/Bʁ?\!dֳ02  Z@ٹe gul/_A_6dߎP[(u/ U.cLݎAD,B$DyaECMNH~dkcP!V(]zjb1"+6ްޏȥrCKL5d5y@B K\lE"ǬqL0Ĭ15|>iDY'lߤ0 x"n,ac_\ Sao$1/k<̥#឵$^0ӯH[3݋m{to'9~kߏ0'#_{?Vl[5&1$x}Mˆy .DT*;MHNģuz6Jl ʬ@ "9 G<w"@g sջz|5A)Đb53\t2Q-D T>l"sHc)@D9xHX{%id_n-]HhɄ]5o,;z-2l#ƺٜx!)wƐ}OW#)&;$7=J"^!.Ջmc(G"yV"3 Nj # O2EֈNXӚ^DSb\68 #{}ZD Ä@) am  d(C%7Y1'!FEL )ǾDnslEU| r/\;@*#Aצ{8$!ފjbaw -$J!%$-8!m0~(r1^H\_Xd Ry\5'N!)@a 9#Rl,A^D*Erkd{X~_MC:s#@-̗ Z.jgll!3/$bdJHrb{fkՇ(_&?}ې9=sb__F!$QD&]sA?E T^2\َDB&2C$RqA5<=ƀ!HMGwpTw ޿'HOb:Oa:Q=8 ]Zr_{3ez==I`o ;hܝq3<QQ#Erkء3)# HB*k:^$OS|?3+cH×ǒ.U5vþ3kmHp*bPd # aOD!Df3aCW @* R [ My*b*7\y%x]GG|kf"lE8Kbw2[! v}v!V"\(r'YlJfQkN^B:!?0(|k园ᣙ!`hBQtK/ ~(WnGdLmƬN lmb<(J^*x2(oɸ9Dx5ƺ8cYwǑ=ÓȞ9ғbˉq\^_{^eD.J1MWcR)W 1`+r PRqgQ$" 2%"8&oߣH"Jd<OŪ9$-HJ1qd@,dBvo;Jy5q [c7P;2.G$Hn(1ɀ5'1ws!gE;R=hٍlK_0:ʫ H-MQ`X +$!>TkDH>Y"ɱ+#d7ej B %.>Rl})"Ԝ}O ߳'_q'1vFd)&ST(GBB'W QX2~D"U؅({Tvv%%X6 ad~w 6+WHN: Y59S yUѺx:%+ׯUҕ+Ո|\(NmH4Grw!-o]A.҆?8bf*W9[ʚ5ּYDdwx l8Baro,@<֫9AdSm!QEp.>c󘺾b9'T^{) cQbŊ*e6o|r'Z_,/>x >fl ˆPG~<1$le<%l4(dt ċ=Fc( "BH;a騟doD#ZDGQEQEQE*((('TTEQEQEQ< ((( U EQEQEQO(((xBHEQEQEQ@*(((PRQEQEQE*((('TTEQEQEQ< ((( U EQEQEQO(((xBHEQEQEQ@*(((PRQEQEQED0P%el|CQ`$4:a(JZq{/>c#2PR#XTa((' >T(J=e 4Hc= E9%iF 0%D#0唤i"AU ݢ$OL( (JVP(B劒ZDGQEQEQE*((('TTEQEQEQ< ((( U EQEQEQO(((xBHEQEQEQ@*(((PRQEQEQE*((('TTEQEQEQ< ((( U EQEQEQO=E)Dϛǚ+sh]LLL{~q͕:NC<^ܾq*+*ẫYr%[[lݶǟ|1|>_z1O@ۢtvu+cO0<2(r0o^+kWfEQ:KL[pUWtq 8C"Wn8eex^1::Gض}=c|>^sEy-G`hh8GWAQL Xf֬Z9b=?ߪK.o} ˖."&&Œk⧿5#cx>nj*++(--%022n?<$_Ʒ8qu,[[EG}]eexWqUWrw+v},n[uW_ɚիxgݖ&j8}=CCC%EQN-▷ukVX,ƃ<ʡÇO*++y[nf%T˕Q^{5Cb( 9ci|nretҋ/_&c‡^.|)/+D\oɕo~jzlҶh!^u֮7_Mګx s%-TT崶4p?Ũ#;%%\x޹٧>Ƣ F9NGg'g4S_WGQQ_wY?YV\A0WvJcc#KPOcC=UX,pRsɅKuU}}|uE,YE DcCCohjlຫ`pp}/oL8}i8x'~6ߧ(IB2r@r9OhG hhc~-bW^KP_OcC5U|D$I8Nii)?.~^ݽ`p|ilho`ʕƆI2::ʝY0i<|O=\OGQFHE1|<|Q%~03zfb=dI[={wq߃3::J]m-_x>xY`>:^ضg45|d5a~?chdR֭Yş44sWJ˭~\t}_k0O|Cn gn?|洵kD"{|G?ahxҒ֬Zg?)KG-F|\|!Ul%p1K4 c[nyNL_]~il#GjVX.rel/QQRQ ~}Ct"0ɇsTsg Bl1ttuQSS{6-74M,**biks!|(--Y*++G>}>ZxblB0흝Gmu5gy\}kGpX,F_mAi7\O0( B;pѱ1۴Q^BuuU/'wYp~oձ*ώ4|UQƲ"W9Ӊb?s$|.Ş|TWWsΙ'/+++/  #g7m pLm+o:xGzFx~F\rUjE{{{D^-Z8\eUЭ;^i(JFPRQf!e<_Za,h{<ʡ!6"eelܰ@OC}=FX{h'*sa"֭YgtlpnzafJJ yx/G#SRRBsSuuu3~+WSQ%;\1KiijP(c^ iJK9 qmhcV\q bg&矋/J+mKxU7o}QQ ׬\Q-8|(aJJinj~԰f&N]U @ Q^VFKs>1]ccɰb.X@0O$UE,m 偬@C ѣ퓛Ir1>1AWw7='5 ipwe\Q%$>{r֖f~c3ȕPhJp%WYahήC.7m LFRQ!rrر*uuug*cy{gc 4L8S17E (~~Kb16TWd(4c1{z\?;OZ(* N*Ŭ^!H$B 1 Ra{V52:xhX,FII1)6X絶NzMTVT`<dʳ+x%>2pkuUK,.W‘) hJQQd(4K,  |9NdVrs;yһh\b*WU eJKJ(/+#LKyx BqsH$b1~?,/Ģ]3(Xɂ?%%%᧋gqt?>%JLU崜Bc޳-O}}F^n۞+rSRRByyyFJYy--"WuoG+dh4Jgw9884,)) '{lL+@;Ϋ_Uղn?‹=|ECQ SBK/fyDa"(##{{uD0KبgVx# Y$@4cxxxߜb2rxxx|X,Fh||3%%%}@БLLLPZRBsS3uuƆz֭]-<EQ2o)F^tM-222"Wvٛ*L##r%MVz+ ~ \DrEUOr%JJK2Tg޾>>77Q_WqP_iRmێ=|E@*\%Yd1>oRsk.ǟLS h$:a$#&}qq%˭ĦG7F G” cii >|ȱP*;@YYi 0wtҶh!-M,[$A 456pB!utsoFrwmhE\ B +%YMpή.;:XܶF/[@Xp!Pct\QN"TTc18H{G'CCDQ*+*injd^k Z[hmifq"JKJٯndh4:3K7)fXǬߊH9glωf Gcݴ-ZȂ[jMUe%-.^%ͭEQ2X0HJZimmfQZZO$ȕc&QfɕJVXId? \9zW^Ekm崵kynv),iknvڭrE9PRQ lٺ.(h*+Yb9*6ѣ{=Mx|)Ny|RWg> WOvv˵W]ACCK,& N*Rhh=lEQNBnAWw7Ѩ Nʕ˗r5Wq3?p=G}>\񲞛*IO6cx+sck7_s u,_$A466a:zy|[Q2*bX{;_ܾή.ngyKq9gSxBF"S^G;Чh4J8hʢSOgB!,'^ U7,Xf+ fi6u1L?PlZP$m\rvX0 |浴084Ȟ{U('@*J ѣ p$Xh ~e H8L8!ynHv8Jqܓʊ]. gY9|(/y--Yj:V\Aqq1lݶ}j(bppG200@cCm z~!Wʬ|H"W' a[D*|>rEX,&ɕCT}>%œ av^u47njkYcɕ‹*WU %EN N6b.//wC}I())E ~$ Hpxk ৩>I(1Q n 3RQYY'288H$Z؅z{{ cccTUWѶp)jinfӤ!vOYW%  W'eRIq1uu Yr%NʕpdJ~g͚^##YrX{0cFQQK |޾>8UU-ZHUe% ygX,FOq^T()r#2##tt.).Yil'&&81YC\d[x;:[D-~Ƃ唕fhxH=֜9z` V-Y磩U+3::G̺(ye"f|®|\XȕbgR 4˕c≜sA@Jg1L67MʕB2cZ1aߖ+CD \XG%"WYrccc:r|WQ2*"TU1 1bzaxxx[VVFkKgKKJYܶqH;i?`<0!'מ=^IAX_?yM~olaѣxysXn-ee̟JMM5ݖЭފܔOz+###EzJKg+%%,ikg}#a[r`OWܵg1s2:ҒRkmXJGg'cYI;&#Z[ٰ~ee̟JmM ={yq+I*>Z,awq;#w)--bg+++8czFFGyqÄ#::4pIKN*'N sX,FEE9 w 7: ;^~|_ OGhjl`ep5|>:ج;E#>ښj8ˑG=xdc Ô2UTT u""W ΛT zIcA+hr,ZSVVKLJi'N0 Zf֟GWw7^x!RDHEIy-YryQvޛ2ZZ(]tvvhjjd*@fVZA4,g4{b{YVUVrI2i D"|>W]~ņMG0.X,~|_ O p!:(--eyl8m-o8P(8|FMQ%Ӵ4vͪɼ#GsWb[!Zibz :$0hM 5WZr/IAh,Av݇a{qSL*H/Hؒ+W^v)%%% \|TVVx8q"ߗ###8x.JKKֲ9rC{TT$.咋.$ sWvJsmg?Iw6Nb1;;yv@*ŭ. UUUe6 } ?<@yYkq0ګX,Ʀ-['gmy!&~7^- KBsY["=+bll,ߗXmK|>浶phBz+;')*.^sAz]tLϟ[`>~[Oi?c]]f.|-/pgr2ynτB!~?gzF#ƒży_GYY)׿]:'DܳΤF9K8x'{]~?g39c1s)/+Zv~y)tPYS؁DP磲~kC+ 1Jip2˕ jkkJsS#׮k⍯U+311~_~'qR0 3=,VX(1Lz.|J-RǞ/~MWww?*kCxBlP__A! D:g( W\B]m-HH$J離ZYl B/N}HN>¢ a _"(W^v)˖.፯a[{،xtl{2^{5l8M6hs$5شosupхsE$'Ww΄s.tbHQsS#>Nx9dVeP_ǥ_gϾ<&a6mٚFa::;9x0ms8vJ7DQ5,_t\ Bv^~F (^q]\b?p{v&N6nZ.|.<.?mI~yo9~lNʕ#GٲIŶ;E%TT翺KSQQNyYEEELLL084D^mr>l0[m˖,v|"޻o}x֮^EmM sm/3m%q?9{ 멫C?~]{`dalyqM 3`O9g˒>rvڍ(-v/~}oLEySrehhٳo?[m$m|a%k0ʕH$Ȏ;Yz555TVVOle~yX,F?ȕo+Ceמ Xʧ 5g}SqIٹbϞ=D1RZ^ٗH8LNV Q^^NyyEEOL044ĉAω``px>bjjAWLY[Sm)1>\\鱗:B'5nj"9,ZB dӣ>˧qpO %s D#:!@R*)//wȕ!֍|z+TSYYI__?CCL$)55544s )ɕ O000ʕeb">FVz\aŊ$IjjjؼyEqFCOHE1DJ;/Ab1B!ƺ$p8L^z^P*2pĜ),sM+2 up$Bأ. V-<4 FQNsy^QJhEQEQEQ@*(((PRQEQEQE*((('TTEQEQEQ< ((( U EQEQEQO(((xBHEQEQEQ@*(((PRQEQEQED0P>ʪ|CQNI|>)'!>+/T(ɢ 4~Ɩ|CQE9I*WEQ@*0EH(i\QB!{AH3!^}|CQE9I\QEchг((( U EQEQEQO(((xBHEQEQEQ@*(((PRQEQEQE*((('TTEQEQEQ< ((( U EQEQEQO(((xBHEQEQEQ@*(((PRQEQEQE*((('TTEQEQEQ< ((( U EQEQEQO(((xBHEQEQEQ@*(((PRQEQEQE*((('TTEQEQEQ< ((( U EQEQEQO(((xBHEQEQEQ@*((({IYƬ>_cw./n,Ѹ5'0Υk<7'8߹,)sBZ`_K~ eud\ǹ^k!LXq\܏)*J; 8 88 h} 0 ="`Xn#;֞J`5-v`?0k6K+p5@#aVkNP$bk1d#9=ǵ t`p!Y dSZrd> X Gֿzx γO Slaܒ}@,N(SzbrMXl߇1ǀm)dY=5RwZdNm`ǀ瀧5|{`!_9z r}#w3I>뜂$HF~JQRIh3VD(D?p'SH[x5s}"E`->`1{ؘ|er^"4'NdpN$-6 v` A-Lw^s6kɈ1ވ܇1deWZ>;0p?WIzsy.@'poI|Vn.nFdL\hyD>Y(uI%2W@ 8(t`>K4sGY=|'_ˁ  YC;aUy qU\ILv?Z߹ Y ދxu<+VmuQJ MIb ෈̝MytR>W-J h{ʑ莦$/Yĸx-3+N}EDCjZF ǟavIFjz6 1f5xʀ ?%CI T;D1E6Oo%y/RCۗ,u4SqMx38y=$yI&;y. ]wȦ"[ pD_#FdׯHX}2(>(3@j^ɒO x q6MW"DX=JI:D49*d)Q7?] < [cmϬGB Fd>$ }x @.M8+[R~ b|kb]4Z3*$LȋG#W4"ۯ#V|P|lapBEI7 4Y^p }\H $+#H{(F=PpLф_>" Ç(l_DcY,g=C={@*(CLv ,>-F,m`_ 4_(mӨu |-'rEuzhP23E'3.:܅x!J98Jd8&CQnܑܼkɛ܌t 7$=/|و Я8'Sx.@@ѻ<29x;fK8ޅ)""d w|އ=>ǹN/"GlG"C"rb)b0<Y6Ly75QhӲt\Rl2]:: "0w]>0xb5}x {eHQ="oEYC/ow6VY{g 2;~IJELQlnEٕ!A , }#R,W!HTEH1Hђ+w|gVă7q,N-D!^xDs$ a B[~3yr#-"8Z=|vwR2N ipZȢz=RuӹDE?!;)b a5E.n%J}n!J]/ S \(Ͽ0e8z dKw6}+_Dbp&B>f.w j+$L1Bˊ~% "ޒla QgIpsfG%5n@WxY3D]>ds乎ɛ1&Q~u#PTGnԣlY3c:?{͘zQCgHux#s*!3Je/"3fjb_qVD9{᳕HD mᥝ~h:D 7rZ9mWYQP#j)$P)F6&k"y3;$/{HhQ^ڔ#J)툀p['Hk'kv!ft"3WlrwݏAO 1 3:iA HfD~YE<)gj蔳bQUyTRawZ#Hx79znG݂>IKU|t#ڙVQD{fm1."E(&7SVY\x HL)B1dC7NbޛK>ƬqߎL>$,DVӎ<zeƪ@*Q,nNaxxqH~g]#𪦿}IDATs cD#!-l͹X\_MH #!,qm3W1ڹxqԚ^>\Y-,G­!۬yvC"dssAěp\q&w Lj"jQ02@BVT"=b?|<&#ۼ1r'1̫]S6Ke(wQ\&B  &ôƪ U !1#$ 9sn}ct7|F yw3цDqn#-&B+F 1K|sFs!V#r7| %q^PlpƑq$v_Ơ( |I\ƑunoLtΏx7 "kUp9<ߙ,RH[S%ң)r ݄? A${ ʕi6~̵ 1I; d_7.E7TT)EB28^ ަ>3`OR}4J 01kCCQܱYd-KE6kD" "x'H>v1"5F1FAd|0 HdT7S6~;d(h0u">p!ak:I#^ksLlB tuCs\ yGTiƥX6an|&ɟF*Rw{*J1cH)5&F+iZjpI` LR̉׬ĜKR/Ggb5Cw"y#^x쾩^O)J&(Fp/KvG&X#|QH~**:Q ]x3ӽvȾPøG"aŽ[F:Cz\\;~Qz9%hIǫL b&x dsلUb-CB AdJU콬=\ļRL[lL SE-,gb^R _G{M/M$x(HQlWUxHl7!OSं}rU$zGBN"&7"f9XPgcF!{|݌ $F2c \>#Ix1!Ϯx c@*f  #t0oX擽S-5y>WʽsXJ)|;Ϗx✛bLKQfMbdiY5>YJ7Hsnä(BbG/^yvA'@~D7|[xJM+lGdIGɭ̍7!u;I_.)lQ 3ճ G{&w d#;lH]cYl`z[x)"ADyL'2*۔b6ز?cqG(S mcXH1øL!ҷ@?8i\mmQ2wa@ȟl#xb'^E1ъ9E*cbPƟ"k}2 dmu>\jGOOs ߎG[w ^Bz(E{;F [G0@BXMg^< b d-ȂiZNR̊K7)QD4y*jbT+a?fҭNm!ɈO(J:0GCD ST&Y!Hۀ}mR{.38K+p=q#bK5 GP^ٗ0UDl7 ̓@*f0[d"[hZ0J G[1{۪Hl[Q8މżt@:sHlLTsL%'GL4UeHE(VcVIπF6&HHdE-DPÍ7Jϐ R)ފ̷#q\0r<0I/'#FV~ 5GHIeJE(.0QWt;2\2B㘕P|LA#{eg fT0YH #._T\|e)GQC;(Lz_1E0?*fx ӽHۨ|y\k.KIoql5LWFyZI|bqdM gmNEH uTTpo K fYEvb̛[YDE,0AfH#H1Ӧr75C-%NEvq"yއ3kFBJO!\+ʡ"ƢQd2r&܉kgs1d܍lzCIn&QVWql#j*tDurx) މ9r}sCA8^?{~gg7bXuzs!J*9d)Ĭ@MM4H?7񌒾qZBVy 78u9N"kLdy$EǐB{D| %brC o0$(}rQ1)porejEփHA}1d`x/XoCL6Q LT"^LF..r' +0A\e V4@ęm}J jKv- U D|KCfi 6nD˜ءc5LXݬ&%8121'&BN&|7v7 -I̅C6"n]?3hm7"{F]L)!i kw*WTlX~ñ8X_EoGZ DAXn]Iqó| c 1]@ .%ON$%YԴ J2W xv֒.&rY8)FEoRd?Hр\)s +g* c^w~Σ |uZ_nAߛ6^3Q;r_4Yt!r|Er |:}b0"ˆl'g j9C=J"k.Cd"ܕ 97[dC~R&LYk c=Ae.C$V!.d3ԃ\RH4|* WRr̊\D=)>rc8 ݈.a=i+v"{n;.E1,x-V(m2&pRI0qRh1n'w f~ab, R]xe1F9V9^oC<շ<U eQ.\W`1Ӝ ̶F<"8?l2G*W=H$:\寝̸Vf*!|Ă`! ].Sw#@bX؏D ϧ!Jj̛R$_H낃dFċ,4(p܌(brkNRd6F{/a.6{YguyoOb> I5@n (JP!G!ǀj8!DPObXl5!Dvd YDĚ"y9*Đ97f[2DS-Nݏ(ie;x 8[WgBkp&Wȟ!g1dFB? u$]g.dz}PuDʘ)xO1t{< c@!=K9J"1_mm=L2 )"0b l'H`e佝Ccd]t˽$}O[ d|g- s$tu kfs9ҏx.]%^$ޓ5&LꗈG?k8ڑ߷f#oA%&Z+D1\$A)HNgq:o@׷W)bU%)K;kݞ9/$%;@֛5$5W -@T%$b 9LqI ߮j~ RC$$f"_ȇyCC©'J<}N+dLn$T$krIhB,ՈgjsF|V";I{D.~~BE~j* |Dg dD-R9Qđ<+1$13p|19( \eU6HrAa|U 33-(vd˪%SE*2AkƭɄtGHͻ 0O~{`pun V$oNf{2f^Gg5GU(Wloݘ 5 d: %b^o9e>b)WThE"CL@ ] )d.$.K$@\IOIU D p6[ytmXLb^0ήĭ:k2pW$LA9Dk)-d"FK˻I܈y0{cnDZ.<ԐPyS9Jad)G cV [Ϲ#^:d3p?m^@f."㸯Aһo|3-;\ːb3Rz2>7aez$R{߾Zx)˾ɲSդm"Hӯ*Er0M[Rb͋s=F¥SCZ8TA6%khVL%3q׸@y u.IhVLp;Ƅf:F0 S + 梤2֬@;!܈!JLBcH4/:v!Eu~#e_E-ӘSBXgjq/mBg;$\Bb$(y7ߛEACː%m3@˭#>Jc-C ~QP{q;w/ kPTܩYh#(rHF 'kyY2}|nkñF<5(pNy6 Ƣ #Wff :#nĻsc nTn$rb EecA$1/O$1/¬\B$z@AHRj"-҈wXмFͤ@ gV"A$nI'!V7'Qʙ鵓 ]+'0foQReoӆ=pr$tl!t?d3nF<0+e' r߼iJ~&p-vw65xB!J0-;U bVH']9FF{5[%Dd6ƥw@%HU3?(ʹ0c.>d @"x ]~Is$1YiUYX)09Q.'шw i\LN>#7Z<ĀpgAHL9 "UYz 8U酰V`.4" aV -Clq}1Eұt7a;`.lM 0oHx1(B9Ro|HuH35+'ː=1$a@C6@N ^T)91LUN7! wGUyf\D:5ه>^*g.dQ9Q%bP\x4w nJr`.ԇk>WZJ:W3D r&sxl[{ayHORē $z,-s %z11{sJ(e H@I&7EG|L'㤖SZT}w8 [ԙX5y?.L@듘Zcɗ·䈚E G8~9B wU * d3eGt[󝷕셰"y>Vl.' $3jdcY'+ƫ \xR\euާi&3ن9l,31{y,GtǘK0;ˆg=B.x*҃y]G{'d@X3M 2r_@"g^I7ݣHy磧FI0e H\q ~/nAdfZƐ{ʫ׼ xתY~G6?"!Vq="$g8[ҫDֱI\ZTTE`U)rYc*6ufB d;C'zzͩ@!Op~B͐o&q3v,s-Lԝ섐 Ŏ׃EtK <5yUOg)/Es=# |ȚDՎTF܈xGTAV]mU#v˗l:?SۿriT G3 [mjnO!:; -2]jDƚȻϗm ֋Jν*r#*\UwgO>k1G9AH #K$*U"$ bΝ{ ӈ)q~{ ǽeq3K(RCcNGd>4#a,N df=lN.q^(  %c:S˕TL#ޅdr3+lN%y࣎׋pR8՘HDz 8JI8p]:{" ߎ0+?E ;4y#W0H׃>\S U wyYlRv-WdisBە8Y`nֻQVd#0t}56+@Qx aY=3Iu5_\6D9p*:elB,cL; ހfS!KS?2u>Q[sA$ %,ݳKHMg2ĈC g0BY37^CXwaAwު҆4Dy쇋چOX5&'i#5{r9X"$/ dQRqgQt^4n\Cr!eq| ogCU!ދ[׎ 3]V!xF荎È4SE Db̏(_7!y)^7rGJDu:H1sks ro8=O# |"\?"CH5O8͈F`)Tds !3a* _n`ي'+ӈqkTx?7 Ls98ڪC xyw$܊ x >as1j)$yS9Q"ZJ-Hi/A|OG.(s(bM*OͰW>4r$.E Hb6sH +tMp1ldXb埭(Drlwq qE'=Ny*u$ZCHe*C #k<g!I(5s^+_>Ǧ??SVF'% +Wh+(xOv"e^*ZV!2_^u3m/@ #2kEEA\{HLD"xBu!;#-Y27LMg-bwj{Y}$K{KI#:%ޗm첻lv!: RfRL/ǽ۲HlK3y].=*>9盬jw 0Snĵ0-Նiź L ہ{;}p}u:fZ y1)L i0dĞz%ۉif|;:&3S %ޕkӝ3YU|43zw!dp#*[0'@gS7Ĝ534`1넍&_xfɍ4\qL/t/م{̉~.bNt_(SɖN|1da1e´~c`N:-6-ϴ 6{1[nbbuѺ0od<[-TJXxr203˾o|{9s IN˘r2+>b3O&9FSNH]$QLR\mjŲ1Ә5ܿNz9;D.:A:!_9x/f"att 6YaL{R^SB'./]aeYi;lT ӥli%,QLo05㭔Ro흌lvoc)' n2^i=Qa7>2L xfA/cf^^б~Lԏb*esL>8"L)^c1flC]]#>ZL\]Bt{%,K{c(+1+18܄9يLo6Jsv7瘄)i 2a'I=q771-;8RqE R)s03}`Hz̃I>ލj$0ɯ$9ÓĤwU_\ܭcg]9$'Z3~%1LX7Œ9|C3qL >qs e1<ĚbNaa`Zz1UC+w0q*gbsH^]~%֩zX*̘^&1aVݲy01='_T=J굛ߧ/s |d"pSu=̤!q2+HZJ elA_M|●18gx/7>$ny6T.OV쾀da1UW&3^y(D_@M*%N&Z4+Go}83cr$uۀZ '35=iG\wq?G]Üt^̉w8Z#c^Ϲs`^b_[0ۘRgx9n' z!TI"϶@ID0''pp4af-ϩ^\Ō!&YГR8TBV¸~̱۸Ot ' sg,0xDwӂ=L+ۖB?#*6# X,LB =4>Ue]|:+H=0&;C/ x1J ŝ(0rr0r,טd/2/c- a\`W]͘n?t=:^̆ ݝ3]y_iIOYc1itM,Zmɝlj}._wɺ01'gc<sqsсic"V)}TX79]N4af{|߭Bc7 8C?!ײ?Yc0'~;zi¤œ]ƧDsH]<MH*r(˜$\O,b1''sLv s|pՎxu0blabI*xE0'b>?0!cq0h|0y2i%c;pT aNR;avbMvbz3`|Oa~oc͆{˜p(77k^} }nm15P9QJ}5n9c< ̱ڹZ1ݺ1]nB_O/{JtO|:}3rbǽm^?ɭO5cW&3cф1nt#v<'O`5qɖkcll2b*O6{0aOtw1mDCQxTQ)`0ݠĴaJL mLLr'_Վr3/ RDdeG1!L^i))XaMz!ͪS 4̍<>XYcN^${iok3)$Řً9M3٭:0- M 17'[<9!<{TaZ!0k}r|s"ÜXx1s.֣~3I]|4sۋY/ R2>p/Z0eإ%Nvy ՘dLTz%'IZ#0/Ӛ[`LaǏ.[1'YX.~']qg~̐@g1ǞvK>^LI 7b0*3 b3&9w}:?In]v\lfTs:d~ECk89֡` lMh-qr\HLJ9Nd9ȮzLđyhΜ95ٰaå E.N%~jI0vqt;SՇ>I05}SiMSXx24C0YX79|xo9U-9JsE9iogp2s=]@ RDDDDDD\Q)""""""(W@+J EDDDDD%""""""HqE RDDDDDD\Q)""""""(W@+J EDDDDD%""""""w g㡠|!"@{ TCdBWD͍D".@k W^:'Hw!2!>_qE GbY@ 8 Mu1DKL,˚bL*"R-rTCT^;Gn98Ѩ)bYD興+J EDDDDD%""""""HqE RDDDDDD\Q)""""""(W@+J EDDDDD%""""""HqE L˲Ÿ@OO/If %8B!zq۶ p`^MF˲D" $Nx۶qP(L?}}ÑI}00+=a'ŕή."yiJ_/+"SI w<Yp!3s<ӱ,@ 9ʵY2?p'YǓOP(v?>*rzTW8G뎱yv|w465%,B.Zo9f={sѣN=gff2s4n:.X*;v= <Ǐ ':%;맳k%"glfΘƚ+hJfϚInN}};Ƌ63ػ}-e3{\y^IEy9?xYO=Mk[;P(~|^/U\˹˩h1l/MMͣVZEaAkVcYdefo?/9t=zϙfLM׿,~M\9v~{:~cqǡOqEqO[t_t;~zcW\㴿}Mx^deÜ;49)>f͘x/\o_"?/LF3/7̜1H$B$m^/P^W﹗AX~2>ɏqᲥDQB!,aYpQoJ8EbfYeOWt#0 Dx^^/|?@O% ^[梁H$B(c|gw,xWA^^.`??_7'\yp$7_F,鳇pxY8Y& GNuq\{{6*+ ##apL׋eY:|3~GiPnn.7\{5w̚9#W,+/mW-6lڒ2|>.X'X~qh1o_OWJJO[o)m\=ᾟ?@wwIߌ n{M|}略:e\Y |bmVƞ+.O|Oq_;k5x}l|QzN{͙3紿f~~>6l"@8o4v=tq.$ݎ_O$}04i~=fdRi'K[5^_U3DtOuq-sO}W\zI"<:9k5ttvslܼ&|>99LVKeE/m8Ҷm-\>).X`0ȁx0XKII1/XM?qb>,ˢ ?}SF466ضs7`|23ҋ9p{ww ˲j+O|*z{{ٱk7OƦ&nR3OU7Sox%7^J(.*=`p` K^N~ms^"3\bY9EChb^U38gQ\x*͛Coo/;w7kttu (.*bɢ47{ޓr+G>ȴ:;عĕ'eʹjy tv+ 3\l)fs/!!//"V- 7SpbDYrn&(MMͬ{I<쒋8t{\\i5snY ~21R;@sK˔&j%x|uO=}ĕlC}CgG6EEE8OdVV9/dffn}~jkhmk#+3I{r-7S]UIcSOöm/[ʧ>a.ZK!7V.\~xi?Vs[VZ().Gp%\ylؼMiXb9hqx|%O|=ˉƦqǕx5.^>)_xk/M[r!^´֬Z9$ xg\"fas^;f>S]Uɦ-ƽcӖm>eKsED"E~ ev~ ? .*˲q:ė~O"yhljk6uǎ7w6kVRl˿I{ٴy+PTTȵ\{~ko ۶wx$<lٶGpudSMζm*?o.-m?xh4JeE9V,OFe-<:&Hãx}.]ʂs^q%Dy w/ĕ;vOgWyy\t Չ}XEuU`④W1$jniѺcx^ΞkV )K `0??$_wB[TTȵW]{~ݭbZm mO?mh}RHR#۶ͥ!'7h4ʃ5 Orh9gQ^V;Du1oh_|͙Mff`J%"^|_Lܜq'e̛;z^xid L\w {ze%\|99,^ظŴf\zm~?]cp8_H[M[WXNNN5TWUz9v )gH]}}|^̛KAAn̜1U+D;Sֳg>lۦ ,rȹd>9fjŅ;ΖSn(+)ՃR쒋bM)φM[p%kV'J ] @4as+%6mݞg vWTqx=HWs(*,/oOƚU+L\9^SϬ={d\e\LqEMJ )V29tH9vHFb'999̙= ^LC0JgYVZ傥&`aҖR]Q:ϟ7Ly6{zncn gͤ ?|, ϝCsK+vb˶l%Yb""bX8FQB0qXXP@ey9M-|SS3¶mJKJ5""'˶-VXμغo;vN9p4Y+}cĕ&f~JK+DT"MfnD\Q]5@We]0os!+s0FSs }TUV3TUVx[سo?h8m۔$~"%"jAzF fx#//Kvv`xOOϨ' Hv=%EXEfq Xgs݅5?/Ol:X~yӴ.YL0HÉ 'el"rm .ګRUYA0ȓϬcO'+Ą`0Hwqe` HG*`J.^gh\+D,ٶX\ $Zŕ擊+yIq%ǸDť?cjJmMub仾/0+_p&r]]dl3dfQ7+^9|>,2MZEߏeYx^,ˊ5*:c. $ʒv z<,<^/1H8Xl3RΨq` k~^@ce78 LeZm K/,w0xC')/+cZM ee4462p߽뮽 Ȉ-=O=rbPxVp8X%+Ӵ@F1aƲmrsr̄:6>ėŲ%w?1P8D4j^ėq[ kkXdeqx0ן *˙VSMEy 'Wܡ."x&2㌘`HKLn4I'y LẦ8cX.^c2԰hiY<̾akk665'])).Nb+"23h|JKc8cqcLV\2Έ.C#JTMFUJ4Q1鉵N5U,Yf:ƵLeeqQ.[zZ'r)9 YE S'IVF1QM&۶(//eZm5;Nlⅸ'ټu奬^cOl۱M\1 vWxz0-=D"3qOhnIvj1vήDKᨯ7Oue%>CG{tvuq谉+YYLU\sZ E&( m%N!htԥ03k}Hxn N?1@pUHu=/2 ii,u3:v8w;yӁή.?V!++k#23'N`WUV0g,JJz+RV^VT\\K}0zpo\~!U~-^̬3سoB^7Qa3,FC۶܇m+W;d:yή$OfJ;H7TVT0oY۱5F}(-)Iĕ.`)R$"g#%"M{Y'J'×A^,Hini! i8Ǭ5ZwKuU%`>rq% |$JenB"p8磴_LQYY yBK륬R,ZysSᰰEšEDNF} ' )--p@vnu dgg}F/B0q%';K(M\zJ$Б##Gnn.-i2szmuCx\Ƞ zRTTU'ljnt%Ŕh|Ι=f\)g⊜CԅUdA{;Xb)͚dffF饭p$BOo`QvVDPXPG[Z;jJ]w:rhb22|kJjƏ9BgWi^JJV[>֦qI23VSCNWDd( 1ɂIqH;=>ZVVR\ik'K"dWl 3Lᣀ{-ƌ+eeea O %7(/7OiIIb٪#G9IJK>mڸJff&kk=Dvjh4J__}}}dggCQAM--#ʤC__?m FfU%YOfa㡨\CWww1pqj/\GRϠ,@ ohp@>z4ʤ)ͶkCGN[Y]]X[[~ͪY ),,`ai){|^_"hqlrr),,H$r233)/-OK[[R\ Nuf&3Oc˶ +Hcǩƶm,ZȁCSϠ6q8*&PΟ7,NvZmM";RwӔ@VWU0oln6nޚv/QPy "Z E&&5e%̘1-v%,?Vnf6\.^rK,¶m [mO0]m.(-Lپs׈iGmf 3^ٳfM$att@_UY3;~ԔrIQqa!.պ]"rrl&??/AgW#YpE,Z+mrrYtq}~-]m y`\ <}y<\rњe^pAlرk7}o߱3u֌i[Kf /7ĕiu=*˙3k&ǎ7aӖ11<@aA/P\sHr5c:e#;|;w`άYY2>*+Xr9Xǚ[x(*,K.J9ynn^ xx/O U7ސ~vFߣu466D(**d).^ʊr^/{X}^df 9D(cvOpǂUDNΊ h}r Y̜19Zk\:u`ey9bΉF^>Xkkb1 ?W\zIʸuW_@o_㣉BO{0]ui-_hu}H upH1O4),,dp|*+z7iԱ-l%y,ZXܠRąj>}~x7x^3$g  PPXY`}TUTp`Zz{{ uuwuu}.Z[`y+#+3K.ZEWFilj慗6&D"9RǾ,"7x?*V{8fD"̜1'|c\DSSe[5rhݘ3rS^VEDd4U[Y~2yy>Zڇl7|oyz`*wM0U+d!(/+`iA&gپs-2!&YE4_fF9r`Y-xsg⵷݂5q婧ƕE"3wt`o|mTW+o~kk|u9Պ6qG={L pFFe_/ ïI/Ɨ68jeeP5c.N4JOgTgb嚫ֲ .ӓOcێi\}5RUYAaa==zyObOQa! ͥk4(oy#ͭ~lWy/͉peY\z%99,\0P(LwW7eezˍ|# ;;VoĴHnx^-YLffV2Yj_(..:aӠٷ+SUYAYY Υ^f͘?~^yՕy6~_paݙ&bytTwc=yD"sUkgd8x;9ضC{O}Ʋ,r v{x>fqϒRYQNm)((`Yҋאů~ï0==C׽ĕzعD7h4J_?,?2fΜNWWhg_~?w_Ʀ!0p\f59,^PnJKJx7}l//{H$Bݱrx^.X̬--mdeezr,_&}px|qe߾++(/+c9ˌk&//-۶s`߁%̟7oi5?x?>1H$JQa!]}%~n6oJÉ3,`#rj,YO@ @}} 43:KQok993J 22|ےiuC<ȟ;{ 5Yh!P,͑Iff&ᗿ {SΣ~ .f1ktߧ>F53 77nxzݳ# xgo|η7q|׿=Iu*fΘ29~ZZZ~/Şk3Lġ4 tvvqh ̧ -I9ᄈ."7RYQF4jλ,ů0ASLK4+5s:|ysfh|֬\ BCʑGyߌH;x/|RrOg?Ѥ'77^xu#Dx 'w\׽ljJeSO_+|?6Y3Y~̝3lCNN6V~xl߱ŕJ&ijjN;P2q:/\@AA>^M[2*J EWW7􎱆K6 /qƆM[;v|6p?KKko~kkSߞ? [nOe4Am-o|=EE#{+g_H;};l޺OTWUW6?':;O~Vԗ6nC4w\s"`O;?[~|~sٱefLmY矖2񐟗KiIIa#a6n7H{{7mѡ=%{ֶvpQTXx= }l޺-m\9x0غ}o}(.*W?߼uKWz{{am|r|[G[7lG>wʫGƕ=wc6nJi+^?8.wtcnf͘eAA9Y?: vKm5~zW\̊l߾}߉f7 9Qwh3!eQTXHnnFWw^/ i8Hw^/yS]UIaA;^OSK cٶMNv6%ETUURQQNh đuhl 7]%Ŕ3/?@SK3==cc,mSPOqaeTWimk?-YENNNvWz呛C$sOx<^^z&PeQ1}?-]G@h$BуS]Wrr)-) xl{hmmD#mtuw%5L%9NHL\ɡJ ziwWq BG֙2&SZR247Bϰ'öm ).**Z8V_OSTŕD2M۰1$ǕsOx>6>(}=-Xܙ3gi|6lp)Dphz4ܝ5~J Žs)H$L(4+cSyj)<HtY_,L\G"D"XVwW, ,R?qa`J8q%B(R\9@zZ."0: c TIDkZ#I LEYEDt '^78'U\2""""""HqE RDDDDDD\Q)""""""(W@+J EDDDDD%""""""HqE x(.bl3Etm+Lۣt@G7˲gfMu1DD""rP) Һ.TAdBb g %Z4~!""&W@+J EDDDDD%""""""HqE RDDDDDD\Q)""""""xmΜ9S]9̞={ ""rP RDDDDDD\Q)""""""(W@+J EDDDDD%""""""HqE RDDDDDD\Q)""""""(W@+J EDDDDD%""""""HqE RDDDDDD\Q)""""""(W@+J EDDDDD%""""""HqE RDDDDDD\Q)""""""(W@+J EDDDDD%""""""HqE RDDDDDD\Q)""""""(W@+J EDDDDD%""""""HqE RDDDDDD\Q)""""""(W@+J EDDDDD%""""""HqE RDDDDDD\Q)""""""(WS]dmsns(""rw%q ?eeezϨ*""p8L?S]3"rjhXJED %?kx_u׍!??_6^D".ҙхUɣL`\V)yzϟbg@6v%""2sis{dz<ȔzdeeMu1>쮹f ""2j< S]<3"MyG9(""g3!My)""""""g%""""""HqE R$Y\9χ.fZgsF,|f$Z}&""""眩G,x݅dl:H{d42< +Cg鳘WeoSސ3oMDDDDP)ͧfe*8%vǺ 䤶ܐud۴FYwhSCSq 3m ݍ.y;5kPPP@gg'[n{i.rNȵY镹,*Zd,TxyL"[,ş((1~6Z:sXxy1w}77x#EEEpcY:`O),˂/ߚϢr/Q>?참GEMocߔu.a[}˾?2${6!Xh<1ۂAz~c'})]1K8 }'\:7ѲdW0CGw-kqI6Uy6["n~R/N(^Q7r4e96Y[#ߺ ya!^zvs[wC*"?h{/==$K-p5Wy,v}O{7i`jkkD"|gƍd8;om7 <E.2z!.swyf>`Y~;v%%%;v<#8ș@ *r=ܺ8?=O6%{@׶xYmCqϴ{MT~j X- xhRᣗgÿQ>`];Ϧc!<;8d.]k%+"^/ޜ'!q0X@{1^'o+0=+P[ Ra%L_ȡ:$Jh˂ ì"/_-aIJ[+r27_OqJ|" DiTq,bٳn{!hll/rw3p饗b <j*֭[G40o~ B4662m4{챩Duasp ei\>37~m`7[D \^fzz|^$ }ϟq$/0K϶X׃59K9x{!MHlSW`ns|eK FVĜjcw\mAM$R u_ - Po 9\_s33i_x<[{lgmSy?pﶰ6>LbYx;ϿhѢ!}z|PZZʳ>UUU̘1</^L8f׼P({7r]waYz+V3Z 圕<$cHHw.2?]6ise}QᏝtz[>/. c4q\ ,~t{!Y/&Zgh;sB_ygk&535zCkiksx,޾2. p=l|7o)}kj3֭[ٺu+w}7Xv-o}[yGy[Bww7s| ##˲p{.kdŝwމ8dgg|fĄ="254YiìJ3_y-.@}gGwG]|wh Us:<>laZ~ΗJM}i0_x>ԑ_tq5Lq';vt9L"5 oǂ]'T{XV飮=[\=qSsvr-lf`:ydwpslxu===jcH$Bkk+YYYSBEDDL?G۶OUE?܎_wnqe d\]r{Ft!IŶmy:W#S6O]IP(zM'"""""r|BP\-9iN{:cᶶuJ EDDDDDNG[[: `d?FK L5RWWwq EDDDDDy~q~WWWw]Xӵ06?]lhM/g?Ks!x}ԱZ$<]`pC'ӱR\o),,̼28'R*""""""ضMvv6vL d4o8acCn@oLh'mjj:\ZZ.D"J"EDDDDD&!;;p8|;0ƓTč6;mH٪|5l<'ظXvv`ʢv[L<2w_u~T dVKö755m/yyy@ 0?)Z%EDDDDDFe6'8z<ߝ8q8KVF뾚j$x^vAXg_o}>_]]][XXxiFFJ˲Seyy```C[[cǎLb0i@:27++92~3<mrIer2Iwuoew9_ Oa8zt+MQ8k_ݗmQN߆IH/9 u5 5 ̈́: m%]'whX{Y3<""""""24>rx(g^Hƛ#-÷K~x e0{+ONɦ 5b"#(ѺBqk&s9:֌ f8:&7|!"""""r>J4U+d6e5̫9n@&?q:--5!&' J EDDDDDR%ûFS<>|HuǸx dz_H82֓L_^.2՚÷u5:xo.V63O눈EQn5YNsR%uR'ΰmIox(xK[1ն^?m#okYT-17%rx*""""""CJRM~;3~F:D|-Xt[):iX Hj&mbђJRI4)cftׇ'""""""2(]S-c2Fا׀LuqqǝQ;^P] pHs;⾉& -c]%2sS2I.2)""""" W]IS<6VD d7R/%"""""rhot'8Xdu< dN<ۈ1ZcmFKv@khIxm;1R%0vby2},9qHfqT2)""""";7 cnÓNa,pI$.s\n7%"""""rp;6m&qmch۪QDDDDDĽZ#jt\g3d&n,dc]w%p'DXɤDDDDDDnT71t<'d$M\ȹbCLcƓcw!ñN%""""""J&=cOESA>ѶKiIENDB`lxi-tools-2.7/images/lxi-gui-script-in-action-900px.png000066400000000000000000006773141447016333500227340ustar00rootroot00000000000000PNG  IHDR {4"zTXtRaw profile type exifxڭiv7{cYa9<դȖd'$ͮFf_TSl[lCϟ~:ϸ{S 'ϯ_@S:|0ОZ_z(hFk(?es#| }E=w,Do%WsMпބ~…6_3! 2+SV>~zz={Rٽ̟{~|sCa~?d{Ϊ<]C}< !m?we'5;9OZnt)F=)O*)j~kHf_w| -P$Ϲ{vo7]qw tJ9Իq+Ww>(}2n+xɽjKun&@{'&م䲳q3Pi .%ɩ^=k}ϯ,BԴUب+5SH1SI5s1s^B%\J^C5\KڛopL-jkwn?ˆ#<ʨ>)gyYl/'V^eVnSJ;.N8O9?̓֟}G͔.,Y㭥| 'I9#c>:2^ +gQ3<]sVy3\^ M371 v;'ի$?4̗yxRg:3f>D|OOQ3Vr;kX#!y^͔13M9j4b+j)3 .Mǹ$[u<|5[:m](P {'ēbyvڡxϦX!HjFmv1ǡvmE;g񨈲ɽDݩ/~pk%R~8\u]JTq:Aڜ 9}'=[y"p[.AzHT?~mȩoO odv&L9Xb/n9¦x Cfs)^=T.z<ya9iڽVnKT=5"&e6B$f*ET2|0\ƀ()Ux\3T+vnFB'*Vfkp&3w|KQJ%4 .HcRHNv' ( S T+­@}!Ef\m)LJ^Gb+=ŏ5k3B=}]=K͠o>iST3*%:lh(iayJi6!'s^(:>]tm OtƕhPle';>;g@|ojQ<gHfbyU౗? =]hhaolk2@{#M`=E$ɫ%3ȭ}΄ТE ߹:Cʴ\.q`xdXўR@k%g}CDRjȮI܀D2JIcڇV~0d%''6[{̠x/md@!)rM 8;>,[UrͥvտnRA8m ;ڬ[~+L1cY' J}g?մX j, %(ʈzPN1!`ozӨp<%Sf Lj7\HFaQTA4Jِt0np1H",áF:o`,BP!^e45 mS8`e-D:7ŐN`666 TpYEszuoޞHv<G y)أꔩh^긟Q2 ^$zlh/: ,lF i`<a`ŭ䉼[9""h"v7=y]tR iKCD 5`1umQH<.@jdORY<BfNØ>͸}<z.HA@V轕;ge@<(Fn;d!BPw#gm%80wSLJ׍;aţh4Tkι= E(W M@ 4[WKB?f)ҰRLNKPp< :kh +S oPR>KuYY RIA_N`2-N0D`ϥT0}& iAo(@)cg8fU[`y)A$G_)"0.TxZMj )x^+$,cE Տ=h!euZhAr*{-):GiJLg` b2zPXNF7|Znz8SJ /b.Mi@bG[ϊYFGCP_"Ҋ&/p8na&ZZ^W-E+k^+93-|MVH 5V@z(o]Ƞta6IMVVZ^Hm*ML,E"y h K"@^/{kD']09 :ɜ4ǃ-EBq*]וEZgT*xd+tA+p# 6ѬZ K֚ ؎˾N:_`L?#LLѐmݭ05'ܢ\>unǀ;6*TDRyx@>A3.2:'up3vmm5g2pĔz̆捰B4i}L.F Di9 ZcVV} ۵X%_/; ml6SU5F"%;j<+-V<,t!\H~L 3BHQ, *\.s&mC'跎&p-J s ZiG L>Ԣ2v_2$zV]_)sW^ӑ[jYϸZ6whm?};?>?)>+7=ŠQ\mUx ,U \d- FJNZ6(ZC5-ݬ Dx?iM@RȴU-*GF G^M DEK7ӬFM_3&&WѮ ~j$g@D<&*BH3SI:@FdyMVED&)N{̵;ZͰS¤ЍHL4NWGxu>t'}D{xr.gizw-O."<䐦d* Zhp ?k I@4Ű I ,EQk$FW!T8vYsP̟|0E~"dnSPopQIHrP_'צI.XuAP AF Y 55T&zC1޵kW{5VƇ-z~u_\d~\t!Ch0GEN+(taxF{4L:Y{:+T$f}m@6pfPO{7[j_Zevә݋?ZX^)Q(Wt U}<,& }x/@=T2h!BGL7z0cW<깃D4mɊ狆Zeqgږv/@YQ-x]bGԾn/QV[!HxO@vWA0/_s1/W$_ _JQF,fhϋ\|LOۣ]],E$Np܅" )t]:J|DPѓǜ9sbzԄԮ?r`QY -lbmHNZNuqP%=}x?` HݬTtX[ o}@7 GC"#cK^h rS@Y,?A){AD~;oe x`pxdDDWX"c( %D𫴑ңC;9B;1] qB_h[Zks=xvOmT|r4 i'WT#DmôYM{[:NՍwI" <~` K ɅL:U$3-_BS)5G\ A,ҒXs,@|LA5Z)xtYUNSC;R%qf5 dv&:yH ._41/AKVv"^e} hƏ/}Z {$]Ջ +Hj#6ɬi ɵD<6xį ̐~F^Z|ȔJn!Êt6`dQ@] ) YJ*U΁X_a+Yoq}Qmhp۔mg适A$ƫQ#́uTBBkWa=#49]yH:B:Q%֩Mӡ \'avPI(p0N\42$o>qxZ :mZDA:w20(?MtT5!s!dGE[$B݅3L˅ DѸr^@5 İ`w]&f@JmWC3y'}i`ĸQGNF,ihbIwkYk6 @'#pfB\ |X@[%@ӒUEjEV #nނrd ` : 2EOɠv~ AX2 E=j|"";@u],NxYY 8܍}Rw8mQ%4pj"IGhC xhe#J`*ey:ަ0 ^{`xdT+dgSH"htlcVن&>@uǢH.!| ho3Ith^Ѕt6pjzfTzn:eRw̰^=𞓊PI6<$̚IR oT )R!!Zuq46m̽>hi[ `UW}Oc!!$KJ4ڪ/!:[hњ'U$СMZ6/;f2{rKjD8tӷDExw}5;ƈbJ:Zш<;%n ޟ ҞjD< Σ WKAY[puwnjub CvĴh&dQWF7c@M@J˙oJMxZo?!tO(1)>$w:) rPwpC1A8NPP`dZLD2L4c4mv6xHu.E.PЅ8.y R5_fsԽcە* NM@Swt3}f(eNG8Ψ>9sCm[+N<#=h`݅^w< N<ǍƂDmD7_7 \gT w5jxMYT9 a_=Z8c$Y\:87=J \)QaP2^6mJ~/_wU服}2:LDN%m>.[xL @A)f1u7/(QP@X.HK'i]A 7q@g7dbzF*Gr>:>HIty~} Bqng1I8䍾BUA ,ȣ{BPYG4}>]ތoJ1)]=Fi6ܚd6[SZyPU bGB_/p'O|J*:Lv31B͟r2_._5~L@ksHд Nu*75 >|dtHm@ JIju>@Nmg!RoN9-Ϩco# PԜHBMfPz8{hhu?\;k?~W`NR,* 'F XJ@E۝+ ꐫ^/IZ!;;ht(M[eK+$G\!$16ϔGNg\U5yGPM%lU+co:Br'TKE贔Bݩ+xch;q"tC 8T=vjڝYԉhVZlum7w$Q#% (^#¤3+i%Gjbά|QvNMmiw ,:1W(CAHcYm5y ^&Ҡb)LN?OQ6ϝB\uЪ!X{]1tbZ,9"dU$u XD:>fkgVŽ~~VN ܃=v4CJ8.sae<ň;FEoo5gF|ۚ?zU*:(@J9Bhj3 bd`4 UOB^h㧶K"^GP΂_mR{AօmjE:*H'IP:Ф `1xw{{ (.+GXŤSc/.2u_\d򆿾g h u\_JR.5ʤ~hƨS*(/}RQKkJ1lJ0|yǻȏkgYcj?$@ 샞$b}oDe0-ϤeYZrC:^%_K`gt2a;.}޵!5xDZT^}uזxOfO'L:}漆Yifu-(Flj_>cQgB~"!$ɴ>z )3Gtw곢 nVEF*?n\Wc[dYֺ@ə[|ns \ڟi@).l>e׻Gur/:}"8631^miEY-we<0sK@xDMuJ\Bh Xh zpυm2<kۑ&5o1 1ô77m>qdx̤xƹ3#f&=O!t0+qTt8kk_+\FX j(1uR,<rrȱ*4Ȯ~*LNxI8#@hhq'@j$֢G@6pq֔=r|2dSv P(gM9`]:YnC`H>ۿwZr%U iTXtXML:com.adobe.xmp >1bKGD pHYs  ~tIME&z; IDATxwxչժ[pýܱŀ Bn ?H.K@L!1`l \"V/ھ;$Kr<>Z픝sfvf;(QbƦ!B!d2<2Qs(>B!B!ĉ1<|{X!^91B!BqӰsƦ)0HB!B!iocРɀroB!B!NN?±P(XTB!B!/<0hP()HԴ>B!B!#|v4A` f>o. B!B8hT# 0'6RB!B!@i&0(uoLcuSi6RW4@h,8 !B!570|n&>kX(7 H@!"U!B!8:|A "$Y"PT@m$P6XB!B!NNah$@ԙpxg6J#Y X  D&!B!wg| zN  Aw޽=OgVEB!B!I iP طu֭@&$ PYT 4 Xk[u+77n2 6MS+B!B!Z(n/u}CIIswh >h2$ k4? P`l}^p8FB!Bp8|yx6PP7`0hwB~QP7P`, Bx\B!B!DuE4wJJʘ’ f1mu;1TiA@A׮]{h-.b dZ~ !B#S9`r&VbϞ=۩Y]|s +GXan;sssBuJ 3/Bmi?XY }R@.FB!8 A˅bnNDQ0aH!miF(j;X,-"1Qo`$F0H̜@u;4LWЩS;hV"u2.Ԝ>`qD*;5vpԃ<!B.55ۍ=ʼnRU͆j%J!TUUQº:)/  j 0Ψ[K=bԎ?,(iB!q8ɈW)!w`n;km;&ɀj+b>X`;r~%%>9 Bq\UBN'HD2Bq5%YK*QLu8<`(jo"Pаhn@m$Xpe X=姽-vHZ!'vC(Z.oko%3yp$=%b1B1 ?ASƖ1 hbA ʑ;GB!Oaz=ѻ\.vd)o!BB:TU44-qv8vԞj^|XIF4!4^@Ff{U"o!Dj۟`rN>t]?|+N^asoOL?^#K&H}ff&<|QPP={ H 55슢x6`6R7 4,hÓaQ薮ThoP>V R-bĈL>=z4zaV@ ~ /_0seqUWl xb^}Ul6[iݻN `׮]x^l6:uM6I~~>@c4v؁i <4ٰa)7iX,n&.d𤪪|C54Mrssڵ+Jv6Mt:Yb){i8233k)))G6lAuu5;wL'K.k׎˗0z;vSNXX(]wEII Vym۶eԩ<ӄFבK۶mQU :ti<)..fΝrBLld\N1K x"DzF2(pRa\7( N?Wyce:<~}yj?@`iӆc{f͚5vf.^{MBÄB! fϞ͙gE4֯_ϯkz)rrrrrr:t(ibܹsq:uYl6\.˖-cŊ<#B!L$gs=`v)UX֭;wb0j(ڴiW\uu-?l0nv:v'iӦiwuYYY\pG,rgh> 2zhv;۶mcܹL0L̙sࡇ"==׋aΝ<'6W_ĉ+Z,%0eNJqq)sw҅Ç駟D=f !CꫯqkDQJKKy')))9nիWcǎF[n\q]qʺ+7n\*z!nq_UU\.e`˕0N8n@ @ b$GQJKKܺukRSS"( iiin0>FgڵȵuӇyg:=zoFUUf͚o2PaZq\q뮻.48s=gt "~;{&O' ڵ+֭㮻W^ CVXbӇ;v?aÆ1e233䥗^bTVVxzlڴ)yw}ѯ_?S?EQ8묳h׮]P(Dyyy76 M۶mYn^łcذaʼyĽ{믿k֭[+ ͯdr#8=cu]M/O^ZX m݆o߾ : v %`G4 ]dS<<~u6NΤ{4ǥ <977j̯͆dw~&Kah;&PYgUԹtʫ* D*/ Ǎ*O647DvZVZUW]Ō31cmڴk׮XVodAul6ƍ#wS>yG2do۶mnX,G}DEE{/˃>b{L67sϱl24M#%%̙3Yr%r |8#G4dS>>}0a?|^/?8fJ>}us2~xʯ~+yg B\|ᇔ&;C:c޽3f gƌtڕ0gf̘(\|>5j3f`ҤIA6m㦛nb˖-Sf͚Lȑ#4h)q`CT]ד# ̛7UU_ʕW^ 6 &g1sL6n܈ijՊ2|M6mT墼7x%\¢Eü̝;WBSY|y_ɚ{n+ 3P\\=̫zX?4 @"zx^zx?> .$''뮻Mӈ xaÆ YdIcfpBn:t@zzzm*+^~ew?̝wܹsIKK /dĉXdi&-[ƅ^Hnn.YYYlڴ)ܯ ׼yر#^x![1sLt]gϞZ@ y睗0jtޝ:$ PS'##`۹[طo/>ZVƎKݓ=쳍vz* ,`ʕ?I&qSQQAΝ)++?,(_~%6l8 MصkK.eȑt҅Kb Bq*JMM%''{Q]]j%RTTԢf%ŽT.8``Wިy^*v6~9>WpGhL .LTzT":(Ji/0W 8-$39(**J>kX8X,FUU%3|>ddK,0d8EQxٻw/WǩtbFp8L$n7;|̜9l2:uDQQvzս(//Gu+y3vX"/"Kw꫓&*/~ =\* VXqXajͫJdff b40 BJw+B<'??kбcG u>UU'4/UVb1"amyU<]aX,::t}C=Dnnnth4ʊ+;v,C/(?ϛ>hРs䮻w|t҅_XVν-5),0MWdqRCzhs}&K[(pVW';;A(LFV6*Ν;?Onʖ-[袋0 ]al۶믿{j}fkF޽{۟]t֍;3.<96lСCN4%5$r?EYY;w[ʤIx8p[nm6oɓ'ӷo_ϛoIee%`nyrJYqJe]hys=^<?My3g9997R]];}B֧*<?V^AMO=o/&55o+t]磏>Jd xg/X,<#L6~%Sݻ7inwr Æ Ouu5馛=z4[n%PUU޽{ b1Oyy9HѣG*>,7osswбcG{=^yt]7n`Ȑ!'5UUesSRRŋD" 8ӧ$GhφaOΝ8q"̘1#9C=-СCٷo_r{z4yWb3͆~4M#''p8|߿`0H$TTT0gܹ3 .$;;C&nGAAsK/s?%j(On8x O?4UUU7e4M?d̘1uVd&/{.yyylܸ1yw߿dPVZo`bǏW^Zovx*++:DF~;< n7g_lf* I Ip8F*ExPUp8$'Lc)))*|r%'1U!pDD'4H$I%nQWOKK7ҥKqbX"ǰnM6<,_ڍaiZfK> H?G", 999曼K̝;7DЌ'iTVV! MK %{<q_^a}ԕB(qݺu8뼌:DkDl.X`4h`iyXԨE2U&FVVou]*YwzTDkq\m2eƍbƍ$[h8 ɭʹ4M֬YSO=բ'1V/  UUIKKk#!X`־?,X`]Բ à"sBxr#Q^zg}ѪԫR"+V8-FNBP($X B%Bl61?:0O&y1M3$h`Q㘚qP-BŒ7Bq ~&G㤇|`{OaZ&GB![$ikq|#S!8q'Y}?yJ?& (8֙|?xB!`ۥm J  jB!.Xo@tO$X*m~  !Bn @UUip·&aH@!N`B 3R&9,BL!Wu!&B!Bz$X B!BzNBJJ iiivI!B!rN? ~  B!B!Nh`0xB밞(B !B!B" -/}!B! !B! !B! !B! !B!kKb1 ÐB!B!Nv,K~O 4M#iQ!B!$Fx<֖+ҷh3p8,!B!$4p8ܢb4FB!B,bf_:8B!B!D=,B!B!D=,B!B!D=,B!B!D=,B!B!D=a#EM6dffDؿ?aB!B!Zi,у,TUǔB!B!]bVbb1kB!B!D :-jI0<'\ kjb x T\G#RgbeDhXd$4jfHlc^"ou(j2a_pj~xK,R;m6P6{Va鴨L0af4H3FjGJmDzM:SQөżDKI Fҩ&iC|ΠxtcƍKW ͧ 6gtFDõ&=c0,6>bFA#J:\{ Q-2Ѡ- 8SJg jf .:5 [Y@l,B! Z:qF7 6k| _ 8ܹݫ<`u)}*`%}P _{CQ,fwBVnTdۈE|ze;1MNឯQ 2`r~Z,ٓ9ke,ކ(|67mk绅Obq,]{G,gޫWaq:q?jgϳyk8=m9c0~o ^H CkyoQ/>M(Zuo2Zup++bj = 2x`@Q,9ڊKzh 0ҧ5j4-_t'gUfwsX)LCjOeUpF DC^v L#F~3?b+; qC{-A@b֏Q 9=|SgQrp#ϹXӈ1d[1 Oq+%V(Zw9SfJb|3C(}*t~.36+fv3͑īc+5eFnb%Z/l_5 <&Ir['oh&}GY?>ퟡ(2s{3fZsh5go04 CQ, g8)X`s߰sa5v(Xl`s[m !B!,|>֮]Kee%ZbҤIڵu, 3uClZ9݋yS8.|^Ҳ\jxSxa=6X,Vn}l~C ]Mf9ӱ\lZ&[V(R3aʳ vk$sXLZĥ窻dV@!5LC#T}hLg2u,^Cts[? | IIƝ֮2sFs*E Hg%Op]Kt8\Bq\uXB!BbNnѣGXr%Vkӛ(*l_.j: ۗPQx4hhOu-aIhG$Tfs*}XXN ,vlv7+ZP ڜ1x4D,RU04b q/-;bHFzVEmGfq^roMQWg}u>`B!Km@ip׮PD˒۪UvVurS''i >={p80`}!SQQɦ !I+ZԬNq}FFqZ<y 9WUm612,{1_$33m; _jTmjv(y=2t}tqp3=?&zFEN(*tw!C&܃˓5P01 gJ}κf"x).-M4\Ŷ5'q !B!nLl4B2~5vݺ{NRe 0z9t-WTT 8zNttxJD\.6|ӆԱR;`wNfi ]w6g:z&\7?]תilDC 4NR4Y[*nkO~?KB:62O8mu[_#-&>IBU4a:m;":@D~cs׎9` Tq|H~c1B! tЁɓ'_iӦ1p7T`n CbzHYCZv I4jRe0 LSy `qL#vLZnοMF\(+tʍo%53;>L[XA>^oY`b1Bb*Jv`G~mq +gJiM3~X4W[wPYX[/юv|զӬ"*Kv|> 27>4 0tkJʹx$N Vd;b7/B!9-:8 |w|>ڵkĉ9x a N}ٷen~Zsyݶ:3a_ ˙}+_Gv9:o=G9ʗ%@t#Ί%MЫq39{9V*#Iaت@2۱q?ѓ~-RY3=$+ M[l r{3d|ֵX9 2vzv]1x^p3rzqәԌ\pRY/܂C }ֵGޯPUa?Jv^_͚EX1utφe+(<4~:Y=8o^|wg1ۈ}}%x+ٳmڟ9ACX똦G5fz Bf z Ʋp"wIy6.MEełi|:tɪEOb}/D|^Zw@١M\r|*' jjgEQ]YlW2`Ǽ{/zM+d JL)B!ĿӢfAUUl6V+aFO6q#+)iڳNmU޴`˷kn;7sp7Tocٶ}`9k<]Ld.&^?B^rFsֹwSQ[T% r1qB=Tx{' |360Ӫ]ol w-]B_JZF.?H7ҭTm[]?`w,sBw|Uw",z_ȋ&"JwnKZf;mYș/by0hiGCm#^Ο?lvooNlf4y[Hn'%5( Ueٳi!.WJ2j`p [V:Ӿ{Wպ3#.=ZGnCݶrZv!#+,k<`ʡ}IO(^}_Ǡ(4;}g߶˒ZFS^ -5(•Xo4aۨ(ކRvp#7QUўJ7ўhw՚AЏ߼ o=abQxX]9 ~hPMz EQٱ_\űt(B!hYM .3ΠGtAbfwb;Z/*:?ڕV*dr \1C BI!)\BB ?BBB @.ދ$7IVVݙkYnb.}?ϳ+i39gՎj^ x` ŕKgD ެA[:Y%5x,B<{<_MwAz}G12r+QTh;Kn æ=pBP`_bswt;;3l]{"/II\0W IDATf?.@,lRTy!5+:wL0u2rٽyڏn`:hV']-aUj?>ԌdjsQ8h 6 EJ# Nふ1.O6&P4x h<x-'k<˝Exw)V &g_,oc?$t&?e?[r6.yw>&2r+0 ]^ڇB\#|ؼzi]y_yFz=a):7Xݿp ;)FVٺ7Y;-`ozmRB$=g+~Kw^4;|ަqX^%LER3f`(?LgK f]c!ڏ(}Sk>>B!zjgВjc/k2`p8'$ttt|0lLl6XByWvWC.f #N'+Ζ}ɢ6̫- JGmĢA&̹_z:1w%~˓k%޷GJ:i>C1Mь9ýNfǾǶUrF{ęAfPTmjsR;wZm;H,&=P~) dΡ0]"p8ٲ?OE*\=MtbbwUPYiJ$ԍ'ԌFOW=iJѴpWVQD~& <Ǒ}+I.%=_>~2d 3oڰHoVh@w6G ެ2Z o>iYezPT x47gz,Ljrʀ/;p _X0C tp-(*<ģA:Ez l)B!GLffIonm{Āx]2=n&?0ϋ`saOYGywZ.uO>Tߦ( vѰ@oXM?~|L!B!|@VQV]3X8^))O<)iytf?ONTB!HCY \ۖ=h8ґ`m/NLB!B@= FRsB!B!9r^ <~;^z)XLjO!B!8Λ`1MӰl !B!>H]2dvV5!B!:/8,**bȐ!kL: # LlrK&*M;wV J# T.LBrGA:&T;D]Zi&.N/#`$&Thؗ(Xܒ)Xl.Gh܈i&B=Ac"XK^T4͊_.DQTG>]XC%K^$Eq|f! t]L#fWM49:h=_>*ڥ"݉|& MW gdlTB6ڎ˧'a|.!g^T,V=]Gjښ̧7oV9O3ȧ3)ΖMԍY0x<њE}m'wDE~d>d#%hVLv$lO"x2VPo+m9IcbOTrKb3hMod$V@,vc]@NZl (gc!B!$Xp4Mcܸq̙3@4L͛O40M̼*͸bcǚ؛ X^E{io\O$4bɸDQU-rxO#LfH*G71e1LLFE-dԴ[qh:u-;ǂIIt*G_ݺ:PUƘfKvǛlmߋiQ5;1B? b:YUqʶ`yC^Mv0=-t4'Ns(5%a9t6mI t+iw-([iHɠn-[v% %CfR12x_vz:%=ޅb}ZTD=t4n o4t 2n潨-˟v!@Hg踏U0 D=F1IVICm 1bMx i?UMۈEFSp;PԌv./GjVu7z< ͠ajJoW=&9~7_fg~L@ue }t4'4dV'iɓ~3גWIOg{,Ǩ AAa=Ђhx1fi6줳yhP9ouz;Ѽ;b\pvg.aS =j ҡ<w#i[wcٽbuS5 JtѰp ӈS43EQ56,qpg=Y!B'!1-AI仚˚ 2X9g~I:&Jqq1iiiIii)6uqSgLQPD4̾ǾE0LLnJr@j0M 跟Sm$smTEIlcFYC?UOaO*mLO4~i i>]>u_?| !B!Nfff5znp8|޽{71 |]w3Y`&q`Ni~<6~t6橷1 %Smc|A|i)B!g9ib`XB!Bsq+Bmm-@ߐp!B!B|-B!BH@!B!'8/!I<(fB!Bq=&OfCQzzzx嗱RB!B!\.v;k׮EQi(B!BXشRhkkCQ=!B!8/C^^W]uԜB!BqZZZhmm4MTUo}!B!v^ 0iB!Bsq5 Joo/Amm*B!B!΁bO^^Ç'h4*'B!BȂ:jjj,PUUjN!B!8G΋`(h&%B!B|B!B!N 8C^LQ?7c/7g(ifzTT %LS|Tm$tp?5EB!#D#1Aj;Rc/{VVVbT B,1c0x`RSSinnP(*ç}>ɠW0h 09,ÌkĈ)RP2{~,V73ᗑ_2X4Jog r*zy"գN~,kˆ)7p8w\y "9Z,4((̏}!0 ƺŨ#y2 g&;H {= DQm R,6uc"F&Ӹ9œ1^G^EJZIϩb/PE}pMj x9U6l4ul/#/nDk ΀99ְ=9m}Y\ulWW<`gA ߌiuaq F0n Mw".8!C2⯣YtG |ՇB!>.bF<G{{Q2'YiW^y%B!vȡX(BJj~_#~_#V0 ՊZ];:ˊZ\hʼnP5;jC՜}1U64o[ I8uj~{*#i ӯ&c7;%w_СbdWj~#l./oZ6-C܁W5Y]j2_֊jI Us[Q-(ZK^H>Dh'Db1D^ql[+4kjl(v|*hW},ڮjqe1r {' d6PoF>n@3rʭd&5s2*016V+`'Uc䂫Gլ<̻)v;6Kn 6 ף&H7/Q3>mjsSR5 F(%/`?%1jÌYvaC9xQ1rNwte3֧8@o4v~N ͚ )'[͉ZEvGUeS\9%n`Q4hyL&YyOYάk϶nǫ*G_ݙFkv-9ν Z귐G2ּSNV kckߢE9IpD8>.*FthAPRP:R'gwZ2Ǩ1m'=LfA5P7v-b[|!4N)ƤK†u)(sƛSAmou/9]SHٰhڕxkc;hދiy/\- &RjV}x3? jw CL5J&Jzn%5+YP^FL748o)k:C23bo׳sͳ~Q\̾1a?ޜ2\V=zIdTB} V(ޜr6$as1<`IVOp޸ EkӶNJZ &&&Q+I[NnUM`,nLӤq'Cf(AUT͖ɒ0"Ψ0h,,@4Ŋ׾w~k;æE?`߾&kF^Q5@O}|c4Ɩ%SEzM_gMW2W} oV f϶c \&{ z:ٶ z<Љw0aC4\Gaof$=P13 hH)r u]gY/[6Kn޷O!vr_'pp/7Ķbu3|]T3sSxt4aԙFB|mu,}t>uřS^GY/G;i|} Z}AP#LXwU!B}i㡴ΝKjj3|>>z h ylkA.__Ȕ˾f uL[׮a0M77,*G^iPT ;уi?iRsi8|45#ݧLWQ:d6%~tfa.}̼*LLGhkNz TN<gy+,xsT h>>_@GK _*}>-CQDA.x|qk<1W7}W1re^}ʧ0tDC݌il_\X9R1?'2\+5L41;-/??Y8j*Fg_cweiӦ~|{# YXlD_~4u+}-EYy73L L0Y/3BVMs+HI-8M=4o3_ǩ5k&4֭fa;;xؿ8|\s;U\*/$3C}T<֋G1Y%!=O#`?a+9FbģģF Ս3% _gqi"'"whb?K̿T=]c2~ql]4v-X70M;]h[Gpxu( v񻯖G7N2H!;_qy *NKVf$9e{[f:M3€)d 巏T7pzEeȏQ:t6K^r✢&)p7#.j&KU޿ 26g塞"*܄i)c11txF sfKD<9`NQ_>:w2y9{/l`s+q)bg~r318Ye~~ѳJ{.FjbR5< IDATzn~t==ᘦA4ś|_|%/C8eH!BEQPUx<ΪUuS]]͚5kN:4Yw%O&<.Y &nO]C~QSZ t0X^ֽS.Wtwֳiϱ:`[ٟ%5;hؗ{lt% xⱐG/cؤrґ y)(>rU (XXWwG60wyC&F<~_Pd`4K_$og0MqFzFb|t=F$$ N F„CA"P,`9Ff0s*ċ`킟q`f]cV-`t6;ܢaNi{r4/'=qsLQu7܇'w Ml'o:/ΧJ'1tL_bunaSÓ1oUq ] 䕌jwL,V] { c]yhQW1hz NDedz.㯥|5[_}_ W*Bwg)*b=!ΆaمP5 m3 |S%3'WߚӬ (2-KęEZf)Qu2r+x+. nzf%WņE'} gj&'aMV æKv*G_;#zP!3)ɴ6lbOVơ݋6f0h\"scsSfpeQO4 &pd n =Gi\LQnjP4*PM|x#%1Jf9rN, 6SƐ$#wހMd x )ۭ:9{!_Dt+6L5oɡ ti6X&JM Wj6.OO"X] bcs7E8aSae_$-_:-EI:3,&_V6,1.(!BbCvZ&L멫;X4̠( (˙pسonyՒǛǘ9_cŸw\x7E4H,4zPX4D8ԍZY8o); ͒X{sǟ}ƚE,{`ut6cӒ_]*ْۧ福F05c^5e/W[FC*ms3p`â'غoq[8o)u Px$M{y/PK7~4MK~šoټ_\u.74ڐX(4عIR<̽׬ N<;~KvA5/0"E tg1^Qbg(*Ѱpw5Mphb`[lZ9Z_s} ( wgJ&;Ev hfPG48!o梥~ &9ma_px(~d8k[WIF:Y2mXO! 9LHHad;iY׿Y4tEZrdBߙ8ΕĈPG$ԋ͙ӝAQy iɯش'nB!>2T=仚˚ 2X9g~{;IGGP0öLJDhG *M#F)hִą~(qj{c=DFV>|8Rz cœXڹ Kգ>BAh '7-wG4b{RgqwڤA'd]ߍL,GEi{zJQѬA߃ VGYj;OC`DII+DU.scaV(JFnw˰W3熟cӉ t3N9:c6/6Wmޜ |k: Sd_Pg"w|hVrbЃ{3YiM'M'݅#s!FOGQ{auxO0q&6+Sm`7jKYčPz޷ҼiD0cy9!z#n˱HC4<ݩLJ'p u8\.L !7zpDUzvi14?X4;ovu8?1%s'ڱ%mGNG\7h4K\ZN\#$%9Ǎ&{|ÄsHpS DE>4 h4"D KB!VffIonm{Āx]:6W^W.E&X.{}uR gŤj.ƺlXKah\|)A+~O濜dTʘY0t zmy]RB!B H\{ ,TJkW͌ 1Ĩbx4q<1b(`uYB!B`E#BQz(WlfqxS-)=RB!B΋`AAA^a%B!By,(,,waa!K,, B!By,ؼy3[l4MIKKc(B!B!΁"X`6bv܉ah&5(B!B|ΫeQUH@!B!8GΛ`(핚B!B!Α&Xp8ϧ]ץB!BsAqq1V}I !B!yٳ;wbXքB!Bs?_( B!B*E B!BVBVTP$&B!87͆n >[^\E%h%;`a =z}\@aL#.Gwqo_:Ɲ,xaR0B!B |Ҙ2e n-[F8PY03!=E8 kCBN7jLnE!1,`q ĈG1M0`s9QD4 8X 5xH 13~zq ,}m}GE9uQVgWoYݝ`"=1bKtxGA%Q4:|XKSEjξmT XEKMXȏfS T+X֛aDB`&Y}eZnfM=IݸPT)iw{y u C]j1a,vo2:`/uB!, TTTrxWPU믿ك(tߊbaĔ[qyrY  4zS?M[EBlX_SĴ+G<|]mu~:2jdV`w(b˲j##o(=BZ@^E?C(Ø•ˡ݋ٲTMJJZ+f]cˏPo!j=Yf~ll<|.ğE,iHjV%/YCi[?!h;e8S2~}z 6lc?&lL&: ڷOkf}Gt68aƾ1fQ1rMl\ Z4t Ø OG~~zʱ72rhV;╇1oܰ/2jq8]{{`sel!)t=FAof?&D( &EAXV bS|Wxg0B!B|;::lQVVi477!P`b1L#'3<_)(GηjCNӁFQgϱqϩ:*4NA8R<9#gQ>R =N'AcؾL\BҲ0Z/ Quh>~΃؜[oຓ g_>KoW#K_ o>iڛvZ9,+_6q #i8(4 ¿>77t'C'7Kkf| RRУ~ʧaI˩$N};ʪߤv>Hj`L T`:YZG䈌fU2eYiBQ5TBjz> ĝ;-q3y97w~Ĺ_ g$,VES4+ ^x*NC?wެxs{9|mtB!,@477˰a:wUT^BB1PD) * mu]Xu՟[Zյ`4^!ޛMžwyNf9s̽< x<eM!;o\.^A&L<8b&lA0`wf,C 2l%T|ʞMuӸ[w1hF$䦥~+utuԐUpfiJ$&%k0ǒާ2;1m ;!(<4_w7{Wc <.܍AӈoOx"H@Wt@UbI CņhK;`8z.kZ(>@JNݛEر"NO43"3R=F3@`[)8a&كI;,Qʬz[\`D/3%m+t{-i͞ZWv :;i݌u3{}Hȳ,լD EZ`-<4MO&dfΜɘ1cXfM Rk hDsi@B<@(_!tH{vI4G4Z6bQ?f9#"`8Ѱ D B(aOBE  `3ŖJ4E0t_`Z˯֦Z"FhXB ^ F cĻ+ X 7Y FQ&~#4,] }!D40,To`[UT7#~"1pڅD,#3.7.RjA{X,~ UU1&g E# v_% M=r*r=ecPFWޣzjo`j&M&x *־ղ5GUk^rS,P()>Ԭ!-8褣qؓr;CqQk T%B,"w?hXO8Іlq+)yp&Q#-L}HGrMSC-Pal,! 4Uu3x*&KhѳN؝Yd+dv0x2 @{V9Ifn >x]HhXlx(y6!d-b!4Pau#mlXέ$#XT5bsf'9}F-qLJFiYxvw_gr+d3x }Cԏdlu>DOHʦh \U(G఼qqi@;v| ; 53v/yt4ll8?quqZPe>Z C@ w g+9#Zv-oL>> &;-شiQ/F1fu;fV.=;L:N>[:sӻp9CFKΖDU1'o^L,,ϟdy߬  Rg5-K9Hɡn[w<헴lđdǏp9Q8j IDATyꉆp>6g'N>cA}Q i.@K܏#) ƙVD$$w9Ѱq`j*#˟/; J ٵ_ ;RzP Vܷ.}i`:t8:?ndkn[bj?bkCmؒ" ߽ݞ)zxA& K(VG `;f[A0bO#oAU3-NX91m09'` [A1{kdI2A0sFU GJFXX"k:BRz1Sν[>ݶXK׈?EPVD4BqfwASe@b–DvT &;]8\-yfk2'm@;#u T!O+<ٖBۀ5ɳbtut)qfk\%Fw_(~켱,tDAGGGGGGGGGG###AtI$zݛ8 {UZTG4}ھmhh4 ǵ]T¾`kB]uMSJJ@Wu+ ~w:w~Gx;=ƏX 2R{a#6"Ce$]{F4A458kB[G{>UҖZ۾=`APX E􃴾wugbǏ"O2 _bY߿fff4:?~x WvG}-`$lE8# !yZq@OPAQUϏQGGGGGGGGGGGb{,0Ȳr-Y|ĺQo^$I  D `xvP;?.@CëxI5T)~#EL鎽]3E"pGQ$ѳJGMOoG[UUbX M}g?% bOK'MFFR%ZapJH݆ޮHDHb{\'K#j>⾃pZNP W[pzz~kk~$Y@|EA9:]Zғ&2H;ca]5-rL9߭P H,Kq-Οmg圔|7.# !I$$$Yjb{<3KH0D$^7[P B E{$EJ/yk[\s5o{lS6\.g7BB!{KrΨ%ِLP r}5| !(yd#l3vpRafm}2b)<EڰX,\tE ?iƍ#99w} O墭:'ifڵ|j .g}ƦM3f F^C$6o̺u# GE<+1? SwlP]qR-  _`LKǔnD˷`1SF8F#v/`2zpLD/!7B,Bƭb-AG Gb/əi||T9r$=M&фA0` ^Ve.a0#srf1|V^2JtS:W>NEawk.:GlKOë548 hL53s&7LpN ML#UL«Ҩ2n]{OT?Ez@+a7AR%(zBG!?Yn(LJ> @-';M$&!"bŵ8f_HQRv<{o5gϰvnɿi $!DD*#Do97>_nǿ~ } h\G̳ mوoGLMIb|B֣:H+W2{vߊ۷/6PtF;~\Q&# 书#=tS:Q%JU Z8=tt|BcrO9FшI0oT*xubDC(3 _DGd|qBQqE\G-cu i4>oP;k]kg a2ΜM鹿"X$%%ai|)t~pH:{U*Q[oEI:ruǵ88j_EsSz۝iɤ4{/?⃶XԼY΢=K5/5`*ZK㏣{MqRI+lk3͙t)]kk_1 FGb00㥽/ Pl/7%Ah 6TS`;34/<_DZBs~gϳ@[waot/ V35MksY\A0 hƜ9sp\]4xy뭷4 ӉDUUN;4&L@MM Æ KxxZ ᫒"?{6`C@H'3:N΄}9 ,,"IHzKUdTs{b?n7VábCYY,什n^X,l0zhVZE~(--墋.bռ˽GҸ;(,,qƍy'z XsN nc4IJJ";;bo[bygew#j#k~XJ -YvJd<l%#n G3@bMDw{p=$j{+=0dda;q"ɌvmXDmvC I=(8Eg{Z}㹚6UEu]llc0P54JJ6$"mE;"" F|rMd3p\ vrl9DZTHD9©rDv$Y"ϒǛ-orbKb1NYhc4$nQGEԵəy A[-qSrh:R}|(2bFqS~p  5M#//O>D9eM&piVt4f3sᢋ.⩧b͚5 l۶m? n:dFŶmOdJ7tPƌ󍅶;?fxp Ƥ k232fpq<^}J ۜUvؗr t{W>F̂Q5h?Do%#Ϗ³fqI'aٰZS]]{A qgsҧOz!'tSLl6c0$SVVƕW^=Ckk+ ջ e˖?WLf.$xrS&i=YɹFԹcJϤ ;'Aܿ "72/GXhxc=/?G˕HK?#PH_H ,#՜륯Sᦝ7*R/RR GcǪ3I,3d̙tMSS4A`CgHF'H;=^ՋKvlʂ+9+,|P5,3~xn:*** #GdΜ9_AXr%*:wu=VrvIMM vsIg>,X9s裏bٸq# /O>}(`ep❺w5G 뵯LZFci}qc̯ύ72"uY,5_<[,K:Ph-/!ż3|F,n>QGGGGGGG>@H?_ _333sFGp4嫠(  @AA|gx<>Cv܉`  !2.M6G!2`j8{aÆ TTTX~a娈"\.B;-/C o%ik^`2  WBhC ]ii"^AUDvn' ~5rC=BpR"D%\UIxݗhD Kʝ(- oɓ'_9.Adll]F]e֮ la{+ TTբ/cg;;.F1c=;<;װտf}zY_Nj/R&ٌ/3>1G(ĺ^ESԵ`$H[fs˜+auKJiB[ eOi[M0dU*^i~ES0aB^c>Fjj*fb۶mlڴ5 & U*" ((tJP KCT܅Q0%wQ!R"PA\NGG1@,@p% )*C%t1/+Vl6P˶6Zj_5XP+[}[ aW\q OӻAQ$I&ٳgx<K$~UUe͛7ijjߦAhjj@ uXpabpSYYɪUQJVh[G{ !Lpܼ& 0-BMEa1)}4ELak3ۨR+ǯ2h s=5vvSP233ꪫxԿYuttttttt'v{f3,/p\-zТ@hlu$, -}iСV@ pX4Mv vꩧ:ߜxYJLO~f3\s yyy}:9s|k1_tttttttttt~bANN\p7tƍK@ϝ;gglh;iX ,T0s(&ꫢx8F>g9Yɪh37)GC|F9fl%֏N IDAT[ Rl 44.̾ʙnev U3<w)1숽x3vd¬Y8E@&FLJ&s~A~ QK;q^|C, KwDPUQF1vXnvGM149ɰf`3PQL*<5)NYy tOgD\17p^y|1"%ih ;SNexpڣ,\Kv2>)q u6T΅(rX[g&ĝDCc|xҌiD(S3۷hgADk)3fnN'՘`OԐke|xTT dg)6[modNb4-e&l6[ᆫ j7r[Aǫ&TC1AnF'k<]e\pTrTK*ن=ksbr 0CvuX;cl}o#S0[O<SAjBGLK'_wvrBwv#Fʕ+EQ2e >} 2˖-*L4 B]]K.`0p) I;v젤T֭[w 6Rͩ 6,i#q-،6rdk#Z~;]U믢)@%>MYW Ƽ/6$ci4(O7~J)tK:hk˥&P 5/pK-vonuHD9Ts*I$&g"[oœO>98L]]P)Sk׮ԓJGGGGGGGGGG!Q]]{C rdYaÆ^G2Æ{} j%㌳iDdVĔT\zjDh(5{ZGDde?E0 77b/*Ɣ'0Ò7jŒW!E"`>:۷H3( 0޸KW5@4ռ\2> nzZ&;'fȟwwsa f5]6#Fraޅt;(10$u J3sװc(`u[ *1-ưalnӶO]Id%~!m圗w"#w3rfYgҘ=D;:: 3I"ĪU0j2&k [l*Vܢy b1J==nnCm6VK)M.ejߩ<[lȚUA70J6\/KܿCQ#!9fо_/ 1ļ]۟D;/ٗ1Xĥ.Tx~Jr'r_hb+($){+~?'NdǎDQV+~ٳgGyy9SO!{/hFFF-p0k,ؾ};&L ??[ yHTD(ES0 &>^Oiz)d|p%F 4R|T?O]bT_z?# "=6#zܽ\a,0RBXd &V‰"[lsg{%a:;;bDo*b F3w:|>N?tEr3ihMdg\G+ ;l&>=ZЌfX2&>w=-/j_GxĪ*{6tPV^#UV¬XEs9.-0Bο==]~1_ mSR "N͂ r Cޣl[6\L`wtUUyrF[1 fjזLy|<>q;>˶/Y)DӴ0541/7<0G=[JH "F0aU?甗:L,vb.M@PUQikkCUU{r6FѺR<7ahvhF"@QPA1gwCSETU=9 G0'W]E\j78 xZH315F1H;s ƉDY9@TS*ƈ:i%J9sytT+W= `h}ȪL%H N<1f eR֤Gz3͞\9QT B7[&D\;r_RQdy%Fbj9iZ^3G~!Wy%̽d㍗|a[[(GLMEтa/6Y0ʽ0JJU*fьF9U( I 6]A5TS*1- Z# k4T!ݓ%ߞϢEmsm~̂ҔR=GW@UςUmhrYX,dee~\} .sHro䉧]X}" t _30g`)UUU 4EQ#F~*q"NzJJJxٵkX ł $''cZ{|6*t%B!W_'H!YƀXE+Z;FU* a'>Ƽ D^~XqK i!z?fԏdccO<>'49ɶgmHiᏑdJ):YZLh9ixan!cw_ʯ E? FTΐ!lzs 㜜s(rvgmoy65ظ\RxnsG4ED6z7ɻ[ 4[n~q'xjɓ7or 7ouNZ,w ƾݣԊL| $s{]bQ"G&3f`Ot,ا:É ,]\$֯_YgL wAqRXXȩ-ؘHD}}= رc!8N͛DgP[cL >cYZ(LɚB=Sff18JmKyvH;L3j_JǺÇ'--O?Bvv6 >@-НVakfffhy >?LYDjj )Cdg9*X0uX B[6}HSSGfl۶&&:ww ÓjGd 즿? ZݷT1W^ŀf3ܛ8Dk Vzt5I0⎸ɷgCQ˺iM&8`7YZO}6]. USV@aR![[)ri $< jDQF'm!ubg=AV`+`Z4"r`=!6[l&HRb l n"Ϙ*XIo2^eJ<;%KY ĴiX`mmmfY\'}_CJXAb pb'0:j*ni0se4ڽ?>|8??j&$UϒbJW\89u2K$|LJSJg=Ti/`*I_N[^++"z*2$I'D$} .:>EZuYU]$Y wtB @.%~&MI!m16,E.lfceY%@A/Ev93+gyΤI7׾5ZZZ>u}d ͛7r#H([!B!8iV# ꠃ6M9DUQn9sGǮ'2hUSe4NQ_x /B!`ULBvv6;v`ǎL>"B,)&B!BKFU8N$t[Vv;p,+B!B >̚5k[[</oB!B~UEQ5 B!B,V/B!BAF]HB!B!ĻgT UUUl6<eeeiᠨ,i=!B!,cϙ3N*bΜ9is̡RF!B!h*oEQZXV~AłJ!B!_mT Ef jB!B!rk^!B!X Ĩ`db{E x/ WÓ܍@Q2 "K|ӰXDD"׆B!/`p/reC=#"rI"rh-P]]ĉ1 ^Er1i$&NH^^$j}I3?N^tb^bߣ?IDpEI8$~+8̥.fGPU ߓS1L3cb4Mxi59 *#w-cI%c'y}Ně)gR8nsgs9s>JNTmG[9jD=(@٤%TԜzSϦr}B!BnjÇill/u§>)9x^&U3n"^X,23uTԞ ɾUdWq`Głkf?CQy,k hӖ~9A@**~>Zظz%܉[?Kug.v69MY}dU.O 3%}~WWm/MS9O oaǦǨ[4YƤYpecl^cr1{-B(J݆ٽ=X̼3?GV_rhj,3.$o&t]Gn1B E)˩})ެqgHjz)^ì}(yg~ _xB=#xŕ2[jrm{x/YwF!WmD?jv.4_iϋl]m\η4j4tl+7?F'sÕiҏ/uyYoRP2p7?a%젥 ]h? m$hj#KP:40P5#B!FQ54MҐJHRNyy9XeqB~?A=݉5=?䌩!c^ Mџ-џ!Si=wV@gs=/[y[?a.7׫PU ]O7eYιS_߱q*LŴK3.u:e".~JoxŝYߙvzrػ}%r=- =5Lf5bs3u4ăw-AO%=cFڳ;o+;o+`?C$16R9s?/qϠj)kVޅ;UՈ 5 ]w_k'``K}OoW#S_ŖdfyYNZJAak4-Į-Oql~ט}mL$x;}V-0$c^]Kel}Lq2s&k~L\ٰ;}I昩r+ظg""U/AAdjFP,v2vT A2vU,{|2sI#Fu0M (0y; f-!X'4V?z;X{^f:2Q]tz po e0d4bhMމ#G[F|95{܏'HLD=j^}llىA%:zΖR1"N #!TƔHA?ZXB_{:Q5;iωE޻S"3nnÃmxسI 7~O.moo!B!w{:̚5ݻw0bB2Eд{ d x#wZcvV?r+f0tn&е$0y%lga& }Vw|N4r@QFГhL "FV8|cִh*ǽ׳ۊN"833OrX$JR=Jj^?^7L&0t,V'x6=4Q-I,Vf<F_{$9^\l}w,7hJG XIh4 ͣmyF UbŎO|,$?1ܙvQTXGZhPER(+,6<#3HZl2kAy =UUGlO=GlfL3}uiI #w(B,.1[Œ ?]0RG4QU ̾hV|F4IqL>}#ךņi@I1N0؇j&Nbuaqh]fu`巎B!@U4M#77MӰl|>EŋsaOFFVumPPdiI< &4g\;J&hsEzmOQ3 &/ҩ ES8 yM`o3%P8(NݑIO^zZ3~y3 4lގdR,nwNz o<üoTU-a_+{98w=5s g𷐈v ^uY4ӯ OXʪ!x ހ($Sرo_MQ\z39㪙vڧY?a =-=]mش^TKof5*PJO~j^ ~@2uͻ2:EIôL@0{g)LZFgfZw֗|6]?Rȸ 6"N6)!LƓQ@dKikFOΡ0( xL~N';VQX2C tSRu.H7mٺ) >3@DA1U4yh. {_zD=k̫"3gwLz;h9ӗ|;;VmFQ47v&K.>nX4Š 2. #17a)o.j6+݇w5 >ѐ7hoIvDN9k8Yj:gǨ{-ӗ5gz`<@B*|F*MB!-x7NTm`VUUv8B7MI0"PUM2$ (\ I%$"隵Z8:[ w_`u}4 b)\nЬU/9g«+ ۜAS{(F$q2KF={Mcw;chfb)4|tfSq<EQ?MS' f+sPg#D+ \ 4 v'):=h'  \zz`}ߨ ?h=sik PTTT"͕xȏՙhX`we&h#ݾɨEKO1MX018]0! asfT4k&X(`0X 3H D)"ɨX\C^q?wN7H p{w_Oq$xzoqVMFC9kprEa|:oc.;tL4tTU8Էg@}WL ݭy}O2Pg5E\}2+#csGB1=Z.Xg 7S}3;sOjުXY .gY2Jz*GpT(ii褓xjXx=crxU/2kTߩz0;w.{:UG!B2VC3f SNeڴiIcc#R\\Luu5QVV޽{G'f,hˌF0"0b1`/ xx슢O.{9 4Mz{{b?<$ Fb$Iv;aۋjEUU~?T vs7WL0?϶m[~bp(c F7K,#F jǡ8x!V^̜lBc$i7J+$v>x[f bAK1#Sabf#)~b{4E#0|k\Q~R}tǺy31K?AMf K eOd۾b_m%vE\|s77Yٳ<33g⪊pX<8ՁBkYٳ]ϣ]S7slB{EQL>SM!BjjdA{{;/===[gyb ߐqL\m(à;AToC~qr+zM(A){;=FdggSTTDss3d?q=ӟիW_qkkWU֮]ʕ+@4ロ3gg?w40 @7uLDS4ߝ]bf<:Qf99Xyd#w2;G;u0;;A|+2̂g8p^^2柋M%7<<|ۺas_q_SUB Qw;{wB}W=Ӳg;zŚ&D>hG S]]B!B|`A"GF.̝;ٳgFLh)ǘ[obK  gholjGPV,Krw9kIqGTTQ&t~fti+B!B1A)h(GUU.2jkkٶmې3ߊ{ 28n`' 3Dj`S4MUTPK$D"<3ٟ|n~LC@1 i$ I_K]JOrEQ6SAtSǮ hh57;B;hz1qkn "Fdбzqy%DB!B5F(ҟPӴvYY8p\ac/)%|K(V ւ1pھ Gy/@Zp-Xc󰍯»p)Wס8~&vc-AebԩdffdZ?{򗿐Evv6`IFFŌ;U=<|fѢE,U^˃r֘Ȩॶ^"F==Wx /1HLO aLL]݉n*ݕēqBfLċ/u% 8``iĦ٘9ss%ϑs=\FNBYFa%i&J]xk8%A==îRlg&P ³5 cp&~K?@ N\|[>::9# O|yҗNwT2S`5=ʠ b,CC'}ݔ "B!`Ayy9AAASL+vzYp!W\qs̡!G(\„PJ(Ѻ7PlvW_4c&\Oƒe(Fa7^&m3= *'y|M6qM7NRԠ`ܹsxfOS_mu!iT7śо۪nci; Ks۽eIZ/hTvŅmTfV?z^`uj{_+E\iS?'3SX$XX'<D'+FlSlL͚ʔ)Xtۄbw1_wz=bŊu׏ x <3SOgɟ"n<-$a$nu\ fW0:Q|eW$#D1̝'?!D!B!0FoD>؟< DQ9ˎQd-"ߚOLєhWJB!Bjd 5V0hiiJFsdTB!BRr5=h@C֒B!B!EjdAqq13gΤ[n:4"X`Z)--/| L8R.!B!B!;3*jEQTUE4RVfapvZ] B!B|؃ƍcɒ%x^233),,dŊD"(T ]IRB!vB!BarN4=ZXף B!Bwɨ $IGH$"&B!BT!B!B d*nRq?͎9BB!*X`&dT*nGӴcXg9 3^3<˓͏AxbB!b 3glݺףi,[ UMϚ{|w ~\Sj]Xl(`IG%w0k`)T_#B!7Xǩn = #ik+ͫLΘ)|d_x䧧J%( l}'Y˾āt5oQ̴E7иk-f^'yR뻴Jg]x JvD o["?h;e$w>i?08>h= ja˰ڼoðeB!BQఫ7x]=o&;)E{hX$D2&҉ ѓqETpys4-$]ڜLe  wC3ieXνdfr?bu=fټNNa-i Yv3ղ%~(n|Lv.S}+qAQm(FeE? +wm=) 4BQ,fzx ʐ2MI˘zw [J٤EX^Q(ZJ^Qz2NETͼ<y>6TIND.Hղ%}1SHd1u'HXnf\-B!B5`+n֮]K$|#<ÄabͪrŨ=/Ѵ!8)92;_z*>rupP}N󸽦Yly7 =@M+"VBVnr`igSlx;O')\Ew^\( ;1eؽm(={?=U^mhezwF>bc?=;O#*>LIպ7^e/d2Qp-k+@O_:jyزn.)2'*#gL  !B!$X0 uww @cc#7peeel߾}i8Wi6hJi6-!FN,x[E!nE]P40 COb (Qt4j%Г^.T ET"4C`;(6n|P +@$Dy{Yd痓W\bCS-XlN|μ ~$" "# ҝuwV+NuQ]]Maa!it:ioogϞ=C*+ГCdod}C$]T=/1mѧ8? **G늢2xIzJ(]e{b9/qֵfwqÛ(:#a"soG8d' 9f^LɤyԿ$ip`Jλ7~U)ϡpU-YEOik~QPGnAm`܄ETL>Ech'6LCX4&,g3riiJ4po : E*ϱoq*v( ӤpF!B!Ŀ/`J?c?Ў|-X,$!7FRaTUnBWW`(D8t6mPRP(t7bЛڻ$b~R8P/Mcɾ`xBuh$Hav۵W3Mx_JFH$bznCQ:mM[p{c{Bgb(D}u_1MHh4mOݶ@O+-{Wcмo=Dd"AO>w% jm ؽ$X% -6b R{PT=8eZn!O͑*{i$ 0Z<'0\wUUUU껏8U'9Ry4B`ggeEacaB:b [aoW]AyZ9cRpyzyIf11)ifmZV9sHRKdk,Zffr{e2.fg*+;W?+11,ZMF 쌳)6E+]ЩwĥqjO.SQ׿_@!B!N`A[[5557nPbɴcۙ:u*UUUqJPw32WP|71qDWz:uΞGoKY^x _DKbRg"ET?d //K]]]2x>9:::b,]K/ȑ#;imm0 زe #GdŊDQ:e]F]]6m"55]n鄌q+NPo\e;^z㽨ʊ\8-'W]ݻsh^@vJ6vl" RȚAO^esq{4uS.VcsaɅ{y){ ǿ׏'ssTWqGƾ> FX(SȞX 7]Mc^G#@RF @Č`bLd0BUU6nH$/_|O!B!`@Q4i(((`֭|>-[ʕ+9| pWپFӀDEKP32izL5-,D +vm2UI6mٴ py'> qƎKvv6sp4q 8 ^Gy:j` 6~q+g>-eueYkZw;Â|kڷg= :ήp?w+ˮᖇ=d\~䙶gp(l'y`E EỻKM|G{nǰ mܾvn};c3ƒGp x/c *:B}~8$!4EæPPh7sYeH9lpJ!B!՝S-'蝐M]pۍt]gLPU]P\#Ɓ 8JP8JHtuEfĈC{^,bz{{btM򗿤 /#FH$P?~9$`*8w{i^(v;F @ %%H;{ ##8==4F|Nxf̦ϣxHy#Pl6R/DOgzNGNfΜi,ZUVx3gSN% 麟4l̝;3f ?ӟ? i |;'܉M13ߌeYtE5bQVFo7ylOi 5L3qɂ.,瑆Gpڜl%sK-ԫP‹(s5"N8y8iܳl-w:u*YYY\RZ!B!1O]cY#9996x<>#ȻJLFF&L  rhnn q:lڴ]uxLGKˠH8K {)n" 8N&jO]gj%z%3D,&ƠoI<'55)SpAFyꩧ0 #YQ;v,PH$B4Sp8z4McԩL>MP}ϞW'EQh 0&e E"6uo6PξXXtqffͤ]ذ1={:{z01m":6H#XX nٙ5FރSu۷iӘ>EN8a[f%۞MMBTP3Q',P(wYz?ZC!B!<ϰuCÁOwuu:fɓ9(X08@ h@^^^>r= KeYtww:*Gl˸2Cm7b3=" 48hn+ॗ^"nv^yV\yn馛#c <ʰvq\)Sg;f N[αRRR8ٰaF!Btl#^/h@>Aˑ1(xperE4.-~"#vEQb477q'kpm?O1Mtw~a#LCD P4}BߤB!BFqmY. H%5}9]8t~++@rB!B!>XR- ,²,EIfȺo_[|)()i B!B*XEEETWWS]]̙3~S]]߀B!B!N`"HJVVV5Ass3`˲4ym6 !B!`AKK hVZ[[1 sKmmLy'B!B|)1'Nfܸqܹ!wO!B!Ď3h4JKKtAB!B!> ]`kFqq1===D"sB!B! 8NƍnPRRz1b4MsB!B!ĿB ??ŋc(,,d޼y\.,"''ǡC !B!j6~%VUÁ(P]]n&B!B|N`(\n@B!BSB!B1 >HBjtvgi9x3ǢVj'-8\Y%,<asN-Λ5ɸRF {Ýӓ'+B! RRR8383),,LNh&̞=Yf;dZrKfbYFUόl- IDATS2|M4>i䓟{1dKFg=(ƢKK.!9+-{<'Ly-OI͑ԅJ@S,3qL#e&- =?eOM¤90i4_˦J4x{#;7?G<dC_q+3s=n~@QTLig@jf =Yt7nEZV16뿹y 0kmMZ٨^˛+D"CA!3 [E!wMfn-u[X VNw ͯ\탤w.,SGXx齔ϸ îd3Φr͌|egٹ7zD# !B!#5eТȢ)laOʇeYDQLB  UUb1aƏO40NF4cAb(6-XO$ňF'p(z`90L ص7aw޼`o#;d\\+ Dy_II?9ͫ~ipj.U=KÁ/c_%衬b̻{Gio؈ÕMye.^5T;a?z"ul\t7-{Y)[}gwTpwyH: 7m>eE9R[V}~șcj73ad?}hτOڰh-~nL0#RLJ/fwRWBr RHaXezןƭNjYIB<ϰ/? 6uO~HtpVUCmm-1vXRRRņon:*.f{ٜl]_%`JHoW vZd?;lDo+aŒKs8i]^Ҳ8\vw:.}-h6`-͙̿ݑ ӓ;#ܢnFS:a!,i8@x #‰děMݾu%ph+:wնQsh9Da<?ch@HIk@JF!|2sbe3YE4|QB^KqɍTU#=|OΔݕwlT2rG_ а5g\'=ęͤa: =̧6Owx#y73)xGSioMWfAKf;p>ǻ}x3PUƑ'-E~8E0x2 ;@NgAO+B!#,, ˲͛7c&YYYL<^{m(h9q( H_2@ wړwٝN4{(  YϤY{Ifћ۹ߟ6L]}q ́iF F<ӳvh E#W<gJϗcYj2Aeu2rr&ϻͫ里q.(ֲLT͎ ((ʲv*^  ԌwRieiS7kvs;b\qk/v=c 5ꌋ9clz4n|EUAUa$'σe=1(`fnH+̖fxvB!B984LTUn( ˣ\~IϥQ6$b!H`o+@)H;fs}D,B,CRuf;c]Azv@"}XD,0ClxR0u{.I*tBFN:񋨫Zxo5L=:"!FZŘ_vc^BNA3;v0GEU>Rģ̂͑RENGL@QT45.iŌtv7)9ד5Q> 4c1%L`ŒKG%t;s`s2feX޷"fw @E.\tzI"tTW??7U_<2 =NL0M G͘# R 8R̦%z`YÝFE1cMl.?U4;`i;S_)DP!Bq~i4fQԧ>&77cR[[KSS^ٳg3j(ώ;N}BE9XGֿ/DO$8 F%?LӁ7|Ƨw18HE\zSķlUL]" 3sϻ 3"'M'5sZM<@_Og\žM?(*6G պU =+%IKCQt6oc'4;jNzk( 0i;;LvasOϸo}x7ysA_OZkWuE\r;-Un^q .u=3ιoF k 6 3XD9R<&*A[z3n'\|35l]KbG4c\_bg8emzt+Ow2vlM9r i"FW(XF"`Ҝkq *_+&.&5 p MO.J+YxHKӁuL[%.#L!{xf, wj1m[JƝ_dֲdR o6f/ sAQ D!B!>B>1 `ڠ@6h3].CYEwwʨidfUU%%%]דc\.4Mn@" ,Qˉ:*rhp=ieĂ\ޡFh RT4{ZC~l.'~y5AJE=wHJs!B> (he?8|1b#WJ6ƺ,(ʇ>a 6 )^ԽhL=H$c)^Ŗ,KSNŢfeDbJKAQFp >t0:(ϣ H_<#8~}7pB!B^ x^u[|#cPHk aEn _~/.O&پխB!B9X`Ee;ϧbCQ4)!B!'vGCX>\Sj?ڧv)!B!`A?N~~>#G$55uȶtJJJ(**pnbO#ZXXʕ+uEEE̝; ~߿(=s9!Ǥ1o<.\H^^^riL8ŋ3eʔi2m4 \E!B!8!3e_G4JJJ1cFFYr +ϗMt=`YX~rrM׷w1(*'?}_$uBptDQn7x˗i8Ng’%KD"x1ir( NsHN'NS~B!B!HLHoo/)))q.\H(:Gdg}/>OimOw]ײc 0aZ  '] +Y&WeP<H$qE=È#,p8L(fvZ^x.o| (X,yNC" Hȯ@!B!UEQp8(NǃgȑdeeQ[[FwAa-|@00e(>_ _њc6lǙж-[ cl~ۅ-+-+h餝pNkxlEA44MCUUEa,^h4̙3l444k.rss4iEEEL2 6e/^L0>zzz*..&+!B!CV- Xt)xg1M9s搕E 72`ZX@+O4Qh9j؟"C1|גÍ\vMw~Лh}zƿχN:(7FGu{E~wžƸF%@MM hQFaTU4M~3k,RRR׿'?I{1xGVƏ 7܀bռ+ddd/~?466tCmm-`P~B!B!P'4PmS~d3].CU8-J67TUr#y>xIN-4A6(*@%2h{"pдsYz?  U':u*_=rKr,#- 0M} }ie%)MP]ׇ͑ ibF%%%}qa!B!GPvv/ѽ^/h@>AIv}#nH%|)GOr>'??r"8Y?m7eGa? Ma֭FR?\ W6&yB!^B!B?jfFW q8رCO(+!B!Ò`J9!B!H:G+r\zEQfKB!B!>˲3gvz{{ٱc---)--Ų,jkky뭷ԉB!B!8Ӫz `͚5<3ɓ4 &0rHV^4irB!Bs@Q$ ү60===tuu%[!B!u phF"'';wbNH$Bee%iprB!Bi7wѣ;w.wXE"ngك B!B!>QF1sLmFmmmrfVFX~H{Y&F‡?ywZ4" !B!iDB$!t]'}P2||>}>,Lۨ 01SΊ[3r'2f L#DřgyĈ޷FO,wdLyO?ld˰?R>:'3?B!B=͘eQYYIyy9lقfh"FI `ʕD)e PydL"̶~E] 'E\g ~Sv-asLZV1}T4! Ç8i$)#5#?bwvM> i6'gN|Ow͗~ƙ~,KGӓ]JnāgNB!B <7n$ qYg1{l֬Y(twwF1bć:jsqwZ5F^,b(`qJf3Jg9|hi9X;I.aܴK({6vdySL삉{=ϡ4Yא[XAO];sy IDAT( 6l.(B"`݄B!,ӥJɦP_70 ʟb$ /e 8@'Fb. E*)DLbeeM/dƂ#p_ S,#˗a{Jw<Ui,Yr NW @g_=i(YKlB"NFb7(JKa/ S1yEqRpy,8)8=d攐Yp݌(eh6&Üe:4"|ݍNߊDI4؉US<9nкd!B!V- TUŲ,rrrɡ}kM`>娪ֺtnᅥd2R3Kn 8b?3{-XFGKUl\Ǭe#vR>J6t5́/S8Kh?e|`2Pmv7dǺ_b: eҴIΘy)^u@<]-;,̼hvMw>R~Njf! ~l|n g?d]ML#ة!%~/j;i'3ug9l]#XA##o2²J^Ӎt5oCQm(: ' o=^ {7=t@B!B|LeϼyhkkcΝMg6;d@Q2ܢ "꫞=ib{o(p!f]Av8^~d7no6Fɸ,ӤvPAahEmft;(BHzaAJZ=H;S҉{ L~ )͡L!B1o<:DUU%+(ʐDMEi+@%Dǖ?EddD4{ 'I.NN<'2ul L#(( zuTF,J 4܃ %}S44۩*;SN$udE4#R)TՁ=lX0H*B FPgOÓGB{Wޱ^94Lcpaı=X&c^7W~UQ̝OpTZӄp oF!Óӝv`i?,E<D{0L3B"Lh`S)zoF1d7P;E(OZYL^t{q3`!B!*X`&-񐟟O~~>===رX,ƢE"==:Fw e-.P5g}N(1FM/+n蘉0hط j^g.BͮӰyęW_aaTՖZ)1|ÑzyigOfxv;:d9w=Ì_!b_ 2AUezL}%`q}ټ'lVtSo-/"{18]H@'P@(݄GpRu'8ҵ{\n3zEXkzW  QTwRX69bZ:@:m4}YKo_`,8iUsQKHGmOFsiYWUo>D[kxA*wR3Kq{38c/H{m/Ci}O%YWVxY+8|h3=mNC!B! m `0\cY#9996x|Jy$yWq:FbݍeYdgg $ ȲLB$T{7=GZiۂݙI"e-51(pV, JjBfBV.4Í8ܸ8]shZ dgh> z(*=ufżip.ZM,$i;h{Qm qq;P& jv#zw4#pGӁģ=:v59iXb:vkE0ЇfwQU:7aNWk5!1ٶ͖at4m'=AEYuL\(Fg^Agn}-$]{I$L|]>s`vG*[ioƭ$b?fAsb]mlzQT=5膉Fg.n|5zQmNڛvkïaTELTIk0QUtFRn"!S) !B p]]]w>X,0t6A6(P Z{yyLP0m-w+=KͯR B!B!N*;;{`%^W]]H1h9<0sT)C8As}RB!B!lR`o-;^iR.B!jY`&Xh4Tϲ,Hx<~YNEu=\>ޙU}Y33I7kKхPZjY ~TE/TJMҤ͞L.?&I6M ryk;sr'<a6|cd&>@4 {"g͍?%1}>T`&-bG},J_įG{Q~lw${*[?>De\Ăة9.}7 >bf i(3#_N80McH)s@ 0Ge]ŋ9s&VkܐKMMeܹ|k_cѢEdff~"  1ydƏO,vj 2x rrrm/((G_[np|v2;m&ANIJ>|8'N$!!w[Lɒ K@P2Rw_)aQ,iBfә1yjBk!˦,ٿxxÜt.ylk09E(9XiZeCF$8IbO 9s8)@ %6L$;;ݻw 8q"SNw%77.C^^cɒ%A?~<A֭[Ggg'i"2C$֭[G{{;1cƐil޼:$InSYYIuu5#GDQVXq(**ٳgXb$o}X,ƣ>ʵ^KKK ߐ08:,˽X 1.zW&"0 b6q \Xjk)Ng"oA .۴Y8Jq>Bb_8( q(IHCxh5U In3QD&ClSf`۵7Á?5'DEE.͛7VeW;q.8`WHH,k]Ǝ&+T$T0;j_#d2Q%Tk*;ֳ+ 9I3Hq xkO33zU^($qUUXe+Wk"YTR(C߇ CB.ٙ4P5cEOHH %%Çir&qԩ|>[Nqq1s3˖-p`ِeY B?/fԨQx<xeEQ;9묳x1Mʎ;Xd ]y=z4v?ٿ?,3vX<NW^y˗3bĈ~qnK{aĂH$2hl˨ ϛG#?\.$ d$X Do*I$z?? ~{Lnÿig6:M|ԙv 4CAo묳=XG`).QXL#HҜsɸz܊Ⱃ_#8Gſى;K ?=#/ofaL3ԟSh#ܴ&<=i$NAeM=Qfzt:bfʔ)a֭[kѣ_Bv"KD,0 J^^'%%EZZXbTUU:4ML$ g, *PVVO,Bcܾ3l?eXh~V60 $k0.%-AM@I!J`D4 _x K҉nk:C!pcrnw9t?_qͽ)j7TU=Fp avwѿ%!0%I&XCDC5?Ij02q$7H`{C3?{>a=u Vm&bFI2B=9;D{.0ˇ^N= asI$tt$$bFjbFqoHH(97zx{b1峙|ޭHšWe֗$f̿"!Dtpcio:@4?Hge޴@a!DÝX8=C3+xS 9HL״w{uU$KK@44ne$gpࣷ0 $_KѠIR@knRG0[zœpC &@ ϻXr>}:]]]^W(u Yv->8N\.׀2ϟb了7|h4+]|$$$pM7#pYnFl?zk3˅v[K%W`:7]VSMڏ@>roF†ab:qbbDϟz(HmT}0?6$y6o;ءZbqab#q o6cAr~'qC=q޻x̄X;ف-o2tweaB-ܼfvvmǠE3۬z?]w, $Sؿ%l[}Hݮj=uabQ] c:#gѣ *XYY֭[III!)):|>߀emٲ={o|"dYdɒ^Ch)((`,\{390~gMyy9+WСCTUUqgEAAA$V^{w0GBw$Ҷe$YFom̓igv.gŒrRv̠ !8< `\x7|=MH Zw'MCI@; V+۶mcԨQzR/Fp s2R],mZOqN9P$.-ƳMmmjFL#$Iܻ^\ L~6oN :~_n&ǝ e/"͖vLCi s~OSC0s˚Ѯ .qc~_S4MLų^M=)8nPFJGG4C"fM+~sE3?;E#3o<ɹ77 B[^JǙ]o$a;DɘxʩٹHp05ޡblY!#t1urּr@;mM< 'a9e_)J 3D[i~y)=響CTU]xtNFMuaa!^׋,>|4TUvzx<|>:;6VUU^ ##'t:Yr%Ğ={x#FUU222ؼy1^ DQ&L@~~>[l-[0tPJJJX|9K.=aǞ }_b쟐srIr37bm8Ldv0 \QW6رоĪŊM` V4= C nXqMD"vR%-h޻nj9farh 9)%D3! \z/eG J@t vO~@÷cut ô<0'pt=,GaM{o0ƞdYtot {Ɂ=kM3ia??ȚcC?~L]u=~fH!^4o< \~O< K2 f::r`xo7[B:ΞWޯ1sL.r~ `b=1SzkE#>׺=g 81M$1f"I@"13I(Ջ4Gfaq>}B@ @ hk\.UvZ]>AdV1 3?-IR?}r-DRd!Gŀs P@2Zs!1IPuǣ h /0貐8xVPPX01q Go;^}x9XUb .]JBBaZ I>q='o:tHʇo+r鴹PTOOdq@ >1-0z|0 NqBDׂ%`Ş+hHm#(VP @'m_&p>;FARXJQwـfjė((,EYг`nGŗt$15][2>c윟z>Nɶml l:B{9z¾d˓ACX5JSKʧIt2c{|~\t >jiD-;  U1ا^}`1@V8<*@ps8g„ t:inn4M?~Z$5)' c#K2神Ƿٗl.R7> Sd%T$VP]k?Ƞ۵!;yۋ/7qI.-pMѦ>m_xho$Gik;B>\{];A HDdz;hL@ 46>݆aP^^NWW 3yd$I"!!P(D]]p?>6M I$F'&ӞɄ $Yy \'~}빮:~^sy7tV4rf:i%1#X%+ y<>ql+Wb;A/1JmdG.\J5r{9y<52 J)dي(`G&Ib[1n @u y=4S;cJ*LM%{}J=:Ry]V7OMz|{>&&6Fr{9~ s 3(q0> dKr{9C,CN-`lTV0,q؀'+ɔjO=Ŷb Zr(LI^Bd82I_@-xǒ[2ԬrJOqq)^diR6o/ޮR,Ј}D>~&Z$]NXN bv[CH`g=OƃaTm:Vx;ZMv SZq)cy̽:pַ;d#@9 phZ8q"u6dʕdgg3tP\.Nk-PP{Ď7 r94߀,ljĝ;$dcNlxenuۀOOD[%$} FjCd3ȲgqI%[7vddTp#l4S#d8?;m622v2 s6ֻaE?ϒCUJ=K .U9LWblHHe;^H"W r04a(^]HO$Ksukc[6R.5܊ ;6'pFw:Yx-vvKC *ߍ,ɼ޸IRpEJF)- Xb"$cIBU.+mcRJ A@BQ,8=AS4Ezw<5C"@ !;St:yuIu0aǎ\s5aP0 $s8|q#^ŋɾ>j[jy \삐Bd @35$$FxJ`o3ɕ.Q5^#4Yݣfe|m׸,2R~z  +l7Mɪ'UU`t,MaYq2LL0`g;w^f|%+\:~e%K2 ?#^½CeDʈ}^Zōfh`CqC69.Oz<ωǠ`樂twg%HD0M+a=ayE 4\ݮ?oo5pTM v@ s(ɴiHJJbƍdffioogر3dn7 B( n<jL)9ɀ؇y ڣɚC]d("5/"ߙOt7{&=ƃ)eS*]~ORC&ɒ'!ڿr;98݌5ʋ /bllƗ tt" 4G-YJ3$ә6wnߡ88otG:?PAKZrY^!1)g:\M̌A-$$**Oz9dz޹dujV7CFyG͖7qI.F/|9N.=qW3c ㎓b^9|j)ĆBGk5CP=bvTl HIH.&oDQh!d:MvGh9'KdUָ{ 5;ߠxϘvяݷ!mk~ǓA @yIh\. (**"11@ii)l6{=jkkX 8.ByE"Efe/km+^)„B~g,o^ H=;wp~,YfhVJ[>.Vǜ9kCvvse,]ڢmm]SqbE |saW.vmejTCl@jgMu6PW ‚! XڰX † v?a,!q{|X$  y.vQLÏ?fCl;2Jgom6>h`4/շp5-*9sX߾HZV5cTIew<2f17k.srN9<yV-z2ܵ.6wnEk3ɕW25ZAAVe<= x {AZwp+nn7XG!=.(7 Gf~t%z =.م*((Rh-][|[#$eCVݻD]<dH I]"Q,`u& vkZ@uY>!@ 8HII6v\vڵZ#}ă<@ Hn-9 !,ቚ'O=~@ @( 13v~mH*.u$Ib޽ @ >@%ϒO|T%D%VS%HW2hZNQн*H_(EAV,DCm"EjKBuaѓnݕ L$Ј (@p 8mR\\LNNVUF墭M-pVYD(d\aܲ9 fdV,L92U̷Xrh =rҩ>zGnq+,|A~ڂkyhCT$WN;uW`+`F tM3 7P@ЗQ :Vo{>Q5ʳod"+Aq% e%?E wT=٥gs2auΡo#B @ pxxAEEEuIaa!l޼9())a„ k.VqCy'ǞÅqAK4gCC(K,CBbW.tY*[k~Ɲ[$ >?U %,_^GEO]4P`13F+ø:^{ vr}t6A}7LۅzU8>qyZ>hP 5G)g0>˲Lpg|{'rZPmFNᓮ›ϦUO|f|̡y yR2Q<U!è8&&̺ݫi}PxSy[Qvz蛆tg;yc 7}`le?[;kU$_5N*&wY#xR :ܲs @ 8IEEnz 41c8p$IKy((lݷt'^KD&!aFZ_؇KuaYw39u2rnv3c񇥧PnQ1sfÙV/l=RYO")3݉$ˬ]7$IREZw .>m[Ӈ2a~LL3FN]ǯ~Zԏaw.o%Z@a,οۖ{D*I mupp;ؾ sA9IL-$DB;ٷe&̹fc{Jr|l@ b(TTTPPPҥK b!??"v;,sYg  xn&&{ /}@k~D38bL]앳RH(4 Yei +vv,C$MHR| W͛~ bEENXݝKbJ>Z,7Y3H[V=® ςiBdKP1lX;j9W>$I&H7%CasdL6?GSF Ÿ3EV}V #64%yB:9벇q$xyo7 ?!jo]H`"I iģ&y7;Eq`Z Im@ N40ayyyY&~slio&O?4O=臨e˖ @>BZA:VҺ" 6'gUWf8U 8'6vnXd n?^',^X OXOGK㦡8DGsýK/ezAv#9-gZ4m|G Lw-կ!#;HIMs*e'Yٿm9^ YDqO%g9|' C'@>wrtݿ,ė/X'?Ǧc3M֏՘`0a[Vl6[hZbgOpB|8Č{}+Wq UV1M썧N;{866xݺLL>4~cPqC?6j! 0jFYkUk妍7ѦL2kz-[rc.?6I1 `{0ZG4.+ )Zucs9i tbu:11wR$ =L0b#} DL"t ,v0 PmvdF,D8NԵ."~z}&@1 nG =)))rWڵk=w w*fe\mb"+6O~Ë9w!."3U7Nq6.@ ay moFZ khhA$@ @0 B,nՍqLX/SiZ|9'R/cbV6>tlθIԌ@& ɖlkpgȊS@@ Si3pNVVwb!++lIOO%;HH.۱H&&f~/]Mgkq  M6-LLddRԔN}ʸٷ`Aq@ 4dڴiL6ٳgSRR@^^\pӧOgL8X,&Ξ2g7)IS]$I3.ͽ4nW\=c*[10>|1>݇I<` g~_N%33foOn\cGqǍh}m$) 2Q I!bF?d>Kd[r}?ĐISyHn'ۖ-(ѓ*4 zG#1%Az]F$4u ph } 7cxY hv~ÑX,`LhHYLQT+$=_R}kP+!Y K,$*z-^y())AUU$I_|_|˗cZ`bbFX#{;RX39e2﷼OXX^ SOm^ŋKq!s8 o}o=6.]z{:L%!<5kh G`-Ǵ4c#%-n{wQTǿU{w@ @"{@vDD\fT8su:^:8.uPEd %@BN{UHIՠZ,u_ &g< n斧vR0I3oz?r19D|ȲʕdY!ͬ{߹_?c}cs(HrQάypvq/w6z80!7k>7-OۣaS5]̀KAWd3VC[AAA  q\~t]':Pe]ٳ:t Ӳ@#;;h zcH ɦdc_1%݅3䖍nO挛hhns)_߽GeԒQ?1I7`ed35ĂFƎ_EqRk4۵z=\?8]W |^h0fB~'j򷐞s>$4T ]]5?!+Jˡ,~u+͡(F Ds~=#&ϣƪMh‚egOJ 7u]e`lRrW~km<ٝ՞=X׹l^ .zl"bR1[[qDw/ z tY/ane8k$,*  %8TUbccYv-R[[… z 01cP]]- w%#B`鶥Dʑȼ_>OO16f,(uy\r"sxp˃wgILCFFErmCeT]^*9??9O4cGe2Zv҉ ],u.!;9QrQ"ih Q~$)[ v,DdQi8Ti/-UՐCyLRزMɟtY.FU,yw!g5أza0ZHǎT>d̹ISnNj;6-܂)۹ݟ"NnJ25{3~NBL)<5 2݊}xJS[pŦiEime( L+$ p֖  kNvv6믿EiڻwoX, :Fcc݊#3''$n&Ln3.~Z< KNm@gI-ȏG|/e~=ŏ#ɖm΍7/*.mPcZ]UgԐ}) UVic.muZpfZ;T[L֏ٿ}A[M{T/t$vog^"ґ$tMe`LV-xTFk~F]kEW$bZ}`"2&5:蕖lo9ԖoBl ={ 4\AmZ]D'dDAA 4McĈ$&&r_s=DBB'O+ '' 6PQQ!>=([@ܪ@T]%cĕD#y`6mrM7ys|.3ʹ#Npx"eAAL]]bddd nxw<~|AOdaׯ4 }GtzjY_ʜ[gUHHž,|uOf}ͤKL1{r3|fz d/ML|:%?f:ph5kkCv #Ӣ**##F򋾿jr4M\Lj#yXf(g-d0to>6sıȊhCB躊h9P] $a0:LQfPC^ԠI6`0:djȇl(-`0"dZ5h]G6XTȊ $5= Sb&w6  OW\\\=>ﺒ @߫ݴ)^o @Q9 Ot]9A8Ȥq.}=ԃ]6utm2*vt6=`၍cQudk2v͍jzfJrؓp+& ps 0>4wd: PuյAʯ[ \ݾ-Hb{hn)  ճ@AZ6{8X ]SNAA~>= AaAZ[[; kA;PNt =vtfLD? Mm]Y 1I'kF1 3 H,Ȳeth ?O$a41Ȳ|s& tD1 elxJ۩:>< *P |0ǘx"'6S%wFRԃFČEf~ͤ^`t|{t~ô^fD5Aӳ@uƌC߾}1L444yf'33N]]~ii g#Fp3tP~m?p8e;3ǣ:K,ᥗ^d21n8ΝKjj*%%%olJJ կ>|8k֬WȲW\3`ݺut5dxL:.d裏Xd w}7ƍC4/^_f3&Lꫯ&%%;wk{n$IHNQQH=e HR{>I6~誷uVt͋گjh] ɦ+kdz$#|r?ZGZCS[ Ik>$ł$@HY:ooJvTSHSG]WA!fP3۰X#;~I ώ4ՋMDTFԃ;l 'eTv]C׃H]Щk-Ԃ~7Ufw=$+G\:u+ (ƶd8L $c{={AARa7;wܔpQ uVx{Bgl۶}ׯgu7ndʕ455ħ'`4ٿ?TUUzjF#gf<l޼[nNmm->(SL!11kמ\`b,^L^^]w~!o6/iiia˖- ' B{t3o֮]$I477sy!Il=fZțgMbϗ63ay-fk4#y-LR;M㩯*&k&=-[jxD&b'pר5#s_]O$ggœ?0 2̶hM5&suď3|3pM6>&Acm)^W&!5_quhԀ q֕ I `YW?b*|[7k2Zj˿]G1>?I˰){$JB.Κ|3b&.i WtΞlKj+ n!1m [W-%6^)P`bHz{[C3A#bG ̿}_)}+`0q`RFxo%:/)2pUB0JFT45Y*!I%AG=Oٺyo2B544Tі c.KĖ-[vmHNN^z){B/tSPP۩]v1n8Zh6nHffI m$ ɂ c~mۆ륨qƝp چرc455z;v,EEES\\̞={;v,QQQzjظq#YYYhZ[Oyy9} #2C &e4Nf]cX'*q1|Taiơl]%oH;W3t]7=+Ojz(h42ڎaW`4}ݔXD\@j3z.]ͨ&PVLe,XwЏW2pet=q{Z_T`+4ԠCf A4MbX|Y1g@bFֈѵcdȘ|bbꅮkXI jC}%=DjȊ#Y6y66{4̤4-~91t̖$,+ߑ*#މ="=?"9}8FKڵ#6x Ɔe/r aő'}[:A.  ~JBBb!55m۶j*Du ]rs 7r`0`۱X,<\.N{ Պ$I1w466wr,zjzOٲe @<7x#]w---b4l8x N'`@mm-8z&_"SxĴٖs~Ô_d9-G]ߏjǨ~;BGbˊ?`Ec5ILhh2EΨ+2f.VWnN"tS[QL~#0I7-]Nx`M#-|5[Bَl ̶x$I#.e(o#?7x:gMOi(qg%1L92K΢Aվ= r@6\Hch!9d,k>6<Ow)^̼TQL':!DžX)/YJ#d$>%ؤLkKe 5R}7x:E+_a׆T?TEjƪmT^D}:PGE7\&uU;&vAAFzz:ܹ]v:RSSþ}(++Z.a2Xx1_|6 ۍ<:6 s`ǎ̟?ȓW7o/keҥ̘1|>f?%K---vZ[[;Ef3 !N -ڀ5 uωٹW7БH2j5cEl,;hFžuX1$lSY+m;=AQv=9ωӄȊ hۇȘTvs\;lb٣9DΨkjp5U|ЏX@-@V HL6Z[+P f׉XhuUcFqpfd>gc03`,h\M]7%K1ld'YpN02++ H2PD^ Zy!I   ?T`ԨQ{nEA$jkkZDDD`q8'~bͱaIPٌ$IlݺAQ__";;͛7x(++#??UV1tPWM&SNe]ɣﲲ2F#lm IDAT޼|6m ""/}ʾ,uߏjh4e0h hii!C{߿?T$OEE]{ YQ~0U[Mle.|m_i $uY2C'}Xy)I'U }sQ}Y{1Y Pwm=-17vU{>CM y bjW!/˞ƞP[-Б$ C1Z)1lŠ0WC!?eH;47ڀh!whVt=tDCvKA 6u<9pT[G߬W F3 UۻHPUZHZxvo4^'Cm #CuP[R`YEB#"a[tME 0Y"Ua@$ "XPUqK~~>_|1&Lh4R\\gB!E#G 0`9򗿐̻K}}==ضm|ne˖dz>KDD_}U5\Ô)S~EFFÇ3zh3~x֯_Ν;;w.>,555ncwqٝ-tEQ>S=\^|E&OLaa!MMM455裏[Gt:Yb#Fgb_qqqXV'*y=k\:; ߣx븚*(8נa@d$UqI1`OY7~g zsFY}Dam&9 G| t=xۮP\/fOd~܀$c- :Y>&cdYrf/{2=hfܬh+sT|?Ξy?Bӎ^fYP]MCvVLN2dm;0ɟk$7K' .SG\D(Iow{=bPVE4!*~M'!5T_OtBUkq;*u>o܂kOfm2ѵ[k^#"& UHCƞoĬp3! Ov6g@Pv&尛YYY#,˛]]u*L޽Ù%IP__XVbcc8tu\81lذpc~z~?dggi4756LdggCuu5{ ,Ϗ~EQ4iR8Ȫp0x`f3{*ixGcZ"**fvڅAu oߎ ogNNTUUwv?/'xQz89?5Jd\?jl}F$\T[JA3S$#P & &κ),UoABD&dcFP$aSt>~˂kz!.x79/7JȢ`!2&QR.r"dLBH &k̮}Lvѽi܌qыU )d!c݅1kd*4*K(U{T_b#>ܰbbkmRADl&b~'=:J̖hk0Khvtt]`r^@GaJlG훬&RQ66bq;E1Yr) &&tMYWl٢҉IBj`]]ED@dYD #p8|וl@^=1;ʷ]<;r=*X ?<."z)~oo)Au222ll߾]0fc-a׆|$ȟx;soB6~ bK=dȲ֕/;σ  ` tE4n7z|>$a6u]x!lF]o%נ6}c@  ™,٥2dBQS^|G/- ihzlBppFUe\!e{@[RS۸jѣ@81 ] QSZSmY  ]WTˊxhmm O=oii :;Q<3̟?;㔮Nrr2/"---G]I==Ņ]뮻(((o6[6l3XGoo  cI;ydeea6`\.f̘AFFFnذM6P$ppB&L@JJ ,xqÏ\HD~~>r }eŊk455 RGDO;KjS"5#W&??4VZ~gĉٸqV/g  OLuУʸq=z4˖-cժU[h~ƌ߿;/l\.~)YRSS;> Ǵi/عs', 5jg}6zj֯_r7fjjjW^`̙}z]&ԋ>zp\N"y+<Ԧ&?|PE9ޯaWrXF%٠>?[@V :qSAqڕkZ/!P2Ν1JdJL>ƿu#H2J\QW\!!φB >$UUzH:X|l6;v贺wy;TWW   "hpzeXYY|9Q__lF$~?ney<q."4MbihwߟxՊn'::]9s뮻gffxҧO~?III$%%tRVZƍ1bVyj*V\-\t@Aʋ'ᲹȡF Q tSV.}FSDϽp\z5}Պsa [XeC䨱$ȊnoEPI}OXS $]{Q]m@bϛZPUg\#'@C}vBPݻNJpp@  ?G%8T]׉%>>N ø8zŲe0Oڗ˰aV^(Ȳ|Ԇ9s^s3j(x LpA$^~e|>q:cۉaѢE|' >!$t#B#Ɲ#1r -# mI Nտ p`?OIMwP秉*`O? о~IH{tFk>t#`] O=I0iP6d7| Hӏ1'Xsri^nYpa2jo$A?  =La`i;0!!qQWWGQQQ1DZ[[CӴK:eee+<< Bz:̲e˰X,nQ={vz<noHIEkqMC$~?P)7( GފrtoTca I1`CwDB\gm9 z la˜қI ρ~N9Sӈvkۆ%C$AAzmizT6xƍGyy9Fihh8jNrr2`2:]mNSjd2ѷo_$ ERRvn/KUUnv|>> ^ESSz_fv;Ţ$IݻŋtmٲeG t*"GDblA}[6E2`7v$s*@U 0% HF##"P,ԧ֖8: feTʮ[ۂ[?+>`L&c]6 ;~) A8=1TAAq1= 4Mcĉ'Nm۶ HLL$>>c~|7\}Ռ3ώ;X`&M61uT^ÿo>c{1$I"**z @aa!s{SQQ{z/}ݼ[رS2d裏=~ǎwHN`Z\&;L>ûe &35Ĝ3w6?xCo~8DEڋ4^Iko 巏}kmIBmrR~]{W_S.I gRΥwlnFRC˨i܅_pu%%% jWi{1 >VD_7黳R:^ʯ:_|Exv hqtN'A83M>}G# Г{ .+܀^/Æ d2rJ9묳X|9FI&* Ed2xA'08tٻ dY>`0 Iz"&&EQZx^ۇ`d29A~ʎ9YQE|  Bc4; }.C'5M2j%66TUhn6t]gΝ@   pڂv=|8III@go޽,ZS ߟ[ns Mo~seGAkk+&) B#^k  Eq!!;v져8  hvDs=l6bbbz}KK a0H& μyhmm瞣4 ]׉h4҂l6f3PVTUl6c4QUɄ`Naa!C~***hjjbdMe"UUOq1^/g͚5DuΝɓkX,*h$$?ճcjRAAy8t?\\.6m"-- «ҥK5j+W+K=4.l^vCC$[oj_gӦM<?>z+cǎXIIIadddp!>4gkΜ9\r%c͛wJmUVz#ʧ( \xHD(⢋. ֒$`   :*Bll,/f|>9p8ꪫXt)[nr!=1^x!ӧOUVqA&Mą^ʕ+ua>Sjkkd͚5'5DB~Jǧ>+qqqȲ::|˞qמRn2xgկ~ٳضm>l9 ~=EЁALR8xW;-QHBCEN`?}!N@hǫ'ot,u|>I׈J%*?^w ף8woNwYWU뮡yA8QRYYɻKZZyyydff7ߌN]}>]&1X[oERR V+\s {FNCxp`0Sz ?;#G4773m4:Ē%K/ 466{SZnO>0Fe$I},ӧL&)..Fu4M#++t 7ot`;Q|\Ȁ Pw,aߖO6qlՓjp<ʪqpW',^l| dñ)T.}-^ao!asH;PCK_6-Sb𸪎}- .>4Tng a#&݅#:}[Rcti9;/1h$d͂_c0EXs3FCe1kOߴ;$g9gOdrh~>3r垇 VS %юkFs[N1еoc8 b0Eb4GiI`@MHIVx5+xs= .9 9-``J!#g e%Kѿd%mQMy IDAT<$@ٖdD6Xxum:PCw%E!W3BK$YdGV.BW4E!4wmQL-Ȋ 5Jt %ؾ˞ľm u(,5l(R泹'ͤơRƜw>O{u{%=>9̱l_?I}rIN /mV$:vL(JG;Fs b/t (&kl{mO5` [k rȊ>7q`g: е9Sp}>9gk|_bD3}K4cWXz^bdCdBVC  F;jK.$-(FkwGs!K{QG1ڑ $#+c׾~ &k~ɭ~Fa4G*A!ԐA@$^|>P~)..vs7Idd$o]˗3k, ƁW_6aZ7n6uuu3_G$K*Y0al۶z봷Ǝˊ+pyCW~?ӧOgӦMwixZ+NgpD R-Zb(SQQ͛ \uw?~d ha{M!sS=<-*s#~ |[,;rm IbyXΒbO`̹wWrpf4Ֆ'c2咧P ̶(Qɬ_<p֤;I4%Ovwۅ<2/>y!?5eY!V_|K(L (`0u;?IӇb)۵FB({EV׈Kθ]>xM!WLdeB {8K$m}8I!+&jʾa?odgd -g>6.+ iAd|?JIlS.}oK#1hmg§i܈$[ڒo~gгo_48KX4Vo!69g~<>~kfg͝@ p#\!"}R֫~WgZԪ ZE@.0@HIMH&Ѣ~k7%:J3`ҳfbE]U>?5_3x s)V{|TYGywD܍ljKK6/S,cfMj9uX1?Dƥ3!:?]w_$DL,Iii)kR^^%>>cǎQ]]QPYYIqq1?JMݻZ<> gԩݛ_Ly'_,iWdd?+v 3YМ(+XOMa_2l|ոꪰ8&%O^oS&koDZ" gɚ%at\Q~m]Je}j >y0(|q̸UOѾ77,cF@!XcxYDaOg JVw|z3v>8A#.-lֽw>uR3lNq5מ^sPLCTHj*s9I:үd{>d.gQY5-ۥ̾q '^ǚWuZPq.OcE1.;]NIGGk &[<]WggwS[)3)_ǚW""a,|^=X"Ujhr`Zw.Ci~P̝JУP.t]bP,AW/版3s(]SY% }99 Fq!2.kD"+#`[l'%7:r7r.?U z U\p޻5#jOlF}+Kg(ZmsC;$ @6ɞv+G|ƻeČ{)?# H9M bJ!cy_eU'snn dE.$G&\ 1=NozV>]X$i:#;TlQ}B;dɒp@e"##Yn,ӧOfϞbl6K/ ll߾7j˗/gɒ%nf3~x__~<@0b*Vpaiƍ|ȲaSړ]bb"_,,[{ǎ;8qbwȒDLLwxx.| 5 -{d/꫏uRw-/{h sD4Cs&k<7Ux*~NW., `t> ```tJ4j1HD\@C{#{mݪQ]qoItB:%yEWJ6[>]=*h6'т=:S)b.J 6qp{2KDc9wK5t ˉ1Y$dـ8u 0neۺ,DGǥлx.qix߸h!.d2,Iс,:z1d̥EM͑MkTno4.DCQv ] Q}?8=$\5bBBf5gH*l,PJu>z&`-Q]C{>D6E AIdeňMӫ܎(s̱)-ځCOd;@Td|Z-WR6 :9Vay]KD ~oVGQt.OC!\U K!KzGs爤 )mZPnZw(INOQp3~h2k;~|Ew_ޮLPQQ$NvIQ=gTh4Cdd$~8i7DeTU妛nȑ# %y?tB!O}*>YI P(HCQⓆR @H I29B|+8pBj)F Ɏ1ۢQpte%B͎vUCZ-;aT~ʻ7`B-;CuFO1Iy Gu]GiΊO~M "Kr2Td{I2`0Zژ#5/;N(\P =-BdԜԨ%H#L@VP̲'sHΚɠQyy;Fμ=I޶0qDƷn/OhC0bP63t n彿LԼo #:u,[4ԡsƲ՛Q;Ik>&}ok1loteŽOz?=$}hZxf.-kQ.7q`3CMvon'[>|jЋbҼ@  ,Ԁz:NȺ@c] QiH>U`⓿ppa0vq ^_4i y \U`q5E77 DE ]MvtxU@&khZт bD^SSzI-玊R9F.Ƕ!'} t-j  Bw>|'v$I] \.Oّr& &ǎ;'Ѐfc\.P.nBPq:+(wC/ ަj"I|Z3~KDLp[~5ԌUgyo@17w:1b{"m:ILB*꠩DǥP]Nq:Ҳ$炇(@>ÐdluR26}DťtyK}6|a2;'F|ρ zfk$ޔmm>LPWu>i(H=5jjs8|6:-aXIR꫋ :wa$x~ 0ph`BxDȡWHSKz4\uE 9O0ښ 2=HIHiȗ s1{¯WkFs{6C/dvP[G}!"R,7%|:>ȧ< =vUG1-̖HzͦΪ<|&#|(S-5ڕI:~c|`ti 9g%<@KE$0۟ؾ(f+b3д~$s%ԔPư W92R2&8/W?bIRL!$Nu 738{>!G@i~Y,hb{d)ڿ13_$2>OuU4՗1 !38.u4?M#H2zH_XlTR[q~c@AA9 B455 Z_Bx<|>"?%` }S $EQ.,E !""3p@)))AuFMff&>kxmd;:N~gP[Oe.N yB^'Jj*p7V:n;5PFDl?F!Pzx+bTUc3ڣ8kRq ɣ*2\MuETbȘ+ʹ-ո;i,Qq RMgٷ:%/kzKc}5ONiV 7AysנJoPi%5k$ͶODy꫏w&g9yToIbTWR`4u75jO5i)贝A19jFLL|)OH>FR2΢n:J 61 LYs=B69^}1?JHm>= ((F}+PZ8^Q3l #{r4ȳ5Z7[>|ˀ$irV1l CUn|^'o"P.$ 2rʏnoiq0M9ZbҰ:?<~.?Hoqp]2b3آ8rS@==c4;8dIz"` EKl /CVH֔H;H==IYIJG/Ndcٷ(VRכ=`Aֿsr|U4?Oq],ecd䔛w[W=IձT&>)g-gTM݄ %7x:'݈уi,Y{2rlfŨdc09!fk$6M&WSSSNA?atm m6%`ȶX,K]Nti4m(JkIuw:c4s!0D zK`og< `jn|JsolR;* MFIHDmM̦dB6PNdoMmDPL zh-&{QN^W̖(yjLX"l'TC aA6X@Lv=!-Ҏ$wXUoNd7oc4/$Us4~=߄h]#wk3T kMhjؚY݄Q]v׺~tP,ͧfB+Xt`qn ݍhjB lˢ:&{ Z_Dx5H>i^>tԺ̧JVz9hSFU0;hA'~7`}oB9y6x1hrXe7Z>Iªx6GdmN -؈P,k| ^S JUhnR x^7"j2h ŝ  ?Ii?X ..>ﺼ@P[^6Ck@k<g?rʼnD RXO*7IlP~t]I9}R[p`qbλgSN*T< Jd˫)ZЏ[;dt{%07d֨nz+ȓ?hݎm{\ը)+N<$ᾑd#glac=Iv$$+Lm"cTKx)8e%2t2w~-|dĶc$J2&[4&['195k$uCAA;&yHwP=zg|P̧    ?N(y$I"** vO]L?AAA cѣP__Oii)Pst4g/**:䉭N'/&==;wZV]0`/fȑ U%QFEmm-W-   ?`ۗ8dY&--8كls`00`+VVpUDD\ve}~8aHzf.ȷ.CCv =z4seeeDDDSO=CAAAϔ$\6lu먩W^  ]O>222:-,ΠAxټy3+V ''MӈFQpB֭[Ǻuӏ{aڵ_[n夾7y={vh45j&L'No߾~b~>C2228p8zAAA !0|pznѣJBB׏P(DMM 4PPUUC=tRi=hСC`0|MA& IDAT|>%%%n1AA *`i4 >|8x^, k֬A4ϟOeee9S֝6mstDUU{9ZfΜʕ+1;.w<ѣWX /T[[KBBz+᠊ U0رcՉ! Oh$**J +];v,GAuzEPTTĔ)SHNNbǖ-[: +xꩧHLL$!!M6( L4*++X,ڵk&aԨQ<3ȲѣG9묳9r$ǎ#33͛7{ٲeDEE_NGruםx$`(]ӧ駟2yd$IP}   0h-uKm[Ck|||('~:3t]'++QFaǎ466R__رcIJJb9r`A  ??#Fpw0fmFiii?d^Ύ;%22oSrJ~mdYH,Xy󨬬d߾}0sL^|E9Brr2&L`˖-[׆&)<[ow +,?v|  ] , Nd:d2{555@͠0`n,h 0  Ɩ1###b,J֞TU`04?Qo.? $ ܭ xb׉ms455wZtt4u׉>4Z[v \.W8њLLr]'~(h  OVk3׿`A\\\;|>uyyy; jm&x6^?r(iBYZ5 'g6;7`XX,'ĶhMCp8lAAA-d u'AAAg,p:5NjocܸhM8A߶Dg$It]׻53͏uAAAD;j !!Ѯn'>>o^X~_|q=zO`T{nZt?? ilA}kLL Vj#,_{tRbcc|æM~&l_~1} rf222>|8%I"))#F0`p ]߿?.%AAA?gT׉C%99EQ|8pÇc27nA>N3h:44(Cj^Z,[TX X,8AJK6hyy7ܐͦ>Q$46[0 ldB!6n܈nȱ1<=Att4_~9_=ƍCw n;liW!xv=5t:Zj' uCBuz7̈#سgwy'EQf*++YhdddpweÆ kHD^^W^8i;   ߟ3%I^+WDzz:*8pO{Tؾ}*ޛ~/1Qa߾s喾-gu;wNk{!I0|xvMct"#M($ѣ^^|I ࡇٳg:_|q7ߜLw|׏^z.P`0o˚5kx4iaGUU5k+V`\s5uEf~_X,k\r%jL&ϟ_nO7|]v{1bF7׿5}aΜ9444pWXp!7ofԩ$'7G5jۄ   37I>}pPWWG(侪S4Y<8QiV#1%T^spUټ\kb1|h: t]'77~r8,Z&BPf]AAA fh4p8e9\6 Ȳ.HwNt| x?>nrރ8̘L2L(Ԥh[:+jrLC}hj j]*(-- 'lUYYi?J\\C hll$22Bccs GGZZ9c0(,,$%%#G( YYYlڴ[nwڼ#op+p9p=0gΜ(t/I$" |>FŶmغu+SNÇ#IeeeiDEE8sAAA~@">r $EQ.,`g=t$ 1vXFɐ!Ce\jjj\y啤qpرkib֬$6n=Y7rM(;2yr{[Y R ITȈώtL:̞ݛQbY$$X=& !Fnݻ\WɌ3p۷Iz4551|p,XԩS)..&??@mm-#Fgʔ)޽^x!fHDMM ̟?K/Iؿ?VyovZFɌ3ذaC9Zk&*\.v;+Wd׏/֭[dٜꫯ:eee9n}v8s |GߺLA,  m0`X%N9t:6[jWSSS /  m6%`ȶX,K].I :1Fciipamwe`,#ѳBSF0 UUA^=dT XRI|* =z4w:eeAt,?u];v,\s .lpi׷[GFTT@:t]d2$I444Tm?** Yijj ѣUUU@ss~;z.TWW`0`8i[S__fŋs}qqq3ЩО(Չ ' Oh ~`A\\\;|>uyyy; jm&xF]??'~ɓ'w^Xٿ?   "Xb6mS,׋@   ¿S_A]S -   p t]o?+۷>T AAAΘ:ݭI h]vQQQAJJ Æ #66K~~>{rz$⠼GkbGU`PGQ!  ?ǦM(--=c+!!ٳgrxwĎA8S$Q^^Naa!`'2l0?(S^^N߾}2e TWWw8`3Iؾ]‡֟ѣ9|_ZDi  ?v\uUÇwg3a(//?gϞ=L>3gyf>w'h4r%,gqMưa(((8}e֬Yw,{zK|v3/B0 ?Zvm!))s9n#FpWr,Y"NA~2l6vY|NaaaxG2yd Cӹ^sT5DZZQQƖOB<. ,K/EedYfl6C^6lGm7݌ 9233ݻ7I>|8{MIh]-` ==oaÆ~fI0n8BPMӘ2e _|1< ].CFFsaÆ *XǰaNZ.A\@eƍG߾}|ׄB0LL4;h.Cdy>'=㏏hW]5L%=7_rbFq4 &I,s!n6;7oFUU LرcY~=vŋ;d„ $&&R[[ᠺUU4i/&>>ӧ <̜9?孬k(--e̘1{ ߏlgРA$IZwy\.~zfDFFЭ={6999TVVC̭ʜ9sظq#_=C aǎdeeq7cZ $™,Bdgg#NJPTTgdffRUUy睇iٳ6gƌ^;I%K #AA4~f֭,[ %KP]]͔)S5jSLaƍjtdBSUUto>=JBB INNh4 {ĦwHOOMӨÔ1L 0z~?vS>6VV[}bLTTT6c("---|o؈njv+XК7"""~PTTĄ 0adee!I?9r Ȳ̎;p8jd555ΡC|z#r_?ee>TTp8^}yyNzPSd۶Fސ8AA(,,& Q]]M^^7GVZŧ~ѣ馛8Yb~YOzlhjjjSkFVVVf#>>Gy=zp!,K&]}~cc#$yB e;NAf#::]9~8r gϦb"""p\jɞ7 'O ȲuofiEQTWWwbmmi'پ.l  4NO8}Ν;k0ra  --B."zAEEIk>sfϞ͐!C?>DttINԻwoYz5-b֬YČ]墾zy?4? B >]׿rk-¥^9x 0΅^?~xPU5\u,,X~O 5uTK޽IJJ6 ĭʾ}HLLd2G33X   pv[@YrضmƍGUUlܸ[ ˸7oc0殻ryp:3'x. ŧȑ#|L6?Ohܹ{<YYY<F?3gg}}=oա:/UUU 8Cx6ɮ6A=ƏsUm;~T@UUnw&my<>#p8(SO=\#cAl6yyy<\i.[ݻшb,܅v0|>\.`GSVVFFF={믿]~YvZ*.^xKp8peee,_._\.^qjp8hjjbeB!/^ᅬ`С|>vMmm-555/A]]Vg}O>x BCC;)X q\(BLLLxp8?~_łW^W_E4$Ib{u]Z* A$J\Xd#XBտܯ?c}]ĉyG$''sNܴiHOOM6QXXyWQ=3N%AzDDpE`}_oUWTdmkKbI B@M}G5`Ap:;̙3g9y=ҥ ~a8os~~>;vQFňUoŤȒ:/qdbF em\KWsWM8WU_k j>"͚FSv8' #9"KR/afL^.{bO1#z31v"Q(y˫Z!Ǫb 6twS__ѣK@ `L @)Y IݻJ^/,#IbݔS]]$I4Nz=GfĈL03<^OϞ=;p:#vi z=,ZHn{8l67p0}t.V+wf"::$-ZDrr2\uUdgg֨?Ί+ڕg}^FON#`bz6t-Q}8q"v:u*=zѳ,ސ@͡f >ǘ1z>j#My6D "M40"CE;Ի2a2!1k߁G.%%pm裏غu+=so$11P(ħ~JEEEx\hEY[uzu:LťYm!?D-X},_~ɴit&(_7}͇g~sy88ޭzTQxu߫]²C߸d3V|%[rgb9+,4M#Րɼ 1L?=z{3 ?~*C$U*Ȋ`9p\6F~>lnBSCbb9$jn7z2|p֯_Off&wX>:A4ϑGQ[)ܪ;l,v3z53bf05y*S('JT@"8+BtvFA!GC#E"\$$͒QAZx}̲K1ȒKȫ;{={ɖ+v)'H =,=T?M8y&NXhDTM:P}i@ @4ƎKsssxC|N(b 2w>i3;v젶9srJ0ͼw}z 6nyXf ׯ`4sRYYɻKUUn)S0qDNg^u;8jWqnsΧkdWr=6"@0,nϼbXJڌ")62\FeloΎLHȾ")ȼT}Gz=Ig  C+륌*4xlc8uN'R)lUbdY&))}QVV hƶmؽ{7^Dn7ׯ}Q\\$IPTTDZZ_|lܸ$"##dagAP}>Nc jxAóѧ*kV[Ji]x@ z,ۃe $O.$ ݄gJ$Cΐ!Cd[n8Nrssq:lܸN^'55·~˒%KBPSSCZZPPP@uu5~s9(}ٟZ_*= !Qg[6::a Tk]k3쥾R=dX2p5HHC)H]$99.m3hA~C>yyԺkɰdf btRʼe]Y3hJʕ_ q8 }BU?csRA/YX7T2"zeMezk4u[cQ,ܖy/Hqsq?==I&[o=K7, G oVL&Sc-gX:MѾWb`l#6BҦ A&iqG4MFi2|pjkk:t(F?m"-Xi;l63c y'OfҤI<#TUU\.x }>cf8ձlJ㢫+&1h ٟA2pi,.[7"ӒE11~"$sSM]"uDC##"Ρ,޿=uF.]OeYNՉ|NZZ@ ^nvr ;jzm@kMiBmămN_~8 x'1 n zKvDDr₆wx@UU;v,s8̙3 aԩƍ#::_f``٘0a{w4@ @pJeCrvJtt4C4dYi(rR Cr4Ml63`***PUOrr2MMMx<<| CvzjL&2tPzM~hhh ::*4M#--޽{$I444-{I=Pd\.PJ~ҥ $Q__\9b2s~D 9!PA6gGo$n:uFש3nYhZS#5CިM7hBm4,t)i(ɩUtǒك];1Z[240Z4 %! C(@VUFr-y4McРAx^^/$餮J߾}֭:zz=JZZ7n bb"ÇgƌTTTGCCl6Cff&E0D4߿?v=&NGի $vׯ_ Ȇ 7mlNE$m۶ztx, ÆۡCNjp?έ?LNNcǎe֬Yr-X,nz=7|Ԡy ̜9t 9t~LB>}A|I ?~<_~9>Ell,> uuu,\F#~[,.ڽgw%jD!!`.ʉz" A!cb.mXOJ!X]ث/IW]ρwg$-|{O! OJMΛ)&r bfA2QiڼCu?knqjixrN5̜9bۇᠹ5kW_MII ^z)}A?~{ o߾̙3ԩS  4iӦ[XX /@ll,z+vjs=oɓ:u*f͛Yt)@Kuu5iiiX#n?$%%1{p8馛xWٵkr 7x#n>sz!n$I";;͂ ظq#\s EEEfON\\/"?{e޼ya )--eJII,j^|{PvՔ]8@nt]a2Pzl5Ĝ)J'>bZ˾5 MU9{Qb~ T5!%P"#z-JL'#PI6a7VΣj)T1TG^صkW8hgʔ)x^ѣ~!]t_~;\wu466r9(O9sge̙]Haa!߹;Yz5YYY$$$p( -^{|>Νƍ>|81118pՊbw5'뉍 A||BN#..ZR&@pUUYf 0 :Ĉ#SNl6z=YYYm Bٳ3<Ν;cZٲe  n݊w^:w6;u6LYNNp82e DEE>d֯_O0 @||tڕ7|^z1zh6nM\\.:"##1b#G \ꫯ[9s&N^iB!-[Ƃ AҥKijjBQp\"^@)..2bEkt:z>\ZSaZ!Ct:y$I ̂ӏ'Zpj^>O9F1wMpjrJeC!--<Ȇ ?̭qr ԩ/Yٹs'L2h|Iv܉,t: HIIa444PPP$Izx"2;6Z:|>lܸ8.))a 8e˖g+++ BL8trssqFJJJ>|8#Gd޽'O$VZ޽{t2n8ϧUUIHH`|aI 88U!vƎOSS'NdРAֲn:͛Gqq1]tO>XV),,lWOVVF#^E?N"I$zEI/ӼȲ(itφ 6bA[@i#(md2wjFMM uf!ANJK*DDDw( 2fv~|>]`0E尻y0Z/DvJaa!^z)III~a+K( #&DknIBZhxh APC`07!4wN^)~8Ţ06-7EDWIiYniCkUm8ׯ={7l֙EQ([xBDDDx^4M`0jxyٽ{7{/)!2FEQ4ݻ3b^z%@C?t֞cǎO?`РAtԉ[rٴiVˏgl6^u18~Gς7h`0=cz=v sn+n^QQf ڔV F?`Ĉq?9,իC!@eG2#A8lqet0 EDb S`FU1 <޾l6YYY?u̙gɈ#HLLɆo߾< $I[n᠊@ @?#͸qիWxuTTcǎeҤIL4#Gꮀ`I&qrwзoߟTn;`ѿH\O#kB8._Okh :<%-$~߅L.2-ZĬY~T0d̘1{C~s=dee2e) !@ XtnvbȐ!H$99:\. '=N#22p~+-IDDD`0;]ßMqؚZf ~iBF$55R:k2埣uTo@r8lkdoue6̑G=dn/҆>YF#ٝ&FQJmp"t%V+3f_l7$Ib`+wɜ9s`0`َ~ -kl6V5,~ Q$bccӟNC4~al6[8 ⧟~ʌ3Dz@ @JC$I"///lD3Ӊ(HD(޽{{-Azz:s̡_~Ȳ'|kbCGl( ӧOs!::]v /PTTi\r%dggM~~>/B>}puױuVz)""/2Æ G ؆~{]@OK'PVgdzqa_vF|XRrz3w|,|T~] Q n1j OuG6R?Pcb>_~Bb3%29z`~s/GO oFgētX =d >sr!rssK;cܸqƲsNyvRSSOq\,[W_}Mfƌt҅z^}U>vu\tԉ~ѣGs=GII | \p0|qL}-X,\{lڴ_|CU,HIIgϞ턁jdYn˳-.$p oN휳zC"a<bncZ:/8}=y9׮&nH:=%s7+Obҍwo_I|/r|2Y9d$ ߦ k qW-Rvϭ7o O5i5^pXvnQ <gqaIUUzyy뭷ݻ1׳h", g欳⢋."//2.2{%..ݘ}ꩧ0Lg޽r3f ]tEEEdee 93E@ @!hΝ;&33Ӊ$IfQЪt|N|~"8Ƶ G B})܆>N*+TB:t@pw<*<ލk~P(8<pA fB:L2B| $4"]~ nY(v=&3YrVWQ |gcł`0ȠA㥗^pPXX0`oMMMS[[KzzzXY|9~p7@ZZ <a0eI0X,4M;svys,@ ) PQQCtш& "Iu  a0BHD0 h3К^$TU o X,u'@4``e%Ky衇x<8ɓ'3f̘vbAee%yyyG5&5h%jɦ׷j@y&!@6P}>@IoЂXj춅$e4"5BQo!\_~燓JKQهõ/mfeY~?I87PY翭WI묿Get:@@ NCeTUmWxY`|ϻKEEo&;wl&11_0@ @ bǎKjj*tG W^3ޯ)--=)AC;vW^?={2cƌ qSSE\\PYYIee%&MbРA1-[Us=dddpYg_mm-K,!==ٳgU,<\|̝;7\nc:}B!g1t:,"OUE2(2`H>~䳱5.ƔٓVW\賦b:!8ϿbkF{oQ_a30h\sV/bn AD_~5QW^?X&r0HW`4%:7e+W2`vˊ+;w̸qׯ_ @n0z Oΐ!C0a_x\?a̙3$V\Ijj*{.^z);wO>i'eddjժv1@ FŻ{5&&&Ig. ^{?V_M_ss?)@kG |CElݾe%6A(؄tjp;j\.P$H{ALHkKZŀ~@[AntxķmdggӳgO yp>:X__i"##-hZ5txq8hF}}=f9z=hɺqUWi&6n(~]$?(V~sNGmmo?Of_?,l BAT5a1@ MSdm/?Kj H,80Lt::zn^DFFzZpz>][Cc "?XV;h3_CmJxj#kS3;JE(r0X,6ߟU%#ھw O>HG}&Eڏ"h 4XP]hMGt;blZ~=۶m;c{Gھx$6:A/^2~\I$ƄЈJg#@ C$jTSFڇB!x7;m fOe4MM :$EOEG4;AVIJ'@ X 81dn ?kzq|~Ś?q BRג^G$O^'IR8k¯(t:TUUt:p~":A mS1dffҳgOiZ.]ЫW/~D_q)'izޅRx\.>oy9l0.BF.^EϞ=Yd _~%\sM'J0s^UyWݻw}>SN%))ןXTU{_j@ @p rxhFzz:Ȳdbi&MBQp>w#Ze\+HcInr!d$. h)%|~RnrW-uېM$嘂v8_ۀAaa)GK2,H&3h&.eqhÚh˲̜9sزe h466=Z:Hr :rP]}^UUꪫ(--eϞ=XVEa\xᅸ\."""HKKcɒ%?(a^^&LGC7add}x,L&L&uz2v~WYٹs';wK/gwb؊>@p\2$}vVX_~IMM (B~0 lذ 6e˖I'qw>@ e7 @@sk1|HF#1o׶> Z½;d%{D^t`LM#g[R+=j"ͤRzl-& 6dtn豩koP%)*0oTR 66XniAll,w+W?s fW^y+V0| },_իWs=ł|I>}]f̘wMnn.<3lڴl6ms=1hР#ND9r$K,aڵ ƣ>ʚ5kx7ni<||5ۿ$I̛7_~uͼK\qhF(o駟& 1d.]ʺuxgԩtl6!NL0\RSSYh̝;K~Xd ֭f̘1>Y`+Wdɒ%\|x<xGox7;vl>,--{ )~^dOS @ X-ݻw';;(*++ B$%%!IgqFbȑ˓b3)N\v[TSfOW-gw}E I_?\gbHZ%KV/*{S4*v[?\G~F 7 ^}_a8 5=%mf;obwwDLBh^Ѱu#O?F~hfPCaQfQZZ`0p5אɭw.-H׮]Yt)*w)))t: 7o#F`رpz>}0gn_Oyy9 .d|hFVV~-_~9wngOT(HLL䮻b۶m\xᅼ;ǬK.={rWsWӥK, wy'6+G}[oeرkx B2|p<Pl+N']tvbDEE1k֬cz\XSVV?LYd zNҥK1b| W\qIII5:'|{t >kɔ)S裏5kVX(//G4ĝX 8IHܒZV Qt@ r@Y BhNd2|r SLW^l޼GnK4^ $ Iq+,+مk0toNBfb= ؏!uHxJi^P>Hzr%g+ IDAT1i -h/ ۸IT?;{F7C="l{-$ twc4htǪUصk;w ޽O?A1ydyŹw`awEA1.7&^cML5K4ɽ$Wc̍+1QAUEٜfae]?́@# 귪~iG?"33O0l mFII RJ|qxe5I(**r}i2}t0=IIIY&=l_ԩS2d79|0Rxy{M7C=իPjPMXh]w#Go߾믿ȑ#oY?˲0/f^7^ޢ".\ 7܀Cu0`uuul޼Ro /`0Ȓ%KBf޽P(&@5bK P(  msNv۶֯_ϬYL8*jkckqr wOpvZ~?wy'1j( T:tAav|Gq%̈́ HKKcݻp8̼yHHHo߾wyH;vp뭷Hk>%A,11w}ӧkcc# . ==ɓ'STThjjpu\VFxٳ'7ndÆ 2 ٳD e]Frrr\@ظq#Ϗ*cǎmsN999!P=Bщ>GJP(  ΘXy+1 7Dصk\tE̙3]vsӿ!V0j_zƵ<|Z%hiۘE=ן?O-ۏlIĎ_^yxI=aE$_w iv=חܾ oJdV~J?L?yI<{_yƷ^]G$$R?7a~HJ*++͍O8CO?4#?x!/@z s=hp8 <={|,wSL᭷⦛nOyuM6qzyg(--eѢE\y啼 c=Exesϑ8p@{J4McϞ=TTTo߾VWW/ȑ#yükk7|w}yg9شi ,p?9s̾}Rj*V^OS,X@MM pş'*++c=FuiR__zb3Da`8bG BP(Nr8#M8 &'5C$A7 DGV1 (")6"(nd|J~a |m˦0cO[I$ { )7 ׷o_o#hߏaB!L#>n/!j?o}ݚfMQؚQuVVoXh/>es;6aS}>Ghnnn#8hOMКp`6?9;3ٍ8631Q=m9 G>ekB >[7:]ᾊ_zss\m^/^}?aHnle,hjjbɒ%۟kP~v|m3 ~~iK.eѢEh\';qʿ;v[k} !?~<@?۷l#?ç EP( BPt.2AFJ2O>2~֯'s{ncf^xnWF4,ve vusCx<'sQ׫ EW;} G'w'dcENifWB=F} !bh)$f$P( YHzt:IJJ"99wz_)))gvIl3dc!#V}c.ܞزc_G-/p\<\s5m\ BJJJ^|,u={2x`m/'xℙ Bqf '.za 49Z^Gއ8s)vKAáh;} ? BPt)%Fo߾A `3~xnbb"WO?=[Ƭł 'l d(ywd̝;(?y7>8mudCݑ0p$b cǎ}-G 71cxWyHLLDu?|pv5k\s TVVsϱnݺx})%3g?TWBPt%@s cvlE7< BPt!{aɒ%k4551p@ `ռ <\@ ;:E(p J 佼'6A "o p#Yx$E bY[]6g[|Zy`FAJ\C7f YWG/7ާxΛ0f|XEQQQܖ ?0SLaܹ\.̙CQQv\|IJ,F֙+ BP(  :jԄmضO8zh N<^\=zQkd]|_AKM5l$=t}08:v֐fRJƍpyod{x^cPz-(.Ƒqw+ Sgp豇{urn #/ 7z,*++YfM<=<ƌî]4 )%L4 I~~>ׯgܸqlٲ>}hz0M}ߦP( BP( %h{fȐ!n۬ٳ'^]vubG"-{ =MHJ9SI~Dw4ܣ7 ."'$ƒ]턖/i:Fq)//?K4K.+_ $%%aF<@⭷J "&99mP(SU~c) B|T6۶ٰa7ofԨQ 80B򨫫5@QA N`;%߃_2q3Nх%c< j@iI,m7q Ѫ ^} i 4\X, u$BSS>!%@?myTVVb&`h4ʣ>innn#x^BPe BqFff&Hgz ؿ Lju1{qt۲TCQ( ,Kyۍyt:СCǽ30z:TFo~I aϭJrc~3;>ڕz@)Dh xDvlAb!q kPc:fǎ1͒xkiB6mz$%%1tP֯_O8)SPTTĘ1cؿBGyy9HD]9 a?箻jC~r7}(6;Vpv{)\եBէաǮM,m2a4M#PPP@$mzgΝ<W؛R]8~?Ȇz =E$&PWy/iU?CMπJų!*j%c7Ν凨{Mi y)4ٲMܲe ]v|SN&%%~1f~_o0tP|,Yŋ?>O<wމ )))n % l__WO?tټy3˗/ ^/~uZ{Bq7p&HMŽ6=b 1. 0Nk2w/~Me%MX|y TWWMSWB8غu+[lA4o߾x6P(DSSi y R i@5ҶI1-t[RW[ u//SbA{Qc&PHgX`2 NP(D(S8#7iڳ4 h'hz-XJOsC19V 0oAC8ÇK/ٽ{wv.)98mS^^~PJ:{TP+BqNDFFF<=m߾}׿?INN,=1 Nw,[ڴFʑ-¶g,VCg<, MT=kG  %!)d N@սV  \^z)VVVzj_͞={a; wb/4Eӎ+3y (Ja B* po,Ndk,>*GP(:4Ooll/Z|yטi p+0q8T( \K>I4zKh4i5j0tM.'T: BP( Bqne< L8p8`ƍTTTr8ۖTVrr<{o'g2|x{3HHpcf~\!47[ө`* M`0C NRZؖpS{)U{;<7+@ aQhnƝ؃ÖniP=Ҏe(Btی;}dAn2e@i!kW43T Xhq!-tۊXr+nĶ.܉pxR9ʨ Ew 4Mcԩݛ`0ȶm۰m={˼yRo>jjj:̘I~~y(C$paPR#|F4:aÒp2fLƬYs֡P(.Õn9e{?86t'^7eQw` {W>pJO1Gӝx.P(D|aןEw5 E lf\.ƍǰa(//gĉ\.igfԨQlܸ8]x< eIm"8bMcE$bc8x0HSSuj,JP( 98MU(嶩x9<n+ԄmD"n7@4%LvaoU$%NlӔ47GøqIL4 BP( BPbŶm&Mi!p\۷p8Ν;;v,_|1NvcH o}ѣӸ뮡NnZOC@bk}oےK3fL:_㩪 p1P( BqRԀI |iU{U(Xi| !hll)%{졾TTUUQ[[aMя>a$ l҈>0~0 ѳ{ٹ _u( BP( 6.4e iءz1E M3@JSVbÇ9|pUWWS]]8cM0%%m;>>j8jYSߗBP(]%b+f$ tWCq] -`)iD4tXP5V( ;HH;ܭm[ݢ @JUP(s%( B $kvrJBǙGUb7iG 5PP(s. ,0RJN'#iax<.CP( lC^6}sG*t%_rC\#H)?~< tRVVLSS3eO$a۷O < BP(Ί Ԡ-&)_2΄lMH3$|E$Xf +*A,hjjb͚5DQ&MĤIX|9'N$77%K̙3yרS5P(^~e,3;mFt%(Näř@HV+@heTBv܉iN 0 s(++c̘1a]P(3fGużX BP(gX`s̡O>׳b ,ˢ>}&11߯jOP(!vݾi̝;Te(BP(M,m˄ >|8UUU_00a ÛܛHi;}H+ BebH1öLOr| WBf D-lBwB'PJ݁ͧ_d I=Fg2CK3(^{!U>!WBHG$T_FM݁8)|fզߵ(BV7 o*E((XpR2k֬S=zPQQA83|pdeeQ[[Ν;u]ՠBPC̞=֭[w֝nIC%hy%A0V4ح+PU@isOAGl+BB %&93SQuecOie^+ xs̿”*uo}/ {\tO ĬضOYj3!P>.@w%7$l黔XPbaddd ;wb6`H$BRR%%%l۶M  Bq2}t @EE˗/^;6JΪs2՘~2CwZ})R)mTelũ!3Lzw'&Pz%_l; %1Z͛Um) 9_ ̙3ꪫXd ~iBPt*BBP( c߾},],,X KXp2Y0SjP(.LP(W^\r%3p8Ν;a9`=Bh8(c&tÃfpϊ(NW_qAF,BRtI)%ez1RJ gYC OBc&;kNҁ$eM0\-BhSM`A&EdF\ĴȖUJP(݂~fjkkϺssEh:5{TE+ E4iIBRZ( % N'Ǐgǎ 6 y >J֮]i2d6o|ڽ "PVv/6.BwnxAZጝ$Ŋhndً&-g8<]jocȄ<*^|t '3$cYa_jlҎgإLH&Xp!oROƜ#"FꋘzOHLmE5ݫX#$d&9s 6 5 $DBW8< h޶yo,͹a~-ܙZ\qJK_R*ԛKp88p@퉉466r2sLHMM=Ih$ W2BsL7dtEV}˹3` g"AS]9?#o>u>xge wХWރ.Bt-L647T+^ބTFf&;ys8PӝH:{z 䏜=:k)&?w  Efȑ\~:i\tEL2Eb4/C4k:v4mv+Ҍm8|ipbE Exx<&MĶmr޽{[&P(m'&Ҥ\pMOW}\pțHsC9o>5M6Yct/rϪ7~NbZ_MԬ8 xi}4WGziQ^]AdMᗶ@􀤴y~,Ӧ.g?!!HܾT)=&d"e4;9?ROO!f[xriy; 3`\j`Fጚ]Yl{eĔ`@%'+`? j"'-e{6rxvB34Uo 4=" b[Q8{ G+&UgXzϢ UDM8].) ;RZP(Vy>/?ְaz444sO(bΝ',BP(  ZJMӤ;Ree%K.eܸqض[oE0ԉҎPV~#.NV6/#RJ>|LL1_!вA3l] G^uO6z4uWu\Ad6;9 |D8܌ c$0۩g_BwOoLg("nyFygl3{/-$s#K]lzm$"Q籟g[]7n:e(<GPu]?`E>Nsa\H? ́J|@{yMގh$/B1uTy"L0W_}ogʔ)~|{#-- MNɖgRStM;*r>>xӣAUZ7YCę>;A8&  ?O?{ 3<,RAҶZbIh^{~ny$OlGS\SB<3 ɽ&v,~؃́sqegŧ^n\Gse3hugG` ?=k2 uXTW/"׸h'Z{cI^c{);v(d؋q%tS',u܎>OiTIFM BѭeD"rrrWzZĂ={rp8(//'%%[n_~jJB+Vhg+HJ;E"Tw< AnZ'C%UEK0AU`j*zēI]#߬Nד-+QǮps5S"jr+o쟙v&?m8]u(Vz`YXKQy !!;4ׯx!(..wy/3p@ [nP|c\G,pJ,8U_(eX МۊIH)IMMeڴi i 0S2f̘/Aw r #-57p]wv&5tP~0dȐ/\uU̘1_Vg2UYW1;m6]F'Ƣ5v=M𥜏m577dž=-t!\s-&qgޝ @JJJ{aIⴓI^^UUU3x` O>i9^$ᣏ>bڵcY[l! QSSúuزejuQ"Y[ Ź$(݅.Yi>TUUQUU ;;(,,ld^Rudm Xf;'mi ӓK.qDbO#đ[vlaݯ>k~kY[=^Nel.xFՅAmw#Ucv|p)SPVVƪU1cw4f&gN6TyQiUaz⩡Xhv30Q,yd{gF|Ⱥ}8>)M$soװjWg --I5 D-eGEm=/["qkhs;NdZ49s޼@!9pV6~;^W㶵A|2Y ;I,BZ!^ֹf;}Hn3:W1CgT"pQvbwyݻp8ڵk:t(yyy00ΚCƵ YY?Kңo,Csyxi^zGNOc'@$B)>e۟>"q,4?;~L˜ ?*fm-%w~pAG$Zb2=~ 㑑(uKߦ?EٛoNK.7}ge?+1h(x%^3)^Bo1KK:V-!/Ⱦ#7}d|+,ಷrz<^zDA)\~>|۷ opEƧ~O<ٳ(--塇L6 ҳgO8[oŋ \zq[)SP\\wkFbb"i2oy4}]SrWa[6ɳ.!Z[C~=s"{Aөo1)]lnFON7~oiL0[3XXŨQX` W\qJ222f…у'Dgڴi,[K/98Xj/&LG? |ڊlĒ%j؅S8ImmtW>Áq!דC=7sfGJKj>Ĉ1fKŚ5Yx'9o氿y?ͧ,Z&4& xnsIu:ΗNnʻ"Li2!u\Cj_ٸ)S^J+taeJv4ҷ(i*iS/: ~ٳ~ZHq [7T&8kkVm7d`EEwx8&OBӴV4 !տcx](D wڿO<LJ 3;~3W|)]ҟADr2B%%$a*؁DޛӸv%+>-0M\};pfw_P}w8 &a(1}-N34B%{'z'LATNV/!CFиa ˗E퓏LoT:.CoRRMMMq  2~xxHNNf˖IEE| %%%E4ŶmZ|>MMM6g}djkc4 ]ILL8(SRt:~4ze BPut )%>'2sL5jTܭs/EA؄?͠DF±ҎMwO?dפa% ";DJ9m$ n<"oP?k0>b-K3| gS вn?m3ؚƮ ƣtlHpB${`TW]w;~c!D%^MR/>nW|$+wUU~IN3 h'zZVoko֪:uOZ8QD< !S{8II\c{>Z{~Z[nixә._4R"4ʹwm~F馛x ]H$cD"&j IDATA<?:n'`TL 8f܎D S4/ V=ʨ]81+Ҧ>^O^9KΡ( `GE8dccKCK]M\ \4cؤpn2[uoqfȟAM&t:UUp7or _w_ P3 Gu>*+N=@㥗^իW tp8vxkH9d(gu{?4*kr2U^zRdYx:˯"nRC8؉p]0OyEj`Px5ر(_ }\eC)?qMu_'o޷ ‹N$(8"㜙d||1pwF8RDv6syh.7E=i'qɒ%L8xOǬY(++Ֆn}ԩSE\w8p ^t:~]` saR$&fOdn^Ks3c _`XְJ(! 84[Y\9pA\d6ecG܏KDdgNOsҹdrd/ux-\+-dZy2="^UIl>+b;Hoi\|iwϞ=w}L8{3g I$`h4^  uV԰xB^z%~ Aii)Nu2O5kxlc<4tP2D zqMIZ$/Խ֭<>qn*e& 6Ç?P1xb\5*Z9`K?##ä?Oy!nݍKaIw>[5oq{ߓg" jGU9M6|p2u-Ғ\2>ǫ5Up8gڵkW=O<#Mr1Nr ׁ8NOV2J"TA*t 'v]w"tփ G\tھ @o}o8H:pTTTLrOBn_䚚>p8=pKǃarAiWG@"'bQd,NMKh>0 %vkk'OB|Y=aY`JMx_C{\ pY {C a/%DBȄ>]RحC!K駟NeY;lt|ߏ ##۷K&arss:oҷo_|A{1,Yo- nÍ[S$9Yz:z㓣 ZhO;OLƈ1!}Rwae:J=kv2DF:ة;Sad9RHdff;R*NkX=v,o~#Fz!pAwתּLO럡yYYYbtDWQ0t;>Jq'znWN9Cg܆jrt: tGish=GK~~~gffŮ\$c/mmqruw{Lcz6}[iP:'%Zat|NF"Pcx~-yr8xZN867ƛizn)%na1']uokjjGeʕǥNh9:Ϋuqֻ>%ĈÜ./3~|5hh9;$=Q ʼnd$ 0zh|>YFGP( 8b(_d$Do"C=jb;Zʑ{?8Y.QXt ZZ?t=D"`R`$MMMJ(P|"|cVZ… Q>sU`&iH͠(ޏ)`zI4N"mi;n*@ܹehmC>SIyQŕ:/8Yt ZGv|Kir<H8v wN~OJ|U;dE2n_V&RuLiyS]M %Lu]?17FM{Mc,+8]>:|8'D(h ضN{XG)QHϸL&q+C8^;7 MW_3<òe˔q>#K9!-V<-$H@]W-$X}Nܹeq¶8.,¶Lt۶tZ^(צdQ\q)f,@6(n4MU4T6GVJ~p!ڃO[&c% iե~KG Cwی#t6+Ie!YÚn`og8SD-M#HV(LAm3BCwf T yAZ ČRe,z$ѝ^m.ZG JwVGVtËmƉUA(N]RRRBuu5HAQQ^D"AMMMyGж?ci Gn }9x&O#t1= Fu> !۷//LE8su1|6nx\?qD UUU8662'㔸JnSBjnC]5kujQQ$^{-uDN0;}},m]%O54&eM>QOEfkkiH6 o߾z477^6 eѢE{1l0̙]wŇ~߮ aĂո2 ۺRx):#Eg]ru[^LDp{\$I,Fh:A_hܭAwHqg"-3UoQ0"J\$8귽@CVG)IN)*ۧ멑+Gg{:d!mO/}32Z'԰Ҷe @Utu XONSNHu^h6)(Ea4x+{pMwQ2 4Y&n;#3`*ũ)Ɍ3(--eٲeTVV2l0 aA"_?r0C&v,8Zf iP8t@͗ 1wϮ kHT9ah9]oG AoI!lNqF IP}z9w4 $.Y/osGI@̜9{キP]C!av:(a{Conv&''ϗeǪUX Ks /{OZLm|MhBdjpuݾ=T P^v$'~®ջݰ;>qC De<~>Oj֤m"u+hO<\7:5Ws,_.tX~=ַO~FP(,ˢ38MU^H$ppu躠hc&deFc+X`zwDO6@`[qZj*5n<%͛3p [>izM#a&zK%НYn%c-4|GYq8R' !>}:~K}l2.\ŋׯ.1`$#?Ű~n v3lJ-^Cŗ?3bfq9){]u;+q`/> ň5pyƠu۩X!E?efQ{X!#7=xKcƃmaȠg_&@.^uUT_Ͼ5(/{~T,WkTJ=6?Q}?z0D\|$I.]ڥ,g͚7.]#̙3Yx1|ضɓyX|9O?4gyfZ@:y_.]O<`ʕ̘1sn:| 66dJmUP(яRuq%Ws ?`bmdr/Gr+\ƮKvqU߫_{irAe/ 4kndsf{n# B9LZ ڔMXsc?xylh+U_De~MlbV7Q˔HcI6,V^͈#0`jU'C2o<,Xwt]'WQtzq~dsAsh;;+ffk؆p"m+{k;'KU_w#29r,7D62f]LoFbyGMF=p1q2M[&{e.*%)AeI4;{$|v2ΘĮ\h]V6. ڴi[.=ܶm ˹Xhm;JJJu7)S4 p饗f͛GAARJ4773gz!'Ofɒ%@EVL$e--cMchm͇~?UUP͛yǞ={;yWٳg2!ՋB9 Bq亮sYgyfZ[Säfɓٰa=sɁ{~JL& oDwp Er&3Pr߯1rrgX"Kjb5lmQ"'MGlnŽ{ϣCߟ;?Y#'oHZ .{N:J! 8ۗW¦&VWmm<_)m%:&+N23+(>b1csn'??)SP]]͆ z/ #5" ·hDVʩ19fPHT3𗏦TH;eQ(F|fvO$ג7:v}|Ϧ7nٴ7BO9cۈ"/sש@(Apr}?4SYV#5!9\`k?֑ bEehK]m Ciᢘ0^G(ǃ+V(#(mRhSN,cƃXS7Z?gfP*Sh>2Fl+(>NiByǙ?>>,uuu,]FùK(bkr|&lۦע:ex@b{w|%>%8 >\2D( L6qdgGi'yhH"-d5,\nn$VWC"2>= eR<"?XO(0_C0|^b4!b)!IdϿ#k2dŊL0!j*׾SZZګ- eXl&//Nkk+EEEtDH?Vd=-fI_O_z2+?Q^{ ̲.==&B0y~LLͲe\Zr)pvԄkhR;;1u21".,ͭ{#X51cF 9>>iH瓝Ν;UP(N dQ/&ʀ'-S<<3<}COlN6Ut o˲Rym JJJ_:_W6lXvK#~3ٔ/Z̀~6D^Zjcm=#')jb+HLeꌹguX q6KoM{(&j{nl=$B&zMոz% [@WobؚeR:}-xЪy25zbԿ]+̺^|8fScj]0oYgT͛yʕW^2]Bӟꪫx7zԤXJХk/ZKCɘ1c4hǪ!;#)^Q)L]) %-[ oQosANםR<}os>RJxmk 7gvjxS8;.SMM)` a-pxyGpϸ{hJ63chGF?~<;v`޽UU( #EJД1N\EL|H0z.?hiiQCv?1! àǜ9s|,X@UOQ=f׏y5*B233F݊֊O~n& ]cv)s& o`vf)i҉(9*߸;)7=#p*E,KOy=)uE.fG4fѕ;3ne2?x\.NglDw#:>b+++IRIlR] e2y<@ӴAIrwV:om!}t nwDpR"vӅpz2HLv誰tl+Gǜ}G:투ꫯs !8lY)u:ׁ׋,xb^yӠ .fc[t?Q۸"A#{H=XAmD*(! %%lo`y^vs=477 Bq5T}c[)"\HIt[%w1ro>@g׺z ]`ܗ imm  y?l~L > `q llj# ޽[  "GV( 3;tÉ&V5J닕b' 9_SX ĝ՗pB"+6𸻎l84Hv#8 DF&1* kJSv*!T'yFFQPP a(JqB1fQ|N:j)Xf %tAu<h˲4 ˅ضM,;,IPtϟr+ BP( 4 ,fĈ,]JJKK?~<>d2IMM K.UBP(aݕmk= D:E@9=(\ݕ"8:$'4݉fx'4ht)ƕLͩ@͑;\mT4 L8˅1/_a3gUUUթ BP('iAIJ_r$Hd'hi[HF3\hdY$$mNF(s5m"$ M7:<`V+_N&y4gZJ ip~+&m!o4F`ۉ . 4lhӎd҉7 ۂKJUA##>Oh 4a&pW,(**"??[2uP(a 0\ibCP( ǣf $#MxKSQ[${ۊwxHmbzNZf}˩ eēbd R3~ </f+ g2_M,pdAӑafm}i25ط&odm3e-!#0rLpf_"Ãp3EC/iϒQw,"\QUHq?KnXhAv%z/EÎwiܹDNqzB&L@]]H)m)e:ބ p8۷p8+ Bih2Vvo6}^Cs]{b1b Nt*C(ؐRq\ L$ha|n[Rc061%ʓU_lltɶ/_iܵ~ wFnwaywkQQ( őXh;vm"੧BJɂ p8QWWP$1?nO&e~L*V+(K,R2l0 @0D:رcI$h(!48&Og? ZMрI ߍnmlNrjg ^_ @Na`=,y@2s3tI&"t 7yٟ1~Fu#'F]HڿÀaӑ JFgl_ BSK xHcc!lٲEH8^RF(4'$ϦMܶmƍmۇ: 6F%wm3Hd<W63æ3vƍfhBRI.8Yx 3y.yݻSd٘}ddRO/gs#Nݫ|jNBP( BP(N`̘1$ jjjm0@yy9wRgA$YyeL&]#NK CϘˤ ~Șn{&doP >rJ˦ `|Z2bX$afH$ @j}@2I0hee lr+l|WZ̸7TV( BдlҎwy_Ttc7fR(>ե2f3ϤQF^KFFqwSJ#puDw-!hp3n&tte+ӖvH`Ehi؋EBc0BpyA<L&,34zLY BP(!QXRi[dq(Pf:ݑA9Ymvs x()J,Rz 3<]vX|9^)%Gryn47请9s2`GhHRۊS`3dϖQ\­ؖÙ:RZ"**Dwdpfa%a؄ٸl^g >SA<'Hpg#"[J1v;TV( B$T}+ i[hvkk*o;MwlfN4+c)J,d1M{"L& $IRbYrz>زܫҶ]|yΜ λ~mڸo>mň 2vuͪ~Iq{-fkp9f2Js}k>`߶% 9KƢ ۶SxDJ,!p`J {i; L2nڵq΍dgnpTV( BDQN׻,wp@8lvk P(m⁦>!?z߂0.O${k,Hs4p8EmmF݁Jf@K /%ߟjX8M0&@=7޽h8L<n*i9s)2XAD[iތmLjFcH,H_Mx,˨޳ Ɨ[B店FZټi":( Ɋi9q0|p\.6mR} #tb&v7sp{r{40 t]?I]q]{,~vg׋Հ#@ױ'e=۶ٳgOF=fWZk>n׆Zvu.ˬd[^9` v~nۛ4j:NwkۃTvl~HQ( BP( ,- ؽu X2BP( BP(2KKFZj7*C( BP( rR,hY>IJI8&  >Wl'w﷏oq~(CPwq9>?}~Lj'̖zG vя~}e]F2薑A__[D:*q%0c ug* BP(  :tM :o|[o[o|+bc>pIqG+/<*Zn>}y"' ;8!̛7sD4Mv؁eȑ+eYӇ?0a>,o60|NUwBP( BP|Jtøq, "&I^uX{DDY>; XyG~pqT{D,"*0жqgtkVشD2 5+1wmɋu42gYPDdNmLC/,&cĶn{TP {'bD{`>Ed̚ItZ⫗GLqy1o<222:D!9s&%K y'(++;,eY338D"ŋGiL4#Gb&+Wdή}>s+Wv}իWSUUŭYx1pB~0h >O8BP( BP(N:W{ƍ7.\JaƌAVZջR?5~":d$h}ip7D H67(}1<.׿oN8 _ro022ݾ LE}= !jց}?~@ 2!{o6Zݠi(;Bj %ٳٹs'555i{~xGss3`V,Y%K)6lwqάYBpUWqEH2DJIeeecu]B!6oޜ^u֭[\^+BNN۷o3uTV^EP( BP( gP,>|8QSSE,]X,СC7~iL{1 rλ=Lh 8{{װH eOD7n9gf8Z 2 />s:]4<wv%E]rc0xKe9]q5 g.+Gs{hxyh3)-~eΦ.0m4>l~yf^/RJ7D"կo>.{+xw>}:[l#b̟??ϔ)S4swqF&N>]v1tЏ7AP( BP(XɤIؽ{7SN%33r8@}}}ݲe 7tlٲ~ۑ}~/%H4c[MĪ*q  R#v`?vs#2O&99ر(Eo!rr(p+:7@Zv21R1@Ӵ!C̦M,@x dR-[F4JJJ0 <TDez)))!grrrm!lܸۧ躮NBP( B8iɆ B!l&bYiBN'!w{:LSϹLű71|>D[=g$kSBAEvGV&v%I] ,xɦFggDb. ns}x8"rrؽ{7]WSSCnnnz" !H$8} àb$aPPP@ss3X )%t.P(-Bii)?Ob444 5k۔cǎtCBP( BP|F{͢G;{Go[PPPb=E?iR]]ijjbРAڵƏСCӧgqBX{w>s*y_Vijp-%q}J up%Z~>Z~!ɽ1jȿ8udLLOnǎDY>r?7 _c'1b-1 B6P|w3mڐZح >wcޑ^0gGnwZ %ěoLe_S>ɾ#FYp̵^ˢEB!غu+3f`̙3vXسgvK)**tR__OKK sΥ3fPVVƽK0ӧSTTرctI#tu|222hjj1^A2.{;7qY!0WbJN< , $$w7 g"=|͠$6#Ѐgx֦2%h:`Gc[1 mX*D7o_6H'd,y'c!uۼxK3}Dn&vVB9zAC0~; Bw^Ǝ˘1cxpݸn^}U)//'L{D4JN'cƌSUUݻilldܸqH)yGEᅬeY5 V\I}}=.L~ma`66mbڵ X~}ϝ;d2kb(J,PbB %(X%|Jb\ĂI(;}mb~2 vqRJ])"Yf׿K%=Yoӧ Yn*@lsea4773g> qD;*'=n0y|T9gL$, KX]p(mjo[zkz[[mmWkP.-RD(l$e&zIaj }ׄsΜ<,}]#ʍpqžn'55W@dff%.X$8<0D,Y^ z_&%V ޽{y'3gao'ǧB!BŐ`gM0mp| oot< z,B!B4Qo&e%G;5pM/[Msx@X\YWNZP9`^?ir9aÆ#v,ÇU(N _N IDATaF8N=T^{5N|rB!sYE~~>]te^s9K/3goln SB!B8X||>kyaY۷o- m'c=NV<l'c}';'TA8&L~ɨiea> 5=ǟp`>1Ns8'8~[qqlCXF7.#c[׬AR4kczCc}%KVzFBq؝̙3 BڵW222=z4G&===geQZZʘ1cHOOO`ԨQ7^-rrr(,,dС7LRSS6mƍcذaL8G"`Μ9\ve,[,7`޽Y xB!B9W'Of˖-5*|񴶶҂磲4_iEI2ΞJ_"(xEѺt -G`r\#Foj1c1E| oވcT7܀w6nm?I ?Lʘ@Etf> }ooN€-- #Dp  _*AE!ed/`AnN=T֮]B4TUt =.XxqYx1O=J{477͕`B!B|.)Sa 333 = rJL$==QFbŊ>[؋A,Fw0 sO=\Z8u$BE3-- GN.\0 Pu?Zewbb@ %- {BIK;9ZN<N&@赗PҎ .=cƲ?njňVlFY-v'sA㍨v 8}7]1TUtjU`ʢmۖnPUUEYYyyy`ҤIL2 Hr,fB^$jM.)P(at5uEQB!xo,477STTĐ!Cx:X FR[[Kqq17pC2xouY&B!oZttto( .9se۩㤓N"ҥK;fAl5Z ~x+M'E< V"9yds>]"&},I!u3V<綊Md_}-{Kqdeٱ捠)Dn;t:>mXZ__Xnj>ވ}p1i3'QW'0A,_"FxP4 y/HFkeY$ nܹs7ommmdff/6t]'p88:t([l9򮭭eڴiPUUE<W_e…\veqAvܙ Pi555B!Bϑ0P<ԃyh=YYYl6xϝG"OQE!''{ iooѣGڵk:F O(Ce p*%$v zHlм>:׭"\92uۉVUZ9j,0'_֙thm;] *[ﴳI;B`(NOHWSO|G-hٹd^~5p(9d\z9Qcizහ׭B;h=Zf&_[t D>Zidff2|p Blܸ˲;w.'Nd˗v7n7ofͨ\@II 6m2v;%%%$ ֯_+N'UUUuY|+_*q\\tEp]w%f^{-k׮e2#'UU?dĈ8N˥cp8л?f*n)3i 4 իc>I]}o y:ϽV퀇;`/--=r=S;3Vu4MKeYl61ejKD PuHg׀>+,`0CĢXhq4a2`b's\c())? untz9x!HtvM`-[FUUUry<']XvX @{{;^7۳nO~ bax<|q (hEQ,"??׸B.GGZohmm=acܹ~yysK$I^fu8|>(DB288:::Ns |>zDхw?jjj+%Bq\R_=[a֬Y >W'( cǎrI4Q!ݻwseQXXȊ+7I!'~ղ@4ONMMMmƶm0MqAEE'P!,?O<gϞ=)B!8EEEnjjjz-铤iFbӦM2*B/T,c(B! >O6SsN4MKNX\\a޽r!B!B|u˲|hƴiP׋륡TU@ @(Bop9( O?dq@4ΝˀYz53gdرq>nݚv 0ŋ$؏ >N; ΦMXbg}6,]Æ OO?˅<1~xt]gՔ]c{ 87x:~bҤI 6g}Ɯ9sW^ɓ'3qD>#֬Y|]^^saJF~AyEQhkkgeѢEK477fZZZpSSS#S!?ʹKii)tM)ӉqgΌ3HMM=cwy|>~H3 6,ٍuĈ\|x<nv)))̟?'ܹs%%%%\.LBff!ʎ3s璒w]ɸ~/f޼y}L8s=M7݄\}v.OII  2 B0M4F$ LӤ0رcB~pΦM(++cĈ)ǁp8믿Nkk+tttp8HMMEu"Hrۑ#GR]]~;F)l6|>eI'D]]wÇOnWTT[b1"_<qF*++{}&p`Amm-wyIJexגR5jf͢?瓑t|>6l`ͽ>K,Fyپ}{W"U[TB!54, OJJ hT28qua_yz 238TBdff2t^A?KW\q@Lb(Ӊ(qg;v,/eq=fϞ磠233)((~wdwaÈD"2224D"A"͖xb,tPUUnB~-qF&NYg7ɔ!C1cf[oEaYn~:W]uk׮Ų,nV)~FQ.2-Zȑ#YlW{W_}\D㏹pݼLqq1vYh^UV1c F;y饗$˲0 ףir =6lGy 6UW]Ÿqشi3f` _w*~ (Yak`D{ii).ɾ,+9ހB/'YohmmB! nJ<_?NKTfff{^Š@л&`umu?zlR'%:FѲ 2'7Nk7^OuGP Ƭ?!5 ܁f+bP6mg騗w}_x aȨ wnao!B! ]י9s&EEE\ 1cFfcٲettt|i10MgIslrNq&t)2I  QT'emoǙb#QOZ*F"׎jK9jZ(Tp|(e&l䔳 MHqݝN)n4UW%7X4Gp- <%]ݕWwW?M7˙5e/qҩ,t3Yc3a#l^5BQ4xߋiyLSFMX{^ y?g=JBF"},3A餅Lu.OUyocYg_ (5F NJq`HXEfH>^,}/vw6g_X;p|/݂Óg3l'wι~h B!'~){~*++{ ЀfcҤIL 8ۖeP4,ӏ-=?뜞lνIcv;<9)ʺ'頥q+ݠ@s"o7>CX [.Cvn^GI-;h\(]wu9P@ռ(G4n"mceSm}<- 3dw?hc/ԯyM/l/!ŗ]|-x@YHôB,rN"Lu'^<|C[_'ҾQ<漮 R$@c& U["oЄ#/&Jn(RsN"#0R!B!N<eYKVVz*.,Z[[0a@{498q"˗/uh Eq@8QO;ed]] vOBQPuW~㝨s7QWT(j>zR]fujvt=QU@Ub.cOuDbj6~ (eYڪMx)Q­ԍ б13 ;00{DQXf(O<=MMMX}:n~?~X,v fݎwݶPWůaIcJLCVio1DrO^]8P_a/Q0d2M{ϼ.?&f1L,+W1 (Nf(j7lIgo6:]4ٕf#Fu+\)*]no>\vmz^ݍ/Hzpb.w9dRe:ca`]2 .`Ϟ=(Zӵ hYeo[ڴ~'_BWL;Ֆe&+VߥJe`q:F|嫞}_E<`Xq˾Y#ؼlX [3kl]5[N 0i޳֦m4UY.Z+ڧ(}. =i0M˫Q`q񍯳yͳ4|.iE\8b 6mg̔+;/j[zDхw?< ]]n{e"$[)?{#Pc>B <#'mrWz6s9X=#u6/{R B!8I@`$:y% gus,Yr'c6Gg܍i$ho5ӄB!BH@jjjwHb:n&`֨jK%m!m!a%4:jB3HIZn T.!B!ė/\.Tul6. Tȕ`5[ef;{TTRTlL-_,j ,-_OWX"ז]lз[;^*ϫikM;7\V]⺢00)6RT슝t-=9i̞=0A!eggSXXHAAʷmn6ǿ|?_|k׿^WRHBVkY`SNeر,_m۶ɤI4Mvʕ+40 TQt{PFkY$_7QVʍ#o(QV6:q؉Y1 <`Np'׮p9j*!+n騊_#A¢lǧ0,h'/XmooëON*%%h:%E04śP̮tPb&Wr,(YO6]]Jmm-.ӧfB!@z+ :pUVgBgrfi?>iɓ4M I!˲0a^@ xO0MxHMMΣDtfbȢs460{ξ+X:mO?gYUU:JۓFqI]mrq=Fg<`}ٶmhn0 Ǝˎ;L 4MϟϜ9suwy'|R͛ǒ%K(++ngyk.Vf5+{z=_ƢIurλynsMK'ESk?7'D^nLJĦ&q/5n|\~GwÿSO13GL;;GOK/W^}w fJWǪ=cX[!ݑ΋S^dS`oSSR@L4m)xyjEa]VHB!@<eFz!:;;={6v0KyyyOH$صk&LBH);;lnԩS˝N'Pxv z'wp yjS [CŭJ@0j]E<ׇf-f{d;z;u: 55DhXD QUU#!_qL$sN4MN=T<+W䢋.?sR[[{} UUU,\֮]{ dK/l-[Fkk\!t͘0a XiXEee%ql6U{Ċq-=FH:ؾ&uNb6E%/^w'_3[o9V!--퐹ƒ 7of̜9p84MƎK,LlWl7o\*tnu ~{wˆ* K#G- %fhP\{xup9l4, 2;fٳչ`M|5!+ĎbM|V D(z'+;VҬ7}7mwr멋:޽{5fB!'Mhjj' ğgb#F`ذa*0z#4Mۇd̘1tvvbdK_,,LJ$aرx<222hmmp8LFFpd u4wM9Sb|]CQU'ZفiXv 3>hGn:x " ( |>xG+O6wi)SPHSFOӺ-,|6-zKjWeocbba%+#fƈ]njOXEU>};Ŗnꘖ *#י ?oԴCֻ\.btAB!3=cEw,0  ܹ>_|FN>d.\HKK vLB|i[ƢExWXd ͬ[Vl6`-[:޽*>?zM-ok(;Wn9hΉSPvF8`8K7-;I'1Ӂ_/ --- 4W)))0a4lȣ>),,$`q~{\y啌9_loNBW!ݣ:-[Q2 pkAK'a%i>V  vdS/%EKaF ulFvUM(L)$וU֩wȡ:rf13q2?Gz/g B#AL;ضm%%%䠪*{9l6f͢4y=vN-N4Mn0㘦f~ `˖-F_5$0 :?\Kd&;KKwfs >(--\u VZ}~\ ~M{uXv iZ?[8fOBu{1n7̟?l:::xijj" QWW7M̙sHE ٴiӧj"hͣLç< tPCJy[9 T&Ej5T{t&:e-`BH14m(/&nŹw˽4o} /Yﰥc a=ܫ,o TëMv܂_dbD7/?U O-7ぃ; \.7n`BO\˓][pklUVwkv tMw8gㇴP4 Ejj*`˲-K,IOB8\]+vw쥥\'CȲ^_(QBjj*px<$~䊜a45;L}.}MWgda\ v;F}F} iAigRw=T*:PUǡetY߰{v8q" .;p7SWWG 0p: 20v"ƠAFA{{;MMM(_̅^~ߧaagϣUŎȎd_5Rw)NU*Y.p0520!ɸv $Zݑ`k xTU*f8yQQh)wӬ7Roaeb{Q1bc{(v~k bfD1ԩS?>wq!P!r;l9B|̏cXx1󟏸o[Jee%sQ[)!v;^uc>zDхw?< ~T-[T˲ QzNfHW];,G<իx<FOӸX,FYYYmc}'r=ox?]1GM4%YivRYv {]xUTF+yͶ68f'BzHin[h;avQG¢2Vw '&X`YguF0 Ldlذ &0n8L?d˖-0B!B!N`A[|rl6[r!C0ay\.3f̠%95B!B!N` 2vÁƲ,,b߾}dff@cc#455I !qL !D3ߴ,0M3gb&~ 8 <: M`֭r)YpUUEUB!ĉn% DUUnJZZiR^^NCCH7|!C`&vwBl6x\2B!'˅2p\ \( lڴIqBOrhL^'By^TUEc`*(⋐H$l2B!N(C4=ۤ(B xB@!5Ijj*D⸿W]׉b J˅uDMp8t Ԯ"kzk!N:4Vi#ngQUsçPT|M0XDQn7vp8L"0 L!BTUfvq:~ȵZ&X`Y3gΤ˲0M>r4Mcڴi 8& w0n7,G<Ҍ75XĎ\#+ r xR QfwSal. !NeYDQ4Mjw@fB!pmo~|xW- uuulܸvk~D"A}}=YYY'M~,PU&MDmm-{ fN:$222'PM eGJ2p r FQQeX˛ô7 6b3u6_fw3hLO2cl`( ʹoÓiAC CBXdUB!kOnSbشiuuu3S&3NӴOqx,DV B×1)GQeR2~}@ ]0L>}-{j60M =-uƲ­|Ud;W+?a?~G<]O΋gZ$H!q*!BuNdO}g<'tMblN6x+,t& :Ύ5D;ێ6K`:F"iD{xF, i=EH{-5WR:q.X毉GZ,Jb&bF"O_@k7OmA!^}~igԿQ;-,,Ϟ 7iُiijo2vРGZa[A1&s%vr*muCNFD NB!N Ls%( TVVDZ,cǒeȑ455Q__ʷeaw HBPPo-ǛM3b7[hh__ ,S'xqgoҰkX EH;  !?<B!ĉA~ 䴉[nEQL$??I0$??X,F]]eT@SrĮy#2L CP<,L=Fǻ`nPl4lwQU?wzz! A ^ " VYPuEW HhRj%!4R'~Aw}+8ssνssx쀇ImԕlB% :֒KdقV(J^M&.eF73(+Y/Y*1B!y3jvlտW eyYY +xI\Rr_9peIVZ}T@פRfBAz!Bujժp}l!ǎ˕1ݕ^KտT5Q-Ww3G!B!i$B~e8B!BK~SUUx<ϼ[а1nx*U~TV-Zj7<8U'!**jjUގ^}ə,J!B_73 AUU5kFzTh==ɓ' qƄcZIMM$x`%4]O.K rhY;'cz衇PUԫOhP;lEˋ_x7w㉏Te鹥*;teN_PZȚ#j HàP￟h>SFB[0 B{_Yĉ:uJ ^zF2331 w}3⇾f5jaHl."҇:5kcCbP14hDCbj`}0^y>6SN C`0j7jբK.,[L!14XZE"?ꦎbbؘ.m.PX&~MH0'`TlO񣎩55hטcLQX$$+PObh"IaIʱvK}QVB6B!po`0@nn./_yTOBU WB4 n‘#2Wpl bFǁEg .;.3aJ@@ ?#kԨMB!B!_k׮deeiРYYY89pV5kRXXHEEE{Cd4zBzC9(~*^lA0_Sx]^ZQ_˶)T6oرcvfBXw k3<0ghG9QvƀeiڶڬLo4΄Q1 \WMb"*111ԩSM6 B!B񛙽;/A6mh֬'OdJDDn&Mp]wqwRfͪtT=F#՟I+)^-N',\EA}.=@ܛ5*8r.| ΂|9s D<::shdÆ 2`<ˎX 5zA y2Im'Tⳋ|i3"?g>C3g Y,;(pz{f=w;i&&LQ)>8ƌÎ;8~B!B?(0>Vտ\`LLLlmX]bUUG\. ˅( evt:(*+!d/A3Ԣb?0UnC0@ E-.B.'JPȿW5(PiΝ;SzuV^㩺:(wk S+ѡÅ2O!$X B!B,B!B! !B!‡ B!BCB!B!!!B!B`B!B!|H@!B!>$X B!B,B!B! !B!‡ B!BCB!B!!!B!B`B!B!|H@!B!>$X B!B,B!B! !B!‡ B!BCB!B!!!B!B0ʕfIa!B!- zׯ/),B!Bx<[[,x$X B!B,B!B! !B!‡ ~E6UUtrn_ݷ_cYeZ!B:ïကnvq:\x{&n=5"11UU9<DU_l.]b֭$%%o>&MDqq:th*-6lfq*%%%=z_<ԩCZ=z3g;{/駟q9s&eeeU.O۶mٳ*Ҹqcׯ={ÇWTVG} Ͻˁ8v5j 11M6( j ???Ν;ǁHHHAl߾:wLdd$k׮%**&MDNN{Pڵklfddd*uԡqqRSSq7F`ܹsV+ԯ_?˗P$4h@~~>?NEQHLL$..۱Z>Mسg/^DUUWN6mx<ܹ˗/( vCiOڵkGhh(ǎ#==CZHJJ"00|vލft:IIIԯ_)))(BÆ iР Ҵ ]vtX,ڶmKdd$NСC>ebУGΞ=KZZ:3!,իǴi(// l /@PPyyy NTTCTTύJ~~>AAAL& HFph7*ݻwgȑl6TUŋ;w"rrrVFF#SQQǻ&//_ n0AԩO>$۷rGIAAA G~_>Nv~t,Z~ݻ3yd?j% {Ǐ7u:zΥKX,jU *Wڼ 0p@v`߾}>|ʽСC񐙙ɹs紛"rRZ5TUOUU.]Dxx8&K.]W h4_y9o PRRByyEQnc|'L>N:1b֮]K:u?,:y$w}9'|o'xMn:FMll,f́xW0LKDDD0`ƍ#33hl6߳hѢ*+vݻwy F#9}NcX8s )))ѫW/5jNd2[oyfz̈́ (**BUUopy̜9srդI^xIIIO EDDPVVơCԩwy'F #PU^ATT̛7Á`o߾ :ڵkӻwo6lٹsvMxμyܹsLj#ҥvo[n{5M6Bxx= !j@YYo6#FoGj|ٶm:tFиqc,ZAQfM/^ٳgٴiwqp8xٵk˖-^??*+ĉL8)Sl2V+jO>{po3k,.]+W_}֭[9x ?0m_b N8ŋ FUUU(̞=Ea6q:<ڵ*rL0;wgƎӧ+Œ3x7O>$NbZUVlٲǏ> 9r)S( :u뒑QXx1Ç?~>nݺq)N'fuK/1~x֭[ǝwI:u֭ua3H}Q f̘ĉ9x ;w&,,}x<|<f'O0el6u۴i×_~رcx<MJJ 3f`ر^o眿VNNÇ… 9oC=DZXx1/" ,Іuԉ#FFӦM r;tڕ-[0n8ٳ'eeeL0ѣyWiڴ)zM6?^^zq ҥK#!!A+7 .dРA |;çRz-IJJb4mڔÇt:`6QUߟ-Z0m4f̘ahٲ%&Mp 4iB 8pOkiw^yffM+dC"p8|nn7YYY4nܸnn{>_{;f1<<1c Z;:uCqz)xѣ񐓓Cll, a6ܹs4k֌ѣGsmq!n7fnѣG3h:FrJ FHH.\M6DFFj>Zh#Gxwԩ `ݺu9<;vdܹѭ[7OaQ\\ɓ'߿VM&͛7g͚52i$FI-ʢK.hтB<:Nf~~>XVʨ_>VH>}طoɔw^(**d2QZZn>gggs}O)//cǎv&OٳmӦ ۷ogСdffxY&3gh*rr2իWgƍZy^5jÇiӦ .l~aNJPPǏ!2202338p {YfCBB>,{ԩS\puq;wNGLL ͛7d2#gy(z={iӦ̘1D=zaMAAArQ m۶ٳ{Hff߿?w&==DTTaaaPfM̙C߾}x"ǎһG̘1{-[Ķmۨ_>/ڵ̙3h- bΜ9L6'Խ˴iӈĉTTTСCN''Nd<J͚59~8&55D\.Э[7bbbxwXr%tԉf͚ѩS'v_W1cvFL8իWOLL 111YGRZ\ IDAT~֬YUȎ?ʕ+ٷo%%%DFFKƍy8q"'""דNXlwu!!!ڰ 2Yp::u t:VW^y/^\e K;iu:,YB޽J˗1 X,nv-Νwƍ}t:۷/{/>yyyL&4h@׮]9***x衇h޼9~M+]ped2`кb{a֬YS-2dYYY<̙3E_SVV믿5kd֬Y 0i]ھFӑG5;8z(={ʂ W^iӦçǍʠd;f{;rWAA[lтvj׮?qZ~~=z4)++C׳qFV\ɼy` 8/f qvg}Fii)gϞrYΛ7Nǜ9s߿?W楗^^#>>o׏˗k^n6ƌCHHZ"##:uЩS'oߎlbwߍ?ݛgyjժi Opqy|zz:'N`ԩL43gPXXHxx8?>8ڷoσ> +,,W_ɠB!= n7ٳgrtܹ~Jrr2~~~dddpaj׮nvӭ[76o @jj*'??Jbb;r1h w` &&`VVy 00X( 7gϞ4k֌hmg5Сtޝ~A۷< ZL&֒ئMRSS2PmVM&wF#:tVug0XbZuګcǎ?ٳ;wСCL:2B~&99EQήrVtwNqq1X,TUeϞ=~턆rIjԨA9< 6u,YjժѸqc֬Yرcڵ+z(//'''vJdd6餷FeTVM}ZgӦM|7$$$\7 ؍׷o_6m /s|Zhf3=ƍwyZYZ~=> }!00p`ٳgY|Vr\׏QFzjmۆlFQRSS '99FѺuk裏`=}[:t(ӦMZa #Gf͚Ԯ] h=E{7oN֭iҤ >|pLLL6wNii6޼nݺހS߾}yW αdZlIٻw/K.eռ$%%ѢE -[ƞ={۷/ʘ1c`Z/-Zh!N>ۭ}( EEEڸ:uDݺu֭lݺH Dtt47nݺa0x=yg2dV..\@aa!;w֞~2$BBBh߾6ƛgW|mذ>};p\ddd?MVh۶-fv;M4`0U)**ԩSt @8taaa_]RfMvJڵhРN^zѤIf͚ePVVF͵!I!!!>ѼAIۭ]+˵A0L8vE͚5iժIIInݚȑ#]6jբAZv4iD;7n)((ܹst DHKKjҫW/ZhAZرc%P BAj= TUr]ׅ822 2}tRRRtK.{G~~>> [l!::W_}cDzn:V+~-JS\ s8 >^z"RRRϱZlݺ!CгgO`/"|رd233IHH`ƍ8pKj:ug}Ʊcǘ6m(·~wAZZOeݙ1cرc',,ŋsERRR裏n 33M`XxFnƌ??޽?QFȗ_~?O>|8jҞp!MFVV:-Z[M6 >NǑ#GXlN?5k{p8oXv-u]L0EZZ~gܸq|op88N-Op:Z[7o~iڴ)}p0oЮyNZnd"##/9<.yyylذzbXزe ~!̟?Ae222X|KUZZʲe˘0a~)cժUfVXAڵ?Aii)owfryF#VbԩӇ_~cDzm6 ꫯرc\*޲>|pmFvv6V#̙31Lud2ѪU+ ^'==%KPQQU]6q\|Yɲe?~VՕririٴ***|z0Z˺w2}Njh6ʆl6EAף())7 $$Gy`q~ڵc̘1,X@kIBVEX.\SO=ϵVUrn(="ЛGa߫ł(ZEh4jyz[ͽV޼6 mvc20ZPnk:m[nvqEQ`*l6*AoeKUUR=6gזAIEEqpoŋ}WTTrx>{+Ǯ{oi|Cޱlx<4+// |L&-Xr%}˖-9NoEÛgˎ7fXx |x=+ky\[FTLV./( t:=rZxy*i\8s  Yd Ǐg޼yp8|Z+:轞x]f =y=kڼiժ3gd\w]u\X,-v}t^wTumTh;UVv{{MQk޹V;n?_[=NUU}Λ\+zz(z+_B]+006رc{']ԫV-(Mg7 7T ~Uo7?EQnX 񎓾~yIzgw}7=̘1gUv߽*\@_.w MT޷ʠ(U>Qx_nݺ*ލFlo7htqF>ß}:4LUNwNZ:oN7Z`0TyN][*N9z ??;?SkYU,Yv-۶mY՟ʯ͎f]n&7J*ҕ*n/UmOεFz+B?_g˲^''' l|ZjQRR¥K !B!gr%nIW(¹s稨 **3ŋk1B!B!~է!L&bbbS<>LBB~/jsϱdrssV^nF:uVs+B!B;~5d`ܹ9rUU)..nc6 EQv6\઴0mr/"m;n[{aii)OUU|2N zϚnSXX\v@PPK.U+/_yp^Edd$.Bvɓ믵m۶eԪU,-[w}á=#9N +㤽,ix<h !B!}ziӆ:oЫW/peTUiӦ|'S^=&O̙31 WXAnn.=zw}>Jݛ7x9sk.Ǝ}m_m6fϞԩSo8ֵI&sNlBϞ= 1۶mO>\.oj2h ߿?<?9fذal߾;vjAsN~x V+:t`ժUX,<|>B!B!_FSV-ׯOjj*.]Ν;5k.\`لP\\Lbb"0p@NI&kƓO>IZZmۖ 6Ğ={VaaaU(?C'{ia7mڔӧ[o`JKK<>Y @H""[mݭ۪^VZj uK ,3ds~@3! ẏ̙3>% ##c+سgO-7KuCX|9Æ c~8NfϞyw9s&ӧOK.x<zͻ~3Gjj*W,YrDs|4)))asw2rH~?G믧)S`YV9++AopBxR?1yd&OL~~>k׮e֭\pdggF;v,׿ܹ3N?K?al߾˲0p8dddŸ{yGHMMmu 584)̫mDZpI&0{lzAII zl۶?YaȷD,D"gƍٲe H]ظq#>^z)|SśG"<. Cmmm|ŤaKKX,F}}=4  ͷZC\.i?i5k+WS__ϦM0`&MO?T)(,h_={r駟'Ly f ^cԨQL4@ @YY(,h_]veƌ<쳼у^x?j.]|i\2((('xBxgYbEX9oK.gyECCC9ꫯҩS'yyFE$9},(('|x ފi.55%K0k, 0a._|ҿ.\H]]ph3f0mڴxFY``'xsrg`6vm,Z_׼۔anɓYtQ[]7x6q<|iqqhנAxmq"AϞ=0 *++ٿ?mvrQUUa߾}{&55;vŰm~J)**"55Lvލmߟԩ}ppuQVVƃ>xԱ rrr,vލ{x<كw۷p8LNN.TTT`&z" RUUu8>I'DVV?a˲ػwoRlz ޽{rѷo_ ڵT| IDAT+>Smуݻm6|xpu@%,`o^*vSNeڴi\.^}U/^'""""""mݩmm6tᠨ׫ȷ7.,8x`kєPRRo$!zUDDDDDDk7FS^^~ E]]-O>_x[G0?)sO|/Cyy'ضMmm-k!##K.on_׭Nx+0 !Cw^sANJ~zӇp8:t(W]uh}vz-׈|uX˂4LӤ`0ȫʎ;,(,,$++ٳgJVVgqYYYTVV2sLRSSFTVVf:묤)@QQoիNo~w^.rN?tL]bo(--!C[2 >۶m{ 233޽;w捻ocYn &p 7PVVFQQXݻwn: [laTWWu|uX˂+V0yd|A6oݻy`ɒ%D"Kuu5xb.R,ѣGs饗ҹsgv}Ǎ7xD{={0}tƏϪU}HKK#%%.-JVVO<w}7e%=Z웦I("---4 9x4h>͈#6lX{tԉ?a֯_Ϝ9sm>vs7Ѐmyͥ4袋xٴi*^{-<,YknVB/33b1 C=D=X`h4޺ 1,0 "n/~ <덷o>h$,fM6;;;t^Tm W[[K]]`r^u/^Lzz:~!:/_ٺu+`޽{ٲe +WWbsrrD"|o>6oLMM {>Ȇ f۶mAHOO+V9}ƍٵkeo>V^M0;vP^^N$M6}vˉbڵ{͛7SUUm~ Hb,Z ܹ} XlZeY~ ϰmɓYn{aժUXE}}=;wdضcƍTUU߻a6nxԮ""""""rb/>n}n'!,H  A#aq\ zG|8۶T04iG&2f|M^{oTԩgfժU \@^^a0qD|A6lؠ""""""_ ...^DXƒluڶM8&''?7y0dGbȲ,('th/ DDDDDDE- DDDDDDDξ- "H|:AlNmamg̘}عs'-y"""""""_v)?##j^Fϝwᅬ`ĉ <xb=z`ذaB!Gqq1~a|Z3h *++YbEDDDDDD.a@8f׮]kvi\r%/[o Ä 뮻>|8wuݺu+?)v??я4M#/p2"YYYAEE555~tBJJ ̘1ӧP,K߰-,0 ˲=z4֭Fܹ3N@ @FFFoll'x4q8ADDDDDDD&aAff&\r 7tns璕?u]mߟz 4iA@JJ /^{-{Ʋ,<ߓgs . ~hu:7ԭ%)))Ӈ,***={6~)Nb,bԨQ8pxZ< ӧEEEٳb#G$55׳uVuEo$bkzM4_UUBm}$#!(p$,kРAc^@g6mlhm۟FDDDDDD&--ozz:`u@%,MA,!Y9hp2%%׋iX,FCCPHRM0 viZ;Pbf;쇸zOpӤ+2Mhۛw-XcOKΌLdV=6L_pЩS'\.U9an7.x4M:uۭ 9q]cc#@322xuXUWcd64|;Р}M~ǃ4YE}}=~?>u  ||> rrrr[>|8˗/>`РAydee B466&I`0K 466*l:˗ogm`0H]]Xm~"ȡX χmD"~? *Ң#Gr5PZZ?nJuuu7㿵9mzhwK`ӧSYYI>}͍?F|x99V6`FޭeytLc uCڨMb)_{&?v68P ~8ݺb6{o }؁u!r?vlP˂cY`A|z*4wˏ~#Xp!K,geڵ;d„ ̜9F-Zļyx饗4͕|n'Ofq]0رc7|3ƍcРAx^2228餓xx9餓0`7o/ P~իW3fxGٵkv|.={+WzͬY8p UUU̝;bΝ3<Å^ȵ^w9ɓ|ocӦMGx^.]ڵk ضgܸq;7?7L.]oz-jjjK୷_WRſW^ <7x)Sp駳i&RRRk9s Bm4#^|i`W8P'wpsPNbrLI4wnOZS+,0 ɴi╴#Fȑ#3f ]v%++bիpR&Mɓ)++P;U,65UȢ(ap~>,bʔ)撝ԩSIIIo߾I4eժU̙37ңGr\'䡇O>OWSLa߾}ߟ III~ѳgOzҥK8p wyҷo_RRR%͛X`={n`֬YAΝKVV={tҿ>c0Æ cذaӵkWv)¸q̤[np\krѭ[7Ǝ磡'2du@m2l@*1{+kSc6 w|,@t'N=S~m OߋĠ{ٿ/X(+VzuٴHU5%Av\w+@SŮ j@ЁJKKyw6m8p`0H}}=seΝAII \z饌=ŋG4p:UgYUUUٓCl2 `Ȑ!tܙm۶1~x raFeY|ᇼO:5 H$)_(0xXl穧SO%s-3ϰn: ࣏>/fҤI\.lٳgK$/"(,,dܹ<L4ݻ3g֮]{|I>C^(,,Q__/1 # Vtrb;ٳgs7ry1m4nn6PH$BFFIƈ4WrwaaYݡT^I˥c@0daJs U?_!r8Rg`#=` mMcˁqx\7;STa6o<&N'LEE[n%1i$|>]tO?r.֮]˹+D"|ᇪq[jw7t#F 1qDJJJXv-ƍ#;;oL `ҥqiuVLd޽8p@;T'믿LO^^p۷ %%_}vPVVƮ]7n&L`ǎ8nݪdܸq\tEFVV}z`6'OD"lݺ/.]0gΜx~ҤIҹsgr~;!33e˖y8p '|2SNeӦMٳt]wիYv-v 0iSԆ?󧫺1eH k==gf0<ϣ$ʑB'"t Z2ǎq>bXN7v4JgP6mrRv:^7LN,̘˛BT~O$ x4%z`0H4{Ν;sM71j(RRRme˖vYf O?JT9n= IDAT`L8qƱ~z|xkP(Ĉ#2d_㏙={6EEE'?aʔ)t=WbY<ӇiӦO?[oʕ+ٱcӧO'QVVm8|M:uDQQ>_yqkF9BCC)S0a-[?Nqq1K,NcǼXnX )++G%--n1cƐ 80vXOYYٓUVM~6lr iiiՑƲ,RSS&q1Y.N쪊r)iWD?1 Y6Ѩ :DN L"{mHz`:>}`-,[MѰ=AF߾|6^~+"O'f"p>x6q<|iqqEkРAc^M%Ivvp "HTMbN۶S05kz^$7D"VG555I>oXX,otfذa\zDxk\.W|@eh4nw];ci2ִek:6ZSYt8p2)Hҥ n[SbX<p:GMLja;ܴX,t, _״mbYD"qSoS@ @Cÿaw I[r%Q~e1!dq豘 .]Jl\}hpr x* d !  R)q G!t7x\`Y؁X6Fu3ߙqk.X. /8[Rc z6Xcolw Is'uJTs[I, r,l^`iSR/k*?-;2q-u͗q6]K;qBW㞦ۄuPwp2 S+ ]Vk8]R?;iS}}=uuu""""rBbG5kGj벟MR>)"FD"kgH;Ǩ>^=4EGku݀|y<#utNI#uDU%y0zj?_%^jWoJ#E"KJ惔5/"'RKEIÃE&{s7%4m5ŖaeMc;m۶illUqX,i& *a,R\#*k"'J$!'Wn$ZQc54 *EPitq{|Ѱ3`0H0 X,O( c"'\T 444\ eYV|>XLrBHdi" A\Ń2UOŪ)nkMNDڵHsZ,rXG+w_@y5eYAtj Boqb`Jmxl>H{P(Z۶'\ Zz(PSSTrBh4J(j5+ {33pдJ^";.)L ͆۠2,ig l4l>4m2p}M3$޶X  kv1p͓D'WT.E!ThllԎuԺ@ڝafAAPdlV/ bk``0XR=@"1$0%Mo`&***uVt:F"]sĩTWL,NH׷4L iÖ6x( OOOH1 @]]P("}~: 9 K3֬eggz#:4tLPD"(**K[]Z Z ZZZ Lٵ^wd,sb1 f(""""""lr,둢eAKa4a&n )}95==˲A#nIDDDDDDeNzinlhhhPn]!uABB7 b8мA6:uo U_ȗ>p8p8H\b@=;1,Y@8fzB/&q́ 16 bB-OԺvƉ#M<|Hx'S/8|y+ĠJVʓJ78n-캠@DDDDDD‚ph3 TϷm- '>f4Mii|Zwjv UVpl͍>Bk4oI@DDDDDD}ÂZ֚neqB Kla`vzY@(09V*zWZ$̓&V[X|9!B`sM{~k- ֵՒyh`C """""""mkk8l%U`4ۈzyk3ƺ7ZxZyLDDDDDDD>_@Reh@[XwF-$8Z qS)_?\DDDDDDD>XpFhzuA9!KH`|Xkk5,8PשUȗ>4Ugc """""""r|V)HIIENDB`lxi-tools-2.7/images/lxi-gui-script-in-action.png000066400000000000000000005657701447016333500220600ustar00rootroot00000000000000PNG  IHDR+ğ}iCCPicc(}=HPO["A;P,8jP! :4$).kŪ "%ޗZx>λ}^f1eq!]!> aLb>'Ix=uSxwߟգLYs'tAG.q.8a#' 6ۘ x83.+8*kޓ0VN+dTQBbkHy?Er*c?pBqŶ?.Шm7N3p:0IzEm⺥{0KHZ|x?o@;9N4*y#^xwWir cHRMz&u0`:pQ<bKGD pHYs  ~tIME4I4ǩIDATxwXW{eUR kDcbISI4i&1Ml(D"JuRvpk/vf=s̰gDDS_ƗE\~0j=5C%N$p[EDDDDDDDDDDT12Wvӆ&̒"#"""""""""/ 0$1]rU'&"""""""""*3+hb[!%9Dz i=Wev4{ZfIӗ6&DDDDDDDDDDT12W|YhZorĴmb[h""""""""""x^ֲb_rChRZgЙѬ7MDDDDDDDDDd+o&j-B"- DDDDDDDDDD$fE\HҒ2^,*'tyҖ/U }3J<64)mhBZk""""""""""zBg<6(9]<9\^"%J4 iDDDDDDDDDDVy ҶhrZIJP7E$"""""""""䰈2^WxP֗.-,MW!=*sײj^i2:/\^(LFyӳYʃRfM9KN鐔ѹ~z1MDDDDDDDDDT݊rEtt'ێbEel*mtY.!$)-.e'&"""""""""zJKD.GY5Ģ:i}3^kJ%(;I]^k"""""""""":O'5(OF?=˹h]iEOkK1tbre}5$)mR5׉QӼI"V F]Da~dEJ+QW<Ӣ2֕UoOʅP6jkk;I*ڊbΖ&"""""""""jZP(rͬn:@$ k1$JN%J%%fM1]ZY_]r͎.>KZ ϯ333L\R DDDDDDDDDDTb1$ R) >uIyxRC'3K+RZjZ:1BR_/~j]QBxrڲm۶;88 E^^ǞXZZ .] œEϋ'פ.&j.JO'LJwg++dg""""""""""zLP@.Ʀ[`\\&K??]?ZXDti;<]Cm۶]RVT """""""""EVC.ѣG'P~^E979ԫ(\VOח.%]ϯ;LJlJMo$''ǢYœК2,O7X.JJ%BTڰ(=AdHC]i2"~p;ۍ"""""*!j*R+DDDFT* P^ gPƈE IX@i:J1]<)]\Yf=^*Su=H}q^;{k,#Į <]"""""LLL`oosss7HF%!JaffBFSFS a)))1xr79鄵v Q9C]M,F&sD aqADDDDDrD"ADDdt2 vvvHQsyҔ= *eNHR?\^qqQLJWȾ!MFDDDDDLJwI$XXXDDDF%!J|ӓa㧟(=14QOxISSSjK=wDc;""""]g瘈j;R SSS[&~/4_.m X,juɆ9[8vDDDDD5gKQMebb333B"huVT*P( ɠR*Z qae˽?i˛AtvVcDDDDDDDDDDTLLL`iiYzn+JaeeU:A 4v3%{z ꝪMDDDDDDDDDDט#;;}YߧsÚ2^)mfG߱!""""""""""XZZ.Bin~riIb="!;%""""'f̘)Sh7oNAAAhѢEܹ3n*-C@,ˈȑ#+Ԇ%b1rsskLwժUXj~mZFzz:°j*DDD}B}oZ1c@& zX,F^^^%""2J(6ch޸U1c(e;>~~.P#,N'k1<eȐ! )K%K<-00k׮СC&"z999̙3x*5 O`kk[n'|#++ ׯ_ZlGcjjԩrssq=b4n 4iٳѪU+=gshӦvYfe u._t gϞ-3^ȹm{j }AjjDŽ УGxxx@.#22So߾:uY[nJBǎѣGb>\$s}XͲ*ѣrrrp-ԩS~~~zdR|}h޼9ƍR"""W^WV>*ܼ577G^^^U̚t֐tښ%)oP Rju%svvA3+\vMDD*] ADeݻ0aRb?_}Ut GŋX 3336,Y8XXXGӦM1p@l۶L,[Ժq111~:{yycǎر6f̘1ڵk =7d\:uҥKudaa֭[u֘6mT*ѴiS3W׬Yxb߾}Sׯw !=i$A8;;G̙3BVc̙&""#=q/^L-ׯ_m $^9Cib/莪 TP>ǻ\{bm>f05|s(yjښ`j7[o'k1sT{=<7B>r9)5ѩJL3fEFpN+gnba fKS>nQ`cH6^1Pi\Yx033&3όJxW |V/ W~~>4mg_:'ڏD" 8 ,6YBMgΜݻoƊ+WbӦM(((ap}밷ǜ9sбcGHR={_vvcyۋ+_033CݡRa[0x`Dff&߿ٳgk/FQPP 6`:ӣG8::Ν;Xr%t\>|=vrJHR>}k֬۷!JѾ}{̘1h4O+TNAP 11vvvxv}eQYMQQQ۶mt邼111h޼9K{KaÆ:UmT&y.o~@f÷;,On'߽g \-ac.ƜͩP @C yaj7[d䫱ғ?Ǵ\D" _:}q7Q3dhf'\lM!Ed-0q!?6IDDS4cݻwĮ]p!?}6AJ8w8ސqqΤ޽{QPP˗ jGȹ ]vEDDN>M"##C}ܸqGdd$b1VZ `޽A`ccYf^d񈉉Add$ڶmٳg(((~lڴ VVV077\.^Ǯ Ddd$Zjs"44aaaX|9:wׯ#** ݺuïQFa׮][. 1xXp!R)6n܈-Bhh(v܉ӧOk?5`h 1c ;;Ճ;m}ʞWn:G7o=шB֭BVʕ+HMMEFW_aРAP*ڵ+nݺ0kӦMCFF6o\{3I^z/uҥK,ԫWk׮ʼn'pС3,X: AF`ذaP(wĉWSNx...غu+oHDDDR~>_ |h4hРVj;2֋,Z59sڡcYcl;k(W2Bg_s4q3Ŏ+X/v3|an*BJ mӿk&;#Nb@_ p@ w):#'kgWpHRaIP5[DDdTjt^^z-1~x8qK.EBB<==@'i% 6DVb!ڤ믿7xO?a8z(_m 97ڵ+\S|ڙݻwGӦMm6|?]t9:tPxV1{lh۶- -[ !!D0zh(J̛7&L@۶m!ѹsg\pӧOF30uTcٲe>|61m۷G Xԛc޼yعs'˗ ɓu+Wk׮:G*etRRFZYfaغu+.] H-[ 4۷ѧO>7oףs:駯۷/k׮4yjGѣG.tq~~>,XiӦ#F#p9|HNN:t7nw)d>}eÌ3h0h ̞=Æ g}۶mci""2PcZĢ4P{ァwEOZ*+o)g@(n}Э[7t R|6l8|Iiқ Em9sg|"""*T*!ɴrs.r9F12S]K _ru;]x9JCR ;gݟs<""B,_Ǎ7CA133GҥKt6n܈-[M6D>4 FNBff&bccq mڠKY"H{sYֹr˧eee(ڦMt^´4 >zBnзo_X/nݺUELůYT e27(1EєH/z!vZL4 ŕ>G^7ϑK[עE }6,XD޽[dgg#-- Zѣ_<5q5\v 7~'h"4TQDDVjLr:::bٲe_󞞞/1oSePtoe8~6UlZ/c2gM4gJeΌ+0m\4Ҡh;v`ԨQXt)͛711IB}嗈3EӦM\x"ڵk AxxNMLL gϞXn_RQЪU+|P(mחP8x Z9uSEeZ=+WhBi4|'ؼy3&Lm翠jLn߾}(?F}_ԩ6oެgCy`ffL6m< KyQT*,JgiPxOOO|>}zmeb\5bҔu *}g# c_G59'ְ1M}}WiJ4wחq=NzR,ܕĬG迧j@LL \]] sssCbb"ׯׯG)-Z`ݺuHKKCtt4LMMѬY3Щ" ͚5Î;,4nG18_ս{wx{{#::3f@nݠh%|||н{wAm 97NBll,Zhkڵk _jaaa8s :wkȑ#FVVki۶--Z'N ??Æ Z֛ Kxܽ{?>} 336lPn׮-ZӧOcF9E BЖ⥗^Bvv67 :w<J 6?z /Ƙ1c7|UUMbʕ@\\LLLШQ#t… x!5k+Whܸ1-[fywrrªUΝ;CRaHbܹx{Ԅ Ĵ/ݻ hgGϛ7Vymb&ºHV>NglmX1 8K WW|l 0n>RbL* fnHg/V[8۳ _״lAh5j<==ѯ_?ͬ:t???5jk˒5k )) 5B p],^֭eee!88X[/~~~֮| իRGرcP*pwwNJ+E[ȹQ(x7paԫWF)mwkkkkhذm/RģG0`#33.jӧOԩS8q"233WQF(:$$QQQo]j9>H$ٳG`:u*  |teQE:r6o DCƍ!u̚5K邃W^j'-- RRR#** ˗/֭[~oΟ?N DS;\"((37l؀g]~aƌ:%;0}tׯRmWYœբSϋ&J?/j׷o߳ELG G%) kv^{c>Uw!<<\/"R5¼yЧOcօ J̆ǿk׮A$!00Cn/"ѡCcUP`` ~HR8qk׮ŭ[ JѡCL6 Gpp0 FI0i$_ׯ ~DFF㚢iM+ق㝝qС Tž?W{h??GuEϟRT1V 2D/III?DDTI?#^}Ugjгaӧč䂂]NIIٮhp!cw*ڵk3g.]ݻZ={6ҤU,-J: O@=<1g2cliΘ6̘&"""ѣ<==P(p]8p۷o1u cΘ655ᅬN:-T*qY,[F\G1MDDdss *MvvبČ⳦Θ&""""y߳t P(駟DDDT aeeUvrssk܍&"""""jVސtAVWxtEfJW&j( XZZ ;]PP}:|||f=bSyk/2ST fDZB8Nf4u)afaK˽Ƭ@1+z7QA$B޳e l\_"' u /qNcj&14T 3vWJ&#xIwDBbj#[hRoclm銐gbloȖ9x-G`HFB%1Bx5?޵">:6.gBDDDDDDDDTtPPa<9Hf&""""""""'jebcǎ–-[R zm3ub_"&1)<]-ѭsBTq;5 K@bc~*b#N 1 "@nV3g񽎈.1l߾VFD>]NX$61[6P)e UuBh4eHYIXE{v{N:K4Qy:"""""""z~Ԫt׮]ѤIlݺj /y镎JrY.$eO`fiM+zc}he8;rMLKݖr.:[ #%ʠǮR{bcahkSEOT눈ClTݻE8~8LMM gggX[[ks#V.:Z߀<MAʣ8y6z͟YҒǯ,!15Hlvԯhf ڿ{hzFɟ r#kSlѢhHmSFDDDDDDDDT{&E--=L<~^.((lRr )))r:,--K Ñ#Gϊ}`jf[5 NerGm|q+ ,#mCKK;ϖ=v5z7QQ$B h2,m]q_OIOtm)Ғ"p kSFDDDDDDDDdTNNNzc\\\p Tž?W{h=QlyILQ!c'kM)""""""""""&"""""""""j4U+&Z11MDDDDDDDDDDՊi4n5o-O]Wct*is01؇fc*ê; 矩1EDDDDDDD<5VZ!883f30vXxyy[5G@R荝y$;NtLuq/7p1{N W*)=;+NusU{U2协!|y\<wZy'1vJիW h޼9F7"%%3:@$ H94#/V*:i w Ǹo[+JgV:o k^tj;."""""""Z~]7MÃixV÷`f%_w4rOz@.{HKcqpn:nMÛf!!V#r3p*Y"lF#2RNEcHG[6f#ǒ+! 2t4ѭ '3^Z!1ݠ󥇣[xa)tDz=\9͐ h kSa=w Р@ yTJl]aeS3kLN *nh]ȵ!|tGqhժD"qUEĕke_禡ژs=3?r~M qpiS3+y_"5>)`aU;kqkW?.C<}{ Dc\ZCQ,oFܽX8cðwnҶ#$Fȱrc艱!3% ~cA^vN[P]<V)[g]Zeϖ 1qp 7l\ㅥW}e""""""""j͌iS&NHܹi8M$> xp7QjlPSÛf!?p{Ф H-Tj m{HytWj{E3ZKTMZĦoT*ƭ~kd܇,/'w=N?D^oa ?Zj{ g2-SSK}"$ ]99vCWy{8e. #9{@~nZPuX5ԄpT'<u5@2%WwYe""""""""jUb:##'>}`HOOF3ub_ƖH> I\=["-6A.HM a֕ݘg@G_Bz=:sKGh4jUJBۇ1p/8w""t' ل[!=CTNB]HWro&^ۅw}wqq(3>tʟh?֨Ӈ Jqnu\?F9D# 9_eH-EzS%b3x kųe]<qtډ ۣSFJEcz\_|#""""""V%U*RSS>ĉѶm[:tHpB6"Arv $u-q:Bjf]nV_La)ۺ<&*v_Ƣw;4C>F^]tbנ#7?tT PxIɧnPg3Pf)3 }joylmW6.:%([3$ƅ 1+{5 wLͬ`SjV\.9vvuK̘=Z@$Ĕu\_|#""""""V%&`jjjk Q^阚#!h-|** iIwlK_G#Rs4 >U#ZA|TB(V³QWX׃[h{6?P~[&:ck?.8`Y/$(Lgn٫E]c;KGV'ږG@5(os3r-Fægq>1BݐD_8;PrѮ:z7p:]ܴRUG5V)Ѩ\9O{t0)?NDzBQÿDqk0l ۍGQ2|=jŌiF\;* ػw/ݻW<\ -M$#h!OL(؅NUt3-`[>^wߐde4ܾL6 ]악3M^ШYw.y,G(Kǝ+q~6Ĕw솞/Wօ竔в,8݆?},1aסk^!é]CwѺLܿ WtfGxDZbbb#V_z"fŞE--=L<~^.((lRRW! 0Yq2iK2*C!Kʂ˸rG!"""""""qrr₳g,UCSQbEϙffmlcw#NL׊RTLf])n؇M5Lv4h,m]pfϧ֗&"""""""Tm~^]͸}qADDDDDDDDDlQ4U+&ZӍ7ƠA]v;DDDDDDDDDDJ1mkkΝ;#%%]!"""""""""jUbZ,cРA8u"""""""""ZV%{+DDDDDDDDDDVILׯ_M4Ǎ"""""""""ZV!*V3ub_"&(c0"""""""҈{΢[W,*\0yUyWIIIz;P7! /J]'NWXnenK'rvC(ya cØRbfrrr₳g,UCSQbEkGbZ"Vg]߾}RpQddd@VWu"""""""""狱ӵRDZZZu'"""""""""gjZ1c4۷o7vj%Θ&"""""""""j4U+&Z11MDDDDDDDDDDՊi""""""""""VLLQ%((۷Y_~]#"""""""""UjMbҰo>Z6vjZV*HNN6v7jZvttĴiӠVӧO#55""""""""""Ujp!8r,--1vXXYYkDDDDDDDDDDJIL߿wAbb""##sN]#"""""""""UjMbiʂBDDDDDDDDDTĴ9lmmc*DTT233aiimBVƍQRk"]v9d2q!deekDDDDDDDDDDJILݻ] """"""""""DDDDDDDDDDdLLQbbDDDDDDDDDDT&"""""""""j%1vc+s\;+mg.=wjZknb^H|p݁H$F1Ѩp[:8,cwj^m\ RJLspss$%%a׮]Z Ǯ@%?-`jgf4vW K0kE2@#7#Q#JP>ٽ5Ϭ5i Sp+dsS7)QP)e37{e::Yi3|GKmz_)ס':YWVwjPf\Cէ?w(O'Vi-<|hWkJyԩSGF~~>݋w1vʕ8a\xlZ w/F=?̭ݭ,/7@VZppENf<B ]&&hyr=|;c 7:WĽRTN]?X~%[Dcػn m"|0o86x7냾/~!iy/$ŅbMwnhP;Be%]pfϧh8 _Mȥ8 g|M+z7 kgv>ju(1@~N _9_BbRUѳPkfLwػwvݣGݭrr$? +ucڋh_?`"1øנ#: #)[ub>q*x÷ .YI YI J'~ĥ#3gvvZ'Njn rSTTl&b^v2RDʣxqS@npnӗDk5fzY8۸qAT)zF@)qAFJ4B~۞\b ڏF•?¿ S&?mR} GO%AV#! :Aoqvyt(1 0d Z=k'ۈ9Hw ~_QF}.*EG.Aru]v]҃PF;ѴX\>-{ᗷ}w14Z5q1}I4|!-1Ъ4;_lfТ8ǂJR -. 5!vue"YCF-quGaLm9f !:} VHK|!KHP{@``m_ywxM'F+[t~} 5AZb[7 g!Q&&RtZ3ҧ~TQUO@ ?X꟏qwU/"""""jMb:t(ի\~aaao*y'a"n^݆ l;pf(Kw>0gd?~^$6Ad&E8-DE_ґoI&=qd\8.n'Cdn%t9nG!ptEJ)Cɟub[&">&,?+g;(#BƹFqd< A#0`jdD#!mѬ80ɑUymD>:nMиH_ڢzpvo!.틛w;;7F$&D"h׹oГhj%b.ͻATB[x%f(K{ ]g. \cEʻVUsZ=uػUG>tb,H-0=P N{g;70xG;M[o 35]}[G/KSFU}i3"n.7l1WέhW"1-aaa֭[ҥK8<<<<ЫW/[G;cԮPc˿&o@!,r8 $<:nMe"ܿ&)Lᚕ'=keAI#r̰\9wzDbYJoGjG^G學 rh91WOȰO:5U}1BeFkwO"#9nIܗPSsCGQ C@>Uzmh4=3Zw^"1]DNP 7|N¯ B,6Esrw4#%F ?afad4i= ,G /; nMS"NѪt%F 7+pdl o|vCsu;r3*z_UA9-|D>.!>Uy/}:2S5jjѵ1zo fiHHHHŋɨ_> JL1]-.e,b#DvCEuO'ânub:)>sK6w+bY#! j*e,C"h6.=9RH$>ΰ.CЅ:ۊ'Ӌ߿T&eUAQ#DU#Sܼκp E LnV"RckO anL%J%/QB¿/kfF ZJݮ|\/ZϯyIhzTK4xv2u>–ohkQP=$K ;=JE>&R1^DĈC=)M)8v{Nhv,:|~?S5Vk*9_9ec~*b#N 1 "xVgdF[^8ea k'$?ݞyiPB<pw:e:KIm0tʟ]"""""}jEbZRA.#-MLxzVNVFD>]NX!ʫ1]Dlb mRPAP|i5̭qr!#>4j%N٨M'ٗDg c4GEXENƓQv}UJÎKyQ<{,/dH~AA^&m{ڏj;P]`oo999SĻGi3}T>=6Ѽm"ow4r2 7vNWM!?_{sdDr!1-94/; 9j],`ԢJªt@R^"9,ƹ1 ?ٽ2'dYN҉uURJVgqmSO')n7`6rpOPn: tKhY,KPϧCYJ#56.AAfj,6Uy:@͂ҒgT]טPBΗs*J%Gc8 l-PAG$]l˩G_,+B~NNj3s[XZ;t\BTϝT]Nއgk^3 *l&1}uUVppp@[mKpvo(^7`(:OƾuS&o/,{s32դD"1&:Ǘ ea#K#wp%b.»Y_xE'zhy2GFpvoVݧ!hhUxkߤWNuШ0oʉUKkgHL ~}Ѯ8lY'߉f< ""B{.] ++ ǏGxxV&{w;.'3.]o=Iq x5A{B.?P)~e;PÏ\sKąNc[{`jf[jK] <mzC!Cʣ=a>sЦɌGøp` rt1d|N1z]W^z7ap;B77. - 2Sq`tG_Ծoae~F#G TJA1#mC/SX+=5!vw: êRF'~DV#uFǎG1b6 B|%]7٠~R3k yukpd\ICBsa|'Ů/"X-z!T[и.LLJ ґo1v-,? ,3Ďpܺ* PטZg/| =.}%$FYA$H=k^FzғB~(`t^ fHOs\qK!?/ KSFUh bSq^>]j6bρYԢb늖EŖ&J?/jt6)IŔg{4&S-] %Z5]Tgqrr₳g,UCSQbEkόiĶN}x4 B̝cP)hkdys̠LLE&:ZWtn)$:CDDDDDDDDKy2.!6Q4U+&Z՚Ξ=QQQصkGDDDDDDDDDTkԚ tR)FcwV5dVZA.ݻQRkkL֭[P* QR+ppp@XXBDDDDDDDDDTt`` &Z11MDDDDDDDDDDՊi""""""""""VLLQDD0y9Ƕ3v5iqư@NNpecwLvuyǨ߬7f6JcZM<g~gԈv|0jNcwZ Bͱw^ }EAAn޼i`nqB887FDDDDDDDDDT)&1]n]"&&p-k521ݮlXX 7 0L7H$B޳e l\_"6mHi wиH&;g|jP 4k7m{φ3":\9=46,_Hl0%^cVט460>B ,PzG\:?bʢ9agK9+:Ǯ_ Γ4hn#>[&"1ckckz(@ܽk:׆}=h Clqw4zXXk?^k~ lй%""""""""5鸸8pww ߿o쮕A}P.`t0G4n9&FFJ4b.i<}n?Xq3xvs0?'8yǗm8e.E}_* 'H(Td=GdX9@JpmGդ'l#c܍{ #h__@]ﶥ&o:6.g2>Bcʓ{!X'1~Ǥ4sDlTs͛x1k,9GAttV*[G/dǕӲB6!#9!#1 Zv{C'.35ag@QݓHw;b:~y+Rc};iƿA dНrG"+50 A(^ۅ.Ssp_ $fpG "SsC$^BGQtW19@)GCɌGR5\8UZƹ?ݴnKl{""""""""j͌MCZZѫW/ **Jp;{Da;hn7/.):\<ue, an 8eBtP'N!>wv@fjtE .(Y`7H$ZW68y&[v}BlbێX@wWʣ[ɲ#ߠ~>NP(2HͅsEANMܬ$=};ýA'vA.LNkPrDb 4<':k"n__q """""""W+JybXhJ]_t%>J*$Fݬoe܇G:gHh"/; 9jܸܽksPW)%Q^;U9>u6X,)Nsd<o_Qո;,zgx6musUR䈽s }_5.ˀF,am_rY.$efA.l""""""""Q+j111hٲ%4h{{{3pJ0j.4gk"6ک_Ѵ Ѿ;pj]&yU/Ѣd3Oϝ;!gnв%KK ~vԬYBNU#.a"ӿGϡEd<8YAPYm}i\UG`Pn3ػEѨ[{.ptkDh}:- 1s#V.%Թ u]};Ǒa'ȸjM) ((z9rrr/kI_+wY#35~qa=,m]4h,m]#>)Z(yhMt0 yRD<۾Ca˿Ipn%;=v^]xSs vr|Ï\s :CUX%Axvţ sUd=Nz/iIسe(޻/ntøY!+B-H~fГ^sykLͬpt\\?F'h| nlq!"""""""gOspغeQ墇㯒ϋMJcQLR+[R# ÀΓ4fP*d"""""""玓={6@&ebe[.z^{fLOjf [G/37ϯgR94=7O>~}u!""""""" b)"""""""""Zإ<""""""""""]&"""""""""j4c8u\]]2ճheߪĶ+} }D:G㫀hݺ58ssscw PkӧNz &LEՠH8O7gڵ %}ֵ_8&i_}/#}D:mm6Xr%na 8;w׉ =8уOбNGYHCqC7${FLlOo ~h<.7}߬yX"a8z8xfǥo_EЧuˠn yan>>k׮ũSp)^ZL1/.^-[C,wh8ÓuC[HGwppGX)>S?4mXR >,{ʕ+$""""""jMbo߾ľ}~z`Ĉ7vרDϞ=} ), _KwS/MEБ K:͝6uCmH8| S.N AkBUٟfͰnS1d:7 [BI|CL? o_}mX^k|;l݈^{!4#:n9:.!vcPj8+CWf 6/]yܿ?ǜ9sPPP~ >>>ژ.]`ѢE[noWT!Iչ.=3x6~>Vf v> X7KاmWCl߾ƍY""""""Q+b>>>r ␑3g ;;͛7_|~ }?ÇW^)7qD Çd .ď?nƍx6F.Z#_@x4s}< :c@$4=u\-7.EKw=ԝ 9F$pyc  ZFet:$|vJoATTT/";- OWr|ŦSN~}|rabڸgGcY2I:)1Tk*]\H)P!\H5Qktpq$?¦M̍D6gZi8r_7nbNd)U~\B@";o[};-;7Om3`7c O8{,.]>R]>IN0.]իO?5jTTؼX̺^.tr酃 (kB|5U/GXfbb~Oe!]}*$Nι$"""""$E"T*zRip=;"44={ĬY믣gϞ:tܹsbȐ!x뭷*,ϰaZOXXwX@̬ӿ3fhcm|9vBߛQaٲN[֝h o יsaվA1uƿOF+pw<\̀SYPoz;@jSkׯ_/sR)H,(,,EAK,DdZ^}2_g+"R*xS7I9 68$^~E'T)tpVT'؛נ}uhsJ/C[yA)>S1v#d*ζʞwCtu;wl3zUm<ȜHsldi>7sLDEEDao 55 4ҘZ5}^^͋E7nP%cbn.Ό6Cnp"1 DkAѣG{. j'66r۶Ofb?~'Oݻqܼy@JJxBNNN۟^ c Ҙy7@ږ?u߼:tPegAp3LC QoB8uޓ{ ! ˫̼2ڬ­ҨSfrs/ 852O/⛈o&jc=bbxk}tŠ+H% IA\~UU>>dI˹W1p0u`k>ӦMCN0ydHTx 77(((uUSݮg^ǃסK/H>¤0DV})ZefYݵK{?hglʺN1xU>ƆRvgfΜ#GbԩxvB@vv6aϥKY,I._2d_Y5faaWWWXXTU-W sssaꫯZ?,,LS0&&&hٲ%nܸQ1Uy\B߃m oKoOد=>4yCdN$\>ٚQF!KDDDDDDWknnn@ݺuѰaClҒ屷Ǽy#F{زev{߾}1n8 FF{Oܸq͚5C  [[[;wɄ~ؽhA mp~umLa8zf> ; lU?./QgdΘ`ίNCygP߅m~q Rf}044n_F>P+p4(h @C zCSOhsυ\Keu+{\Beab'b}74Ԑ!Cp 2RT׵/bRj·6y޼y=z4-[ 4iM4ƍ^{ 5G} 2Գ@9 $-DSfb3'߃aaXr6y]km] 8Hp}*$puuũSQթ5}gϞ/bժU8rv{vv6&L7|;Cs3#GCXv-rrrgolqo`} b+kCŠ/1C삺.hľ3W.VyR7:?.S߄P!?&R֭6E}1<>_!63ǃF_9rCϞ=~}|'{.ZbH!s(5JL񙂆V DZcQ>)' Xc}:^s?;3}gb"-IlXl. ;_kR u80f]b~s/9g =.96Rkk@|||*˶m[|Q@xv8:K/hn{쁕 sŚ5 VXmgN>ŋcʔ)x7Yf|2b\J Ƣt}bauhεwpqL𚀍1,Lk8Mc qg^S!1:t(._O`""""""D̊= gQ+Z[.z<*y]PP٤$>K_|,--1{lcwѣGcԨQ0aBu?/>?U]{n̙3sIo Ξ=  WbMG2-==3ٱclmm䪽)wI$no>?Uw1)MDDDDDab1ZݠRDN*sm>cw Ĵ>Ccw'6vvabFdZZF2UNpHGt|𕱻C)-|Ox>nybjDb+ٳgo߾cx뭷 ///[훠LKT;ͯF)x޸9s`׮]HLL,:0G-Wh)S? ߴfF231G>•W?47Ěvkii>;p"3גKcD$ѮK~:kelVI{Ky 5!\sk>}D:ƣN!}BX\Dx\{Zr "##1yr,$&O$% qyddd퍾}͛شi0l0ߪ ľ3g/OOO۷opqqh=Oo}avUU-bRIgu޼&e}]o~nǺᣰ/ݎuþ}:qD|^{ahGݧryodzEg(Q>R\׼شx3fppaω>؟S 1n8U*O$pqCPӪU+!$$)))8rd2Zh!x?WwkOh~5e%✂'HXuC'x7o25I3N>JoϿp)_Wn7Ӿ^WhD{FLL *< w"<;[lwEW7 œsp $ KBH}70ٻDW_aK-qp9$ K得1,EdɈnpI$Kĭڡc^o8wpngƱcx{~Emo-h8 ˿;v6?!rP$ ^Bb#a^o#4,ɠz|A<2Ȏ@Xf:qɲd̺gFIi y 4;q  Go-c?܉G='`gv!-E{O/O?>qa+%&N!!!8|0,Y}…umܸomu/·; Xv5LV4iÉ1UyK؇|^شK=pa̺/ÿ,<+t|N%vZ""""""? >.j$$$͠vlD Q۬y7Du~FXߜ Uv6mz;f'reݩ+ p9V;TYv@ihv9?Jծ];\~}SXPq8d)E*@a9 M۟NۮF[ ֱmmulsK:kX;aF`jYXæbvl䋓|>r It Ώü&0`cʓ*OŞ=~K؇dYrC/]@O瞂_3kB ^k՘lG"~b _ٽ;:1b n 5wwF~ݶ}o'tٳ'f͚_={>9:tܹsbȐ!x뭷*/}x,vvp2sV ?(MYRf.X$"E/ǁW\po߾!"""""")$@u033C^^4i^za˃a% ba /,{widܣOss61|yM?> 0|,[l{?/ȟubnbo||!հq}u6V]{\9O>qۑP``Mt ŮG0g 1(F?mp3wCBA\]˥Ɲgp+" DɄK؇nǺn]oȵZH@]㇠˃"!7yR/oF[~C}DqIDAT[BClVI[n7n;}}AAN>|$%%l3ۥ7>1<-=ϣ7~o]5hsϘp:} B3B!S  "Q@8rH>',|m{MÈ3#J=&0XtYXSgLH>hg ʈxEY_qy]<(8ECx/\͸Z-}7Ernj뎝aծ^ 7Ex (S_w\SOB l(2DāUkW۪{Z;m{kZEDEA&aoH$%az<|z}9>Xw}?!:_H$d6= ^zP{{{dgkd{b]FPUMY] c֦T+qK-J'%Gm7RP*pQvA H " `srU inJLdVX] 7o~f ܻ6@RY1PV[uH.&.Xw)MC2?f5 aaa)=nt-1330$%ʚj=0c DK P/~]`~}ݛE]SS|駘7owoBvvvvvv022j<7*6Ѡk/1$8;5;`%풋CDDDDDD0i@T T HX T~+WгgOƍ>bbb: kC VO,)k*9&Ad-P,;Ϝ9c[6q'D_Ӿxe / }^v\!,/ 5ȭ (P|,*Up3s7]׶{ο/e%}I'q$*JJ|aXw$&}YXazaAc NZ(v+񅭡m"uve6;^ ,/Uwc4 o o6 ~oo oX/#K߼?~W㳤4>Z>tGHH~w >M1"(l.'{:ɧT*Pq^A}NO;`8N00ҿ=W{~ Hꫯ ®]R8q"Ν WWWf͂Rĭ[T1ׯ_'@7{3fѣ1cFu5~{Lnv1Xᶢ͹;::gϞmS âK,a``Uؾ}; 55ǰa qju3'!45ǡP {(:rP>~fǫT&#~ůo?bCds ~N-ĉxW1vX9rDchbG 7`khԲT, eU1 7p,X1ٽu`Mux-ŗ_{Ρ9v+@h |xClNܬ9yqdcWƮ&kikښLqziԖp015i+`"2ꫫM7S{LKn/aiߥ?Z|j}r_\_@VeLJ7?KhEK7 7@URR>{?'?߂UɷqZ_-}hwBxx8LLLO? }N8q/̟?/_~j6l[СCovLMMYYYv.:4S؁П^juqN_VV^k=,GAue*G!*{? FFˏH׺DaZ$h6p0x`<عs'd2DcFSqzk(Ⱦ;`*L*LUPQ#"`]1YM񌪭Qu7~nj{~cQU^;uDDDDDDDKe2n6fj<,[ ...eamࣸpc$\(Ⱥy!WBbを; ߎSR>HUŎliG|q>S cS¥DOq 0tJ\ 3["G<1MR;c[ƁO8>#!p8"~V=|\oRirHOfVe߄c8wbČ f$ H=?~K9$gM.YN0x십CvT NLeό8´8ua]0r]Ҭr9"&T63 `!F?>NZHXٺb[PW[3_VZh1'vѝ`s^ [H9A58k2S">0SN Z8i """"""p退899a׮]꽃;}ߐ'08u.$T S=F\3שc% u- ߫޾[G_@fJbCs@S:UPB(UWW܌V)! ^AziG!>hӒ(gyx| Ң,şҪ_0vG1)q4 E)jwtNۓ%_' A(ԃX9lՖF(+AEiݞ M^,KWkWWRcI|PTڤ?&-QQvP^|ê92/`[ ~epc2N琈Hݮ0///ݻEEEZ?.r'RoSKwZjd$FFiD=W 4^m Զ)J-?3UU%<E~P"@nz4jk``ݸj*K۴mYq.8Q+@P6y@ת$EJ%b#Ga!x|?;"ƅoV}azl=M]% MpZ'C; B77-4^9mnt51:LqWXdy뿣\?U[++VKy5 ݻ[rrUl$FkJ% a`h(/EiQ܃4z{]mu{PxoR(̿wpa~2l{GCP +"܃`d*E/>=zV[C]]5o?c`hl >U0{G*H9F q~h/F_sMM~୥sMC@G \ /n:LTy,FyIZ>&02Vfm{*,l\`mYk3=λ%̭QZ=)݃`a kg\?#t´@ T*T*H$X,T**&(( *T7k_0x p36^Dr콢Ņ{" Vvn:x/h)mҟ,7.'T ;~[bdl ^\;jճoi_O|vN~-3<!#!LUh9AٴW[> ߑK`fxJY7T1W` @e04h=?@vE8{Nm/_6)e#%F=ouwRCNƕ&skrN5uT*P'1cԣ4Y^"V xMcg} E]ZL{]?ڌn^هT83xMj܇s^gM u"C-!u[ra{ By(zOãBQd-IRW!+%R0%""""""Ky $$Dն+r9of̘ޘ8qBCh"%.~ P,҉r5<LYrg"M;F}5 qZX^jIMiTWpAvހ- RqeJ|@J\R'): )Z5,[L{zz&7Oho];јTU#.u5Mcy&8{5Z3`*"wz5Uu /7ٯ9&][q%o@]M?faS[Tm/_V۪{>3´[8xVh2Eyx)B^=j[J]3Dl_u z=XY(.HSS*{^!8w9WDDDDDDD#q@]ԂFڂF톇g ṹ-\~~~1{S }*uAO{ϡψEyJSB?tɵ:M1P@mg׊FeGC D݉VN:a5b#vtuoPW[!^BUy!oujDDDDDDDDb&/.'"%.G?u:J(ЃgזV"' }x(u.ADDDDDDDDDz)'S0ir=0W^8{,t_J(ȃǺNr6qFTw1[GXAѣ044i""""""""isssL:߰rJL8IBBB|r,_O<tzƭZ @NNSn|ǟ"ErA`%Nn16iZR|CUpoxܜzU}-QHΎ=11;^Yd?vߍH;hhmCː˱os8_p7Jn`u$,Z׸6]0-PQQ6SWW+W8p"ߺTWTv}c1vXݻWCfM>5ZxܣZ1n>;wb\8DFǀ״ob=o{Q0<P? %7w^ FzFȯLJ",ڞK,XOػw/Ν mu]0-x4s5Ν;sBCC!ЫW/%] x޼IN>ŀ Ca>ajM[w>8m$M.]և'U-1}t!%%ɾ?{g0?~ߚ-XDdd$?>@mu駟m۹s'VXfodY #lFmϳH@@Up}u>kVDzзPqle`U텽/pnMGr>.s%χHixDMJjqs~$'^Kn/A(ZQW#$^>]sAlq,VEBqM1v~]Kն[Xc&\iC^-ZcFlFJϘbW.ז?XDzDdv۔ٳgallQFuؼu%"]' @ j cH}(&H{TɀĽ5j,2^_x/\ UɷPt D;[B=>0Cڵk{k׮'mۆ4:u 0l0^k֬իWamm[~u>PnFqMj_fE&1,j^~*k!C^HY$/ZKKQTS_,/ލM7M q*ލ{9&M@Fy" "+W`\,Z$M%(`ax}p5s-RTዤ/C3$OKFWW.v!C5y]EE Ҿ'QQ(d>8~x QWѭ X`*++/ ++KvaP&; ׯHf<'gZ~*ri(YŪ´6q w={qqq8~8Ν*L;::ΝCEErssqƍN>;>Pz9MᄑokANNj5żyϳ؝?ps>j}w%oc0lgy=wꫫ#N}k;c7 < [nm *L__ƋW^DJY z+#8lByUyk6n@ȭʅG_c.&.8wq"` O _ gδxw*ع}-]慈+VB|044D1aݻr\;+;kQ(<5yn4Auzׄ$vJLFj\bݟޤ=dȽ;^°h"opbccqQw̉h|11 Ŭ^Rv't>>{]+_oci`n+$ zKpY~`o[-bbTɩA~97:uXNrpa >:Bz` !@$]qu;& p6`  Bbi"K#>^e]%l ھ|UU:tn.ƴPPPZcR@ے\珴UKQ h8D6@(-%-VK&E"?yW~~>ۘ7okkkU1TYQM /pqc 04@X!_bt4^_ '`ԩQ)Q4^pa,T{8l۝(@>ZQ"HR>'GfMXX#*A~U> )*Zk[Z񺲮R2RAkI$d"""""""[L @___(kQr7GŒ1I,a:4@Uv1tW_sRqqqpss}ݛE]SS|駘7owKJJ`bbj B5{<###ȨUݘs:$~o{nQ۟\  mH)k#ee03|4^!Aoq.2+2QX]ggULqM1rr5nU.*$ j4cxX[ FzM%% Df5Lu'xczư7qrRx7ٞ^(đ#x%"3=x^^Gy~.QJJDŐJV/0c ={#&Mkkk$$$h|ɴGap =<O> Rc.mS3'LoϪ'q `>a U?s ||| [" ggg#((vR8q"Ν WWWf͂Rĭ[T1ׯ_'@7{3fѣ1cF#9GP*AÕ+H,MTۿ-y8NOi_2YMj(v+񅭡mEDL1 Rb=1~RP PxK}KoMފ>)=|eZGa"r_737x[xciߥXVsՐ0l i=aW.*k]wMb]b&>OVXc 0ouɱ4MhQ[C~==GP>.MgϢJQ03%-f7}LGs)gGGGٳmꇈkL $$Dն+r9oRjuuuՊ-+)tR|  PԥO*^ATQQ[OLG})o!{zJΜNCQVA' 4\'NW_رcqȑ&y?gĉr)) /@__)))x嗑vaÆoEii):fa֨q 17ٿ#ml m5EjY*]^Mb&m84LD&X}u5IF-ob6 |V_]|i1ܘ| 콽͉a'![Q%|%>ߢ/5֠ű2KF 5(O?49s/]y WcM5H,MēO"d23t^fzs:ݾn«^|ؙ^~LqfBt5uŌ3Xj! 7c3g˗>!"""""""č^wQ mkh zwEw_7<[涘{ 噐wvٳ1k,̟?_m +WmٲfffXpaH$!cF\ZCYtNxfbZO;?ac ?agN|=ac`֖ju S)L pBs511oUV!::旈=شckk@E6zV}hP6z4Ѩk1M}`nnuӵD$aРAxu=%ƽhSPKn/rO:6cp=߶e<lO  ک} Na 3Q\S磞ljZƽۦ4888O>aQH ,Lw _ݺ5Smm- = >Z\)Gy]SkE :[ 65/26zu\/\ZQ<""""""""""^X&"""""""""N4u.1b HƻcڴiHIIt>Q%D@DD P.F(Ld2!>>555PiӦٳuDDDDDDDDDDR(Lk*00rnu*DDDDDDDDDDV)L u*DDDDDDDDDDZ(LaҤI8vtQ&uA*mBa}M_Q\\4nQw}mĉɓ'QZZ.QHX T:d2B&DDDDDDDDDDԱDa!!!%\]]!˱}v]GDDDDDDDDDDttUU6mڤ{ݫ봉% """""""""i""""""""""T,LQba: DDDDDDDDDDԩDN^ވ m8U]DDDDDDDDD]@(LcĈD"All,BCCbﯶ[nuML{+=~G>Dđ:Myo`_t u!]0-PQQ7N&êBu:w-\< w8[m˧sVmoat{၊jrң0qfY9B}~A CLvzW >#</Q˹=5婭06AYq.\OD]]-N,~:"m@L7M;c[ƁO<Ő+!qAIĄoGԩAǍYS,%0أohu5F&XN|,PmwOmŶu^(/}?sDDDDDDDDԹDaZSVVVXt) rrrp9:N!20i+!ˎՕ%+|\Gbv8$^!'vBfJ$cS_0?iX1'vѝ`s^ [H9Q>yH鞽  1qrjdF܂*DBynqLc0wGVj$l5U缥4A* t Q+LY&"""""""f u@gFhh(ߏ'NO<LLLtZאrd\<E JgPC:"nE¼$Dn@Nz~N-=iEeHz#kOfy=`e玩 "}1l콐6 n! Dm Xظ7BQZWqǭ:-͏1-~;8s[8ߵ*o""""""""ɪ999ŋH4yz2l}i'luu͈TWRcHl jro_o yIj¼$rq>);# 3}LEHTUC %r2`l*#gș.z[|_Ek =4rңpeʊs}~4iIzi3<\< CiQOzk6?@qq1$V܉TVŴ%M zTܤf ISOXB=?]@哟pw (g 7=5U00W 4ZޢynIYq.8Q+@5=̏&1-R*= I\Ѧy """"""",g077GiiV,Cz4w׬&1b3U[ ~,Q aGm)r< ۊa R>JY)#S)OG{j\e=汮7O104}~M{Ki TWAoxߜc#~AKae玸 ?t|_O(L HRHRD"bHRXYYbN~gϞ۷/}Q( \~]Zv:ª /h $:m7x? /' ;AM~ [!uװ5}U> a,FyI.z{NP/ ~0t*XٹA (|G.uOOI=i( dPhz[Mc ;"='¶/Lmˊw y7PR1K.BBBTmKKKB.cףF!P:Vu "GcKGPUYKw'Fg\mQT?,CV9^jIMiTWpA|@J\+): )T11ߢǾ)kPS]XDTUY| MoVEM{Ki D !Mprj\}LE\9DDDDDDDDu44j7<>nx mu=4婭70BYXkm'jkt=DDDDDDDD666-"<<<@:w_+= m4j7wLMan儡V#6bDDDDDDDD"M&/.'"%.G?u:DDDDDDDD<]/!Q4u*r=10Uc gϞS.fРA8z( u u BJB4]wZqqYYY y7nF1c Mzɓ'cܸq3nݺ:̾zzзCP7nݺutBCCurc,ǟ DFw%CcDyB`` q%]LDDDDDDDDظddd| Fy=Gclw;E"***fc1{lTTTqM]ޢBշ舱cb޽N{bܹm.Qd C||֭ç~mΝXbtAVבH."Gbvj16cOmƜ:u } ȃae`U텽޳uV ܇iI9&Vc؏{7ĭiVٳgallQFui%"""""""nB.3gvbbb4l8.R_;ʢ"!ŸIj1B##:Ee%^zw2`q>}W#e0 ןCU-;yΖikСv}ڵkm۶!-- NP__z5֬YWZ|(6k~k*z"evƗCDjY*.5[nX_^ᛔok;WceⷑV-:jce3 G<1f$89qܠvriP### 4.]BDDzqơZ%= z@QYP(QWb$33n V-Qt4P_,F`bUaZ\Ν;سn޸8?~sUQYYsΡq=z=&,vgƏ?6܀i=Ṿu:ii&|EF@,vYqa=i:ԲTUg 4 C[rrr%"""""""K,qEʕ+HKK;ڂ|?s7mK/U1Auzׄ$vJ.}[5>X%IӛT0roX~=BBB`ccӎg1郘"ݯ]C_aKJ;X5r^R[K}V :3u-ݢ0]WWjd2EEE055ո\珴UKQ h8D6P*[K S[-kK&E"TzGpp0^uܾ}Þ={`mmQ63&==V^aOjy*L΂/T?_"ܛ Rc.mS3'LoϪ'q `>a U?s ||| [" ggg#((vR8q"Ν WWWf͂Rĭ[T1ׯ_'@7{3fѣ1cFm0qtz}Me1rHBs |%0, }I%&bRI뉛le`f`J):9V{9::gϞcQ%~!!!%\]]!˱}v@BBGb!>>^ԕCh)zJJ@ҧQQTTo_Ahb[޸^3'!45ǡP {(:rPw{`6zI@eB<' WĉxW1vX9rI011O?2|g8qĽ\JJ0| GJJ ^~ecذaoQZZCwGs#ml m5EjY*]^1Z:GFAqM1vej6s77ڤk03Ċ++]w'sOTdcO;X16sL\|YDDDDDDDDD% nZh[C[Шл,"000<77u= 噐wvٳ1k,̟?_m+WmٲfffXpa#m&"\hWbbb~ VBtt!"""""""v`ccb-PYqCFvq4탹9lllC#!! N.ADDDDDDDDDz)'S0MDDDDDDDDDDK9F;;;H$"44T-fʕ;7%%.QD@DD5kt>Q% 2 aaa7Cuu5u>QmטA\\jkku Q- ΰDLLS!"""""""""veaNvi 8;;ڵkN[vi___#))IשuK"]'lll$A,C*2`E"xyyիP(N[iږpuu\.U===a``=$"""""""""ҡ.Q¦MZaQHǺDDDDDDDDDD[,LQba: DDDDDDDDDDԩX&"""""""""Nt7a*Mr9u!?_,]8o&ވMr$:jg(A m{g~h1b HP===FFF(--ELL ._X~.ojoS_ԢoV}T#.GT<῿k|Ӧ]&(?uU:{bl{agzr|k""""""""{DaZ$h6&00 899aĉDllFs;1ZYU^c;wJ(-BnFtsљ/"""""""Ke2n6gϞHOOGZZ ..CCX /`ԣbg#)[ͨ=>H{ Ix[՗uOO<&\q8d\QFXA=nFpyO^O+7;K >#</Qg"N{]*J pIj1S==[f?T~^7C8t59_B߇<(u ^q=;;=Ő+!qAIĄoGԩATk1? YߑK`*Gey!n:-i9G=L 砦 g"T[\hJ~Ǥ[oOt´&n߾ ///H$fffHNNujMr6`自"pCfyB0GSwQY.LYLdڷ*i%/K% Bh?SĮUL`LyK";Zç?,;RoTWhKia&n'c,´ǠH__2t59_CƯй820b0rTg@B~}ܵu' ghלc~} F=.~J-\&u6깯?cУ`L(KF•}Z\hJ~n\ W}cRgs^A=)_I)L?OCTBPĉHMMujMr`f z8!&[9 ݻe97@Udkp6x,@jE"nE ݀0ps8Oi}C̔ Z+n&N]E] ̭y(NU&kgqHprj,)kyl.4Dm ۽^ca EMuyR/v@E g~y E-义pQK3(uU1~!l?~o}_}}H996=槬8u g?w K4/Nk>Oǟ Sڊ"&=DDDDDDDD&u2HM+f?HeDգ;5y D#ݽY)>0i@G \ /n:LTƹTW[ vdQ&uFaF3v~ٿɏiOuUDCMWUe1Kr11]^Ң,8=輷FS8x=vg -a']簁UfcynbGޒS ;A훧PWW#)îKR)R)D"b1R) iii8p D///"))I7KMd^dFB"Z_ZT0/Nc !ǨG߁e동`l*H_ Pu6<D_Ӡ[G7%J&r24)NjOvE8{Nm/_6[jzlϡXJ]1vPը\8G, `e7"pVу{{/7G;r {zLOCT F![atuyp綵j~49"NXc;bMԊ}Nv]b)ږpuu\.GE`` ƍCCC"22/^uj(@g61ywc`7PWS}~[W|~xpسOl]HZߵ븮_cs[N{(*H װ6}f+l`΋/6ݫqob4K'7S Ol{]1ߢǾ)kPS]XDUs|UU-==rp蛧s ab+a.Å#"1~m>:m4zxl&|9DDDDDDDD;q@]ԂFڂF톇g ṹ-b Qw% n &"""""""vcccb-PYqCFvq4QWan")VcȸPU^tQaa!"w3kK+jq>\$""""""""z0M)OƏ: """"""""%uDDDDDDDDDDԽ0MDDDDDDDDDDi<r L;:5zٳgaggTZ4h =zN%֘677Lj#`ggDXbȑpqq! pYdddtz7UVQ޳gOK0`~MŋGHII p…BRR-Z>LSGDDDDDDDDDwLD"TTT ""L88|0v؁4C":#Ǝ{6ghh\?#G⭷¯aprrj{ܹs!u=}DDDDDDDDD.Qd C||wt2z*\~k[R-Vx9uuP@YU PTU@%@hh(>vvKW+(9wעPxpjr5>Z _k֩SkӠ*5IӀM+Q]]ݪ===!++ o?<nutaa!~geeeFiiinA&/74`Lg`+| wJyvj}LCHOmd2XXXj555())~9s HPPPЮ1&H Zy∈u<AYY䄌v?%gO!{z$C)TwZ7V,14i`ޯ}T$5[!Czzz8p _1!..yQi@T T HX TC=マ={o߾Wl-ɴGap =<O> R7ĖG]٘0 }Z:{G^vW{CZb@Ob!'|u|Μ9&B!<<<X xxxEsNbɒ%pss믿###ٳc8::gϞmHDDDDDDDDDK,a``Uؾ};@PHKKùsZԕCh)zJJ@ҧQ$6oVzۮC뫑7BQQg^@k(/GE|,z&1Pr$8tdoEG6ĉxW1vX9rDm ~gUw7nRSS 8w~m,^=RRRK/!==]i0sL\|njHDDDDDDDDDG@5PѶQwYtuóE```xnnk*zޛBhbgB4={6f͚CT:211oUV!::Zeشckk@E6zV}hP6z4Ѩk1Mg߾}077 t988O>aQ/iRP(_N]ADDDDDDDDDZbaK[S """""""""R#uDDDDDDDDDDԽ0MDDDDDDDDDDi""""""""""T]bi///xyy#33I?LMM!pY:}"""""""""nK1t8x jkkJ쌉'"66?#rss#@":}"""""""""nKߏ8rD"\\\T1~~~}6"##'N ޺N[?300wQ ѣG]KDDDDDDDDDԭtt`` d2)B,XllmmQ^^ccc]KDDDDDDDDDԭtt@@pA`BTWW z"]'О兽{HUUU066ƕ+W022R[:^exԨQ߿?v Ldvv6zuoB!푝ԉ.Q 7 T T SSSU̕+WгgOƍ>bbbt>Q%f̘=&&'N"446lr98B]ODDDDDDDDDԭt֭[5Ell%"""""""""ֺRDDDDDDDDDD4u*S0MDDDDDDDDDDi""""""""""T,LSZFVnc&9{$ny=N㡱( Ciӱrb=Qw$u ^^^TŘcĈD"All,BCCu} <͂EOTɐbY-}? ῿k|q} 忴[S]QQVӜV9L\?DDDDDDDDiwww… cΝdPQQ:=o001Tڪ_QUy!\4uyyyXl\\\TiL0ur> G?F•}HyIй2~%$6.():?( ,TU91nFVzwꗡ0cU_>0;6`S[alj\Z\9).vuOO<&\q8d\Q8o3̬!˾ w !&|;h#f` 6,'?@r8Ios@$>H{ Ix[8 vF(-0/Is Md 07d:\9YϽ@_ abfTDXΘéV?300:V,áo b¿AmMe1bcL+&>uU>*i%Yc,NZ;/乷s]^uVZTb%o7uŗozHznǝ͏DF!VWwϠDi/H}] M-=AWi7OEeΞ0e(g 39O4i+!ˎՕ%zN5ͧy:q5 ;CQA*F>̭Gyn] ԗ(OEvڥV ?Kp[o""""""""K!ɐTZ+1/{p'(*Hmr&󓛨DHEi*04Đ+cs;zKvI_uu͈4ͳF6Ȼs]*eZ.&V8s`- TbIMe`kK|8wEQW>uЖ saaIF0]r$"""""""΄N5 ݻU?x*$}I֔J P^Ң,8i&U0&q=A( '5 7l܇ VC =C۷Ρ0eqnu:OUe1*JfF뜴]?ɰ壶MV+!z?"¼$L]?vDa:(( >R)R)LMMU1@]$A,C*J7k_0x p36^T ~0t*XٹA IDcS)DbZv:ª /h $M02Bcaia k UNgω s)Rk3?r>bwm4,k ~V>J R1B=}z>sڙ\=|F.EBLg󃮟g9$$Ҿ2+9U(jqg uF5>gDDDDDDDDTK,̘1Cm{LL N8000@HHj%\]]!˱}v]P+3@<~K'6_./ `T#?3gl_'6Ao?D\h}*iWƟ!FuU lly&8{5Q{-݃ƫb|~}xpnx m1|]i`S[o`_3""""""""")bExxx "uj=+V4z(=hnx5 """""""""Su5١=&"""""""""N4u*ٺu駟:47w{t_B^pYiިQ!ckody~?]E6cO "mM-g:G(L{yy'e˰l2̚5 ZUaΜ9ŋصk :$&dڪUp4p~y,rQߠANxr# t=RҴ&XK炨Z~|F^QiwwwQ[[VVVZtE#G[o_!!!͛Ԩ1vXݻÏUXSQˑ^aQ% GDDpm9r"...Zh.N< .য়~BPPPgyNBXX^x}~~~/bϞ=6mZ>̙0ŋq1xyy шD"믿j?>ϟK./DBB}]`֬Y:;_R[8m.'f<)M^|1 zVmݱn712]6!0JLG3ḾWD}AS* ߨj[[՘?܌úc VEcᛐ ϰ˰}%@X1:k;7ԶM>iiiHIIsiZ~Kylی#ͩ7qk-ts~$'^Kn/A(+ S53 ǞƔMW<^Af }5rApqlz,rYiI-3c M AзP͋6nT! &涘4S<^^8 _9>^M?;^s%o!pgǾO_Ͻ /nSkopώψEX~F#3xqC;AY`&9Vn lThѤ#k!nm`0^ڐ cS)`S[}9g޹!W49йx7.c h"]' m3CCC|W¿/dff_~pttT8p *yfcĈx+Wedd˗wArr2<<};{=Emc&@ ]1skJT&è7JJPW\hgKKyd=gG Ӏpy@-gy }de#ao y|K`7`7EU6tP\vWC %vmk=7`%;9qlF;'Fڌāp<8ԏ}ax}p5s-RTዤ/4HFBe]% 23#A'*IIxG$ zjT).5rL/ D_?zxkXxE5EInoR~\_c5W$ 2 SNk{ӧ>}sνTxNθ4շ뗅JMnWWT; P(P0*O->m~b,MnZ64ĝw_C/tA|Q**AUjZ=VA6@i۶"/Pv0tu݊5 B#O/y59::ҥKU眿!,ߤ֏L$&aPU!xM5psvgԏ=< [nm *L?8M18tjY䲦OQM/( ar|Q~%ocr´!^υ<D{(v ~v*pzT*AcPUa:gm X>^ qzkIdtwoK-(+ʆ-Á/]+.HCLxXnF4Ūt5<w¶`,LB+L vB]]]cӯ_?ܾ}[UT( U[&BնE111M7Z52deeZS\\f|P*JOer"hk 'T$[#/@= ʢ/7KYSV͡63TWRYd-~O{دY5w/^o=3sXL S!b@DzX&tIm ,.Kaodu^K}ucy۪ܓe-uX_, ,mA3@} .˛^?ՊjDFz4yz5'R똖H|PT*Jߏ<7F|[bprB=%Nk٩FnF鉧Q,@p&2EYH?>$va^zJa*ș0rXM󊈈R@xyya޽(**ju(+6>D"ƍ:lڴ Bau*ԊڨAII ?̙3D9sf-! uM/'BkQ eN];1T=).@ѱC;fJK`7fAa45w2P~-*?Chf~ O/\XCY8sLվS~O] TKbkjj 5*cbb0dU[OOā4](~ w24~ߟ&#Qq 73*bKeu5ZI\dglD} P(Puf# "/(*Qv|892vsrU iPiyj}_-E.h숌]?BA q.1׊ZwT+/hcddsssï\rycZ{*G,#eB8o۷?;zzqFޝ}vj;0|VvC TyE]^Ң,80MDDDDDNOaaaׇT*T*V1-9z(n߾7zBPP|IP(HOOǰa  !j*z5j ޹s'|}}d_٣qEEEy}UA ۇT|a S ۳X@Uj FBD-DB=Vu?ٛ?E[ }`ҿ/EWתb.u" C]I1jsa>fJ/E4̙3X,nS^1n"|%5"Ga"r_737x[xciߥXV컳el)=>_? ))#@}>zGmm%&bRI뉡'h3c =z3fh'}(*HŌhXX; gGT0/Nc !ǨGQ[C[DcS)DbOYQ6Ra# fJ undl ^\;j{" Vvn:x/h)k=FDDDDDDDa1cBBBTaÆiӒJ,^n‡~{cpZ_H$>|.\@ppj߹so#88;wĀK/!==k EEn=17/Nc`@̀M}[}^giRυ(P0w}fFLn \?YLaA׳(J-G4v) <Sh{J׎_ޜfiYOO]wA'Cv5Öprר B!B`YXXWqsssZlB )) Q#RRP !/*Jҋ v 瘟)Phc[Ҷ*gvrĕ+ >8> I;8zV ؝sI/NW^9zXSO7nu/oiNW^]ʌm8>`ƙM=JS| Up/CI-JHz$Lꮫ . +ԭ0 G3&OOhQB=BY~11O?뾯3kSNNJ xWkY2y< 3Y0|M aكWjLc&>_ztѢXv85oPrzB!Bqojeb:884;;;3f [Dc+D8caݵ„:Li2( Jvj/rJ=Ğ{X7 7nl\fq&gRȊ`jөtpI.=j%Ccrc94>\ѪG23g43cb7m8IL$$եf[1Y~ೋd'dǏהlJ33Q.};z:my=ТXIL !B!#%;uꄷ7VBTj_ʊzŚ5kHOAcC(0Qp,g)i%;ٹ3ýLjC#K +W6Kn.\Z�u5u-z q U=L8;r"V=qyqZ%ZTUҕ x/= |O\_kq>;frbrɕ|,c+ܬNR*L r"!+S+Z%!fҕ:zZRRwK9SXZb0sQ7KKta^=&vM߿h[-?\gW2$GS|Sg7p@n]| >عbfnĴ{F{ :nZI#[?!8:Sfz&d2t !B!xՊ<gΝjԩvvv(Jٴi/_6vB<'m'#7Ăx>1_]JSoU{jJ|^o9gԊOإ5r.Lǝ}eprofFLn SNLX1Mٯ.}E=z,lZɗQ_ʱEʢjSt?bfnŎ_?hcz#euֹ2-ĥA sK[vك_(.ʣ]Wo&Ey\?B!BhPC,jE}eۊre7[f;%''W@Jq/<%d0#~`<O:| ;]B!B!Re777‚L@ Wz*wSmSnq1-BTMC]ٝ"U5{ v'ֻ.333ڶm˫jn !B!%IL !x$*LyK|SJ%8Ő!)`II ;wyB!B!(%i!W鹧B!B!C !B!B!$B!B!BWBTuCiء夅28g<1j,g28tnFc-HW}{$3mA:=-'|`B!B]Xc:00@HNNСC\~򾾾楆V/Xk (rt|2;pt!;aK8kFB!BUHLm)_] Z؆c fԣ4o7mPUW~cݵ;s[c/r4(nVnק3ĹTb6-7ܚUCb/s)KQ^Y\zXR/`Z]0av-޾6x.~yĘػX3ӪU>3b~w7lGg$UN @Ncyصjc֔#AYR}N!B!d21LZZQQQ} 6Ϗ_ q_|CjI[gvl؂668[8s&3gX_:06/o.؆c!_)H,HLƙk~ !*Sxu"1E/,[́ 4Ɓ}5 \CCIQ>1S\GNf" 5>ե_yi[Tғ/Ѩy/Zuy~~393LXNJbZ!B!nSӝ:uۛUVT*O>lٲBc(DT+)VS* _Z]:; WKWX7x/=)KTyuN9作8ɟ$ ٸ)9mLh-Nl."V^Fk R#ʦ.xolKGnĞл\=OθwND,ÿOuWڍ(Tvsx6+v :=7)/B!Z&005k֐ꊭ-}&&&,Y,i#cؘ!\L҅ΝyK;I.䴸" 6vvjх9CYRH=m+['U% Bw[UJfɇhƝi%:yem֒<(wV p%B!B0nݺի.xpu.]57np5/_NNNJ.L& cHU|xCN]trdԘWq䥓tIslf.etqϟq`_Zt~^ |C8 . ':84V[P*C?dXԥAO s13_~9]\zؼdr2N!B!ģV$CBB bϞ=ꊫ+vvvu+))4T* DI't4oFCL杀wx4ڃ= .u֭[8pQOӖhe'yvF!B:j7Ba9M]Ь`Zu{s=\@YO5$\>w[OO|WgKH}TRXu+6%G53uzB\`ث1e%FW=YX1=rd\:Ns<<h:IqQ)sz"B!BG,JgQ++V.޺7!888,95 SRR=Bǖ[ٙ^oogرB!B!j9*˸ dJܽcUܭlrekRBGR$#O`P2&7A (jcffF۶mꫯ!B!BAfL !B!B!#FfL !B!B!xHbZ!B!B!}%i!B!B!$dΧ-?/m.l9ii NgYHBzh:o7ۨsljScm{$3mA:=gTQ2x&!B!xՊt`` Çgʔ)L2CҠA2L6M6qDc.D,COb8ͱMrsM쵞Ӿn{C q ѹRw]][e+O^ъ^.]#gȾ̋zNgc !eEyDkeGUu? ?/}JUBz%5En4o&G}i=ТXIL !B!mj]bSNx{{j*JfիW5~:Ǐ'00G;l!gϋ[,[OKQckrlekBmLh-Nl.T%^ ,v,d& N=LLLqF zoet{jV %1Bﱹzn#xq".j/Iq':'Y?+F*?\?gm\sl@Au{Z7)/B!Z&005k֐yײdeeh찅0Mڝ%1KփQ *)[jZ\]qt1iӯULjFsl:e=caeľrAWP(ʙSa;%4hك/ߓ̒;Ѵ ;ӪKt> &/۰i];~cѠ !B!Dmdb [nzj މu!''ء a47B#F4iĖ[_ͽJKZ΍PWnI.VVwmHU֩`mmMz6v(>)K'-VZ]8:&d2N|8\ |C8 . ':84POƑ>Ɓ}ijŬTwq76ȊݱKƝUWQa.f?S}?LLNߥA ɗN&'3oߐ{G!B!"1BPP{WWW\]]Ӕ߿?ӤIJܹs_ K C龥7Y}0aI&_ۖV\+X1zM+VYUs>j銥% 0p@nr3onOO=dg7ZVq3o(&mX*״ Zv%I~+}GzЫfӪݛcAPQU&^VoQ޸y¶&)kmx<5ygijg9~d'uG^q W ڄL&x;:#B!Z9ܹBAnݰDoNVVhj%[olehf]eYvqr#&7)'p,X ,El[3[f?ܻ|s9zKȾCٗiER/qD]Qo^:gœ (<5{}}'_0'AC'4uSoDdJ꾍iQly e}޷-F-mٵzfU&.jfVzcE1N)S0eJ *_>C__fذaXXX;|! ݝyaN>{WiP6lcXj=X6mbڵ\xء Q#HOO'>>2]ve_=+*l(/2O?4>O=-bڴi |8fff>|X2Z̆2yd駟%**SRRkd ]ƤI|2W^5hģԜoū\>S3KF؅G\>N7jwĈݧQ(sƝW<~mPTEJbAх3S>!=iI|ݬu(cGx/Uވ^~mBsXYߏhkė<amY7wѸW  8 -N?pvoĹQt7NfܬZ{VOWkzOiʘZ}Gv=_AܼvF3>(t5~-FQ~:)~~YZ;ʧt73 k|jͼNrYʞ: xa x !BqTY֖@!?Tvn׊ӷ+[|ˋ ĤI=z4AAAU ɓmRIxxB2Z̆r1Znڵ]+Yn1,**"22;e|ERi85๘[stRr%|#w~Ioq}}D('Cb/fXc=@Ɲ OUsSrv#qWm&/>JFNN"{ݝݬa8u"<'/{iL?>fZ=à}~ Wz~$F 5_Nwbwϫi7R.{l^2gѸx^k;mN w8i2$(;Û?`\uoC9 c(B!ģV&IKK#**&&X[[Ӷm[nܸIDD={ qߙaooOZZge c_'N2w\8Pc}_Qe'uv=_#1lf Fx qQ{0ڶ5uONIĹIvƁ}k$;F=um76b#wk!.jm}_ˉ]_ҾS 1zJccؼd}zN|܏YXcfnKf1(35_PU_G+oOeٿ緒z#ݫgheZu8;7pt$ŝUِ}ץ_*dﺷHINOC!B!5f^ŃSNx{{j*2 E$7nرcܼy (kMGN{Ԕ\)((\2Z̆4`BCC?iӦ d56Zڭm5I_}"V^Fk P(K ()\ +u}CSS,m{"^ ,v,d&jwV|Vݪ{Aٽ_5G>c,$hMZ.gFERJUPa墂l,`i퀵37θF~^u]|8Wzb/:p}C5| ZٗC!B!E*1L`` k֬!33S_TRTTDZZVLx˗/g߾5.IMMչ̃!,[m۶p%ڷoK/kl +|V+ b.llg_V]Sa;%4hك?7_+['U% BE%۱#9wxVV~-։!#5/zEYR{Μ NAaa6O\_/I;MIqx59hu+K,)*RTR) u. G;S+!B!#,ѭ[7XzuIdթSc.QӾ??!655u֜;wN2eWF񘙙accS!T*1h֬53sTO#Wn #ub/!;zoʲjB4}ll5 Hؼt)X5OK uwo?Z^z/‚,iKhElPX01.1mygqtiL^3Ն14'Np{{Qs#zOrY޾ ?C30|"O!jca@VZ=u2|s [:)V2Z+'K's觼9TDaukW8tz-޾xy^[DGl 6(.5vHB!B@B!5;!B!ĴB!D5uB!B[ ŽWĴB!D$ -B!fdݙ;fÆ >}ӧO3k֬mG>}cw۠=ItZǤ5ږCIݮOOOOz*k۶-[na !CIVknB!B/jŌ@qvv 99CquMiӦUh֯_oX ?`a eԯ_h>39bBH[,_gPxӧOg$%%U8vI\¸qB<4B!BC+;CfQV̘%..M6aJJJ2dNNN2˗/׺^JETTïQ]ve_=+G^^^у5kܱ̚5k1bW!x2A!BQԊڵk9|0$$$eєy͍".]W[...̝;]vq~wBBBCP0~xlYv-<==ٴif|2j(?΢Ebܹdgg3tP/sW7?'hy1{ӫ~(ԛ:Chu9G;{n»Δ.!7X^E_G8~'/;9 CA='p yJ|SJk߀%::q߿uv'N!j)B!~CjR //eZlIDD%%%:keeŋ),,d֬Y\~oL4srüyHHH <c߁=+vD{wVYKOo>=CQՠR.XRI)(~ UA>.c^ifMv֥-&4o?G]XHv~ܧ Kr׹_cjoOU}Σ^(.{K{^.JJPbAACp՟^8o?].$W/kinnY|ρ/ϗYBG^u2Z!BG!խ~$mll,ckkK||bPowZ1c ?<<;wj7o[GcccCll,~m͚5czuE֮]3 ...$$$;pjU&!!?srQ?΁3gǏgҤIDGGkU+1o|.ͦ׋1en|a7,Īy ڈ- Aʭ \oEq1k 'U2Eq1Ŀ/~9a9|`}O] <^zf#?<)Ki=o{a׹ǏToΝу-[TA8q/_F!eI`ii$B!xT* ͛dffV{GaI`Y13 l_vYe7[f3pKNN2cgyC2jԨ I[[[oOӧBͽ$ƆB()),%B!eLLL033KKKHHHЬZPDsM&]\\,FXXX0 (r[UngOmSnq1-ģ?N:pMcB|wwwrsshB!ѤR(**lll'11jϞ$1-CLRO?Uz,**(c(Fle6m锔]@!B!GQQXXXhZgڼ$ xqr-0vB! 233e!B!=)))!33vݷ$ksf;!T.Ii!B!AT*qww'33SsQG}ִ\R^! lrsse!B!Af_u.^HbZ!Nu-yyy_!BQ akkϭIZG`` 8;;̡C~)bmmMNN8q !HՕBc$B! quu%33tV$}}}ȑ#(Jڵkǐ!CXbiiiӢE 6mDjj*ݛΟ?o.!lll(**2vB!BZc@Ky]ÇKBB[l Mwww∍%''222WB!j5B!F`iiY]Զ^XYYMAAPU`YfʖewΉ'4SRRcǎB!jGum6!B!~lll111ZJ^j = jMb[nzj222`nn^9jB!B!BꞒelmmQT2sjEb:$$@mۆ9瓓J"66֭[YʣiӦ?~ !B!T*BW\"onnΗ_~IΝ˘Kƍko_5mڴW^h[B_ɉ ҤIoN3oWrSSS ^yyy2kZO"1-B!BR5jT/ҹsgvɜ9s43LLL4vJ4i҄h|||Ry۶m;w9s搙 @:uxwhժ}k݆BB!B!jO^011ĉXZZRd,YGGGONN ,,瓞U/"{jT*111ښ9sBAA˗/gٲeԯ_I&ѡC\]]INNfѢET*tvoFAAO=W^L3pǎ\~{ggg~G5jDTT&Mb5惰l]ҢE >GѤInQ$B!B<2}Ybccr ۷gڴi={3gwѸqc6mڄ=O>$kZu4n :LzhժW\M6̘1ӧOHn݈ <<:0yd222Xr#FH\Bdd$ԯ_KʅOҨQ#.^ȤI|$֜63{*t֬Y̟?>j57&))zɈ !'~B7o2dT*ӦM矧}ԩS>~Wv튕Ȩ7n3PRR›oɨQh߾=?3zҔkѢ˖-K.Z|F5SoĴ1-uQPP֭[J(Iefx Mr 99U~XU݆V.(i!B!bR888h.X33h=^+1 JJJ8{,FN:1|pqrrJ)/33ʟ !.߿?6m"++իW;RII Ĵ{$/؎۶3~doK0hz0V6u9x+B!Ry\6cpݺuoZn|Uj5-[ۛ8+KP7p~mᅪ=$BZԩS3vXhڴ)&&&X ,R:ɉ? jO>7$--u Ԋt`` 8;;^:tׯkXYYѵkW|||"55?<9e4ldqbל?Fڛ66vkSv =>ӽ:N^tб zv#!.j혘7ٻ-NN_ٴO`_:dLFYRxV!^υB!S2e]i___8rJv1dVX&w޸yfrrr $44e˖.feĈi(dﯓG ];4![-өJ4jދ#Gئzn3mB&K']ɸy]nML$9Q08?B!f͚E^^f{ǎlݺU:9x ]t_~aΝ4jԈ,ϟ_W_}E˖-i޼9'QQQdeeΝ;O^$ѣGcooOt5**:0{l8E9BOӦMadff%a&˒o&oФI*kjm߼y)SCZZ&&&w^8x ͚5E8p]Ӱuf rK7kiиWϖXXٓ|c; ?k{n!6v.f%S{/v`ʼM>;(Qi؀ڨ&.j6keO_xqG~N*!)$;pt!;aK8kjK{?N^ݸoQs5eLM-xo? J5TU :<1]ckFFJ G}B?:_j}*Nαy$\>tgF"O'/~g+wѢExxxбcGի_UEf͚Ä _Ybkk{}/--3-S+ӷ+s aP:ž^zR[#6MR2v ϥ /F{odsaM9o\5+يaMzeo0?[†OŎHGE4ǟ]fp=(NnM=%mwݸt/Ϧ]zb/Ct=Cٺl1t}}8yWwg]vM~3ٹj:ף:~-"#% z}m\6"1Gw'PXqVr%|#7":h6{+̧&yfKtQUks7mǨߨۺp|%Qh v9LzѢJ 5_>[8\Z5ofa3nK_";-Wϖ86{ iB_|ǻtyR*۳g־ /..fѢEw|{{;wGGݱ;d59BZQFرSNUYS5J%XYYނ yGQ5{LZZfiٲ%vvv( prrhcMvz]DGR)2Sc8sGq`_rY j5tf=̭ػ-NR\#'_S'VK̅ -:ի ]CxϨ*/#7'r\=Z5zo Cs'yb5G#n~|ϓ%E\^BlZ|Vb#wz=[`mlKtkSs,˹_ۡLWk򲓱wջ?dڂtͭfJIIq!%Ņqj#dϚF M>[8\Z5f΍ذx4Q{Hʥ8[z !B! AH[:ntNfժUZTl۶}2aj5ׯ_ҥK899U/Xp&!O]Tu +u}CSS,m~t.t} @ sNO8SjwbyqmX=J5_*}^wl1]ِ碪תyWdT83PA!B!Ľ$tJ%l-]M*1L`` k֬{FF+W rss %''G6" 6vvjJVzTL+LL+-[\Szѷڰx^7K+CSVT^^UT 1ΥaiBjHY,#MѸ3D>o`;=]{(Egbcʩ}B>veԻD5 +~- /Fk-8\TZ5g.lLCB!`bbruKAAЪ5Kyt֍V^jfeooo͕uUNZ%ͭJm4j[3Sv ^! q \U(?Az #Jrʒ 2yXXko@>e'oQݾMaA9)ZZZΥZq:EWQFU<[js"#[vtTwq76ȊݱKƝ :Ά}^?w.!EUndz?k$ݹQϫ-JeQK8\k>9 .>w2g潾B!呝]eggV$CBB bϞ=ꊫ+vvv2קe˖ӤIlsC5g14쇫GG<tV[hP`bjNWȶq"֌8gT\Z%|`c犙֌qpjS}?P(h2+kGud'uG^q W ڄLK*g,e:G0SL:7bѨyo<[a[M+ {fF@Ǒ86cQϻmEViuͱw *R/| 5>~. )AzafaM]\=pLSqH3pq0!Έ׶PXEUZK*<h:IqQ)sz"ѵU9sl];yi\>Y:g} qiЂanҖ]gp`,æOM72Scغ| 1:_(,ȺzSS ҒZ38j|ty/]{=v~sfkSHz%|رt.`ѱ 7K_4WtnGWԜ'gжy+C΅.U]^%Et8'_ɗ9C.z !B!Pt^^cffI|^JEII z,=YԊrʶnn=.wKNz-ɔcA﹅[زahcR8ߝUuʫj:u͛.B!puucu:X..U/gFXXX0 (r[Unrmm=Ky!B!B!xxHbZ!B!B!}U+֘we{DTId|B!B!Dy2cZ!B!B!}%i!B!B!$ lÆ >}ӧO3k֬mG>}cw[!B!B!tV+֘nӦ 888Ç*Hǎ#--W(s ?`a1PƏO>ȑ#K!B!B3J%Nb_LBCCqqqєiԨ{o$''SOhk]2{l/FMDD_}M!B!Bgk׸v۷oGP)ӦM8z()))ܹBjŅsk.9NHH^u( Əϖ-[8~8k׮ܖ'6mb֬Y(~FYhQQQ̝;lzcB!B!B}0o<V[5b…lڴ SO=F"""B4JpB!B!Bڭ$3f ֭[Gbb"&&&XZZ={d͚5s}ӓAquuȑlڴ 6?ңGF`>m5mڔ rJ׶޻w/#F133ޞ4[oŤIHMMqzBqyzzB!5N|dmVkXYY@^Xf e-LLL(**";;LL[ߟMXn־H7o^[lllxޱdeesJRzԔ\)((J!_l٢R[!B!jCx ԚĴR$55k׮1fڷoQ*bccéSښ_kqqqjk۶mc1o<&LJҩOZ <>BA6mܹsZe4h8vP:lY JŸqq 62w\lg]_~,^";ɓԴ[BRSSxu)L^|EJJJfԩ2{l233< !5[ !B!!STTYUѷtƎ-B@ nV]4@Fh޼9[Yf( ǥK4e222ΦM6k333mۦײ%%%ر___ƏϘ1cefGFFҬY3^{5ƏOrrfIH^x^|Eؿ^mOLERRo'N絰GRRF‚w}WYB!HbZ!Bq?HbVeOl_vdtֽ$M*;rO(B5 n/V !B!j;999FOLTY͍` P%U'˶)]^!B!B!rB!B!Bq_IbZ!B!B!}%i!B!B!xҭ ׯcGB!B!BBfLؖ-HOe*vė_Wj>܋P>-~OOOOz~ 8}4Of֬Y5g=8}4666ml$m۶e֭XYY;!B!B!V+fLiӆHIIiԩS.]P^=9<۷o7v蕊Pӧ~z=h ~ݝ^{-Zڵk3gNr?g}Ƒ#G.sI\¸q}!B!B!R+fL+JN:Y~=)cffF~~>&##!jUm5mڔ rJ׶_~Ǟ={xw CRU܉ѿz-&MDjj*7ֹ풒 !B!BqjMb:##_+++իk֬!== ?_:#Y3{usՒΝIJ*0c̙ _/ΰCB$$ pI;3ҒJIW֭Iַͫ~ /^;^zrOZZ=nʖ155%77D 077׫ qrrB!B! &1T*IMMڵk3۳}v\h??;ڴ˖-7h߾..PR&**xiFZ*RS嗊kBUۤP1BZtv=׭O[ӓ9s0|poٳg}_۷s)Lqq1899|ruK9::hB]!B!BP+.~XBqיʦX 6o.Ӣut)B.SzFggK,,OUDDi֔mْDBBEDDЬYJ]p///ݫ'??KKJﯵϏjm6;7o&&XlCeԩjqF^yû }mSSSZn͹s*S^f͈0hB!B!BԴ>1P(8p E>}pvv&**J+aii t)TJ5Z9VX_*߂y>b~M1o^iE}Rؘvm bt_bcL ɲe|c<ٛK;Vk,G˖-+M*oݺ>s:v숧'!!!9BٳgҵkW7oV}+W'dРAx{{3a.O[P:[~֬Y1yj=<cllloPoFfXx1666|^k+ ;={ZmIHH?dܹ=zqJaa!7^ϳeʕ ҳgObbb ̙33i$y״fR̠A8q\!B!B,JgQ++V.޺7!888,99RRR=gyC2j(, ֖ӧsic#Fn/V#11]B!BrP(߾]}ť2nnn()wXU.w+ۦvƴ0?:u͛7IRZ!B!B<$1-T*~'c!B!B!B!B!B!.B!B!Bq_IbZ!B!B!}%{0xpCٲCB!B!BFa6m>L\\L`` 8;;̡C~B!BG ͛7GTfp חvڑΖ-[B@3J%Nb_LBCCqqqє%..M6aJJJ2dNNN_!B!IGߧW^ŠĉiݺCB!Xbٳgӓ֮]U͛L2tjY3;6n]3g2믊̜ȑ޸Zw]c=LB!BZo߾L0ggg J8tZy6l5L"""زef+СCpSN?/VᄏkՋ޽{답5\xݻwk.j_7o[ošCXO>L::uP(())!''?ΦMHOOVCG=zKF⥗^=BSHLgnnN˖-Q($%%ݱyyy:׽pa{ZvBLyʼn ڔ"I..|yk T[m !B!De5-.. xꩧxINN`̘1?Bݺu#??Kh888Zh޽{)))1P>ZnͬYpssөfK(ё֭[ӺukFٳgޱiӆ@Ο?oaB5igggƌBu֑xSuhڑ5O<5e̙<1*O{O9_B!B)?ޞ^}Uׯ7oVVV|,\]]ܹ3'N0hL 9sZ?dǎdddFf0554ƛoIDwppM6 x{{oɩSM!jMb:##_+++իk֬'L:uۛUVT*uaC""/eqcVbss._!**MQKoggFNL!BaXߴhт}ҲeKի v횦իW GHHZO?e͚c7nܨ c֭[rJСC,\lMƍ၃={Mnݺ1h 4h@:u&==xbeN) `kkرc޽;NNN$''c-[w=// RSS_|8Ç@ROT갱瞣{ƾ}Xtnݺ3Ν;J~~>űb .\`BԌZqC(bjj*׮]cTspp0AAAYL).VitzBQz/K !B!jYܣejjf2O?W:.bJݺuquuJ ;p@͛)JgclK.,X{{{MmҡC<<<4uuu駟?ԪS|7 >777hРcǎw{rrr1c>,A?//˗ФI<<<$%%č7>ecc_ͳ>K155͍gyoV 777-ZĐ!Cpww|M׮]i֬AT!Dͩ5) ͵u֍V^ƖΒ흴DEeS\qc[|}Kli!B!aYZZΈ#޽;srrXd ۷gŊL:ooI&# Дeݛ0qDpppsܿ?zo߾|lRN}>4lؐxFŀx7P*<EDD59sqF5v7>,> G_/">>>dff>}0m4dĉSNٙ$ƏOhh(O=fn !y}bZP0p@qwwˋ>}쬵~tHHAAAٳsss\]]quuNv""Ό5k㖌PLff17wc|m[>8C%B!E4hݻٲe +V`ɘŋ5-[ܹsN: 6%KlИyyyyVٺuB 7WII ׯ_l_tÇhfWRRZFRe˖Jԧll%Khgt :m۶5XVW.f;vwbz*P(4c|rNI4qqaÆj7nwwwr9x :tۛ~uĻYfj&N ߛoɓO>Y㜝Mvv6_~g}_(]fѢE\p_;9}47!$1-B!˗Yh=5Ύ"ٳgf*͛~:#F ;;; gʕMtt4ǏgȐ!t,--&::Cu(J^xӰaC233r}Y9++S2j(vJzPT$&&rqaaa 0RiФ͛7̤N:( JJJ!::Çyf5v ̞=ooo󉉉侜<^}UyBBBprr"==dɒ _f:uSNi ׯpP!`Y1.(l[Qnfz{*HII1!!ﬨ˫jHLL4vWB4h (..‚QFϣV=z]rww'''µ6^ť2nnn()wXU.w+ۦvcYc۰aO̚5ܽcұi<==ٿ?3vONzh:M#F uksg=齭ضm[n݊&!B /d۶mlܸ-[h֢޼y$!P+mڴaL:S2|p.S 4֭[sȑ*ٳoTyyԻ>}:ׯ'))!ħ-?eI%z|H;m콹ʲWRcqܑف99$/T@\Ͽ^XG1 aExxi{xc9|J8z l弟3c'BbiRɩS4MhтPVXY*D2B 5eѣC5v>h^9 Eb~"Vq1"S]iW 7V1'&@^eM5tݕ"U֦֤qy׶,aA|~s Yޚ5kxw駟^sR!BT]^.{#1bH"C1G/ L|'pi%aUr|&pä='7ژ?u'f;}7Һe pvs> N槄Q吭fŔjJh:%FqEMڙSx@hh(B!B!D$̌N:P(n8!e)==0ɓ'uqv؁Z`ԨQ̜9Kri INN̙3UPP@.]ʩbXal3ǫ>6l[_{i-SZLfϷ~/b $r%W{))ZֺV罺tB!B!&姟~Ғ:0h ɩS{Ů]?>z :$;}||ؼy碢h߾}i u… t;xxx0gΜEK~~>7_uGAu܆Ǭ9t8p)#wFʯ\m*x]RFcbp*kw]o>MѣG9w;v츧Sߜt+}cWw'tk""عq2wb f̩+{3{-9wL/M'SuYܪ9˻_9E`n>N;;RR-jJkl $ F4AXxynT]m2o!B!BLbZVUywaJJ SL{ڵNe s쭏#G6TW28?0^}SgD MEfƵ 8 SMZ";;75տtMLLuff&G[nR%22??oӦ^m۶5{yy9Ga͚5?6J՗?b[b?qܞ}^.GgEk?zN: 2zho?x`&L<@f;v,Z]gҾ}{ZnB`5i#FcFQj{v4Z uSXxQoKk3-&ƶ N7n|yCg`:;vҽ$‹ i67 7,L,0QT&5Z qqwRLiƒ%89}K_1Lo8>N+(זOjsΏf ;,Oڑ ,Lj> ́ON&432Mc0CG::t's'::tϮ/KZ۴UsvAU||| 44/B!B{_CբRիjrrr % )s/*++cϞ=5JU6mڄ /2$''pB"""j_oښe˖a4 1',Y+[o`vIYY''O+>j͕Lii)SNe̙pE~WcuA>nf;()&~3]Քp<}ƖK1|_~4E\Nm~Gխ_FG5!Ûoɀؾ}{: +EEE|ٳZ,L4_~333x~gzOaa!۶m#**dkk pZ.ckV&gޮDŽqtnN|QV>pqqkV>=1CK7۽ɤXO>_mMm90ڃ}#XxAzejq>9rHNq凱cbb¡Cx뭷nkNƠ'_!nsܸq;I&͡cmmͫzzj:u]k12U4"NƏo쐍"T,;{ܹsٲe w:Vˆe4?B!B!jiZͩSزe [l!//ѣG:=}. Q>>> 0`crO f„ XXX~eB!B!& 22RRRصk ooo* 6PJJJ yxxp)|A'N䯿|پ};'N`ӦM :NmOptt֭3FWk׮|۷Ǐ3l0LLL7od̘1[S܈#رclݺgyE{%>S'gԭ<5ZAp,c2hN* wM še~]o[ۭ{i>]lvsl&->h6MZ}#xU)LMY "S<+o yiw:yb!|1#XwWn$$$]jP۷oƢB!B!44333:uB1@޽!&&Ν;;JOO',,CrI;vV5j3gdҥ>}!C|r9sAmХKrzիWaÆ9|0V"??>}l2RSS9uӦMcĈ;$&&2{l7oWϘ1cxYlOחŋS^^κu '`ɒ%7?i$"##oY:?p_'r*#js?f#i\Ž8|4-ה%S~BW?Ƕ֘:ʨs۔]Hv73>"gTI ÕJiiICS\Lщ]WLJZ㕱Z)==//B!B!DSd姟~Ғ:0h ʊ!C}vʌAvիdС$%%]͛>E<MFPP`oo.\Lff&999uggg<<<3gsѫ.SSXXxUw6 d~" Կ^GA&NujKV(G[V %Z2\4&mEŵg}r S7<|޻iBhkYL͏*}2V+Bagg?OϞ=y'ugΜeŊ!eB!LbZV@JJ SL{ڵ 777lll=z|< 7vpAqݲUZ޺B!,_GGGV\IRRjO>sCW ܹsٻwoc9rdLQ5Bojj_lwu㞟BmV]X"FqppuJdgg7xLLLXjzq={dСL>`&MlH!B!M&1}=B/_~?x`j5M5ѡCx7'%%Ѯ];m$&&֨ W^^:RIϞ=?NS ooo(,,$++vy8::"##={Vbj*sZ rKXtfա#e qTEW|)5k^:X055m.@7FEfigPbpU_m- AV3m4z!^{5@Ν;Ǖ+WسgfŅ:m۶6tZBE܇d c'̌t4ĴB`Đ)۷ŅÇ+:WQQQNƊZK8VeDFFH_z'O(|P&MDr 55o߾ر"h4h4uI:Rܹs/3ڊ Wa-KCCZwFFq)ܦϟҘh&љ,#t}ǡ#Ixڜiꃩ+ֹh",,,j~>>>xxxZ)w!R׿jݻ7JG{>dggTw?aL21aii)iq[}bZբRիjrrr !&&ݖ2èQkߴi...˸… Q_~Ϗokkk-[Ɔ |Ǽ;XXXd6n[oł عs'eee矜 wfuߣ))}4{ubJΑ߯ޞ={x70`۷o~#Gɓ;Gq8{,Ç͍FVV...t҅={ܰh4΃w21$O;Ej֫^&WWW-z}(##OBEgbb¡Cx뭷nkqo7ncǎmsX?`ܹ+Bܷt}yV-Jc@/?8yyyXy^|ELZ̍<@/AaL21$xzzRXX,Ե\]]oYݝC5PQm^SZzǴwxyyѭ[79Jbڴisc&ƍՕ+W;ҐcˋO?TB{ÇuIiL¯Y5k;pЭVF!B!$EQ*L8V^ءhoFhȱMtt$B!BѨHbZ4$&Md0%B!B!ƥ4vB!B!B!/B!B!BqWIbۺu+ᄇ3;ր6XatϡK|KVѶ K|Jcw ֺۛP<<<\ocݺucǎXZZјB!B!7Mb]ҡCȑ#$&&ݛ W_;z9r$_~C' 6?o6v(Mܹsٲe u8VGi֬qqq|G=zTLXXL6?! !B!B4M"1V9uyyy2zh֭[Gff\vv6n];t! رcJx׿իٿ?&MbժU?^Z,\o2c.B!B$4<"""$%%vڅB[\EEW\ѽMtR/=ʯJ~TB`l߾'Ni&zmy{{Q(F9>fnh 't!mx*Q(xq.9&v{4jme—OWN!R:yb!|1#Xw+|8 s#&Mĉ|DGGtR jMbmmM߾}!B!BqcMԩ Ɣ̚5 FCzz:gӖ|71|._LvS=Fb̙,]ӧO3d/_Nrr2gΜW[|W'O<%KnҤIDFFTʊ~ۆ3P$a t|O٫H?c8M5e W[x`r6N\5- i^ªCG<5Hz5NòXVUƕ*0hNA^RW,"7hR(:~^鉱$̝*1`ݢxzADDDXر#n]Vs:vXJETTAAA޽^S!B!Bk2iLB͛7۟Ʈ]֖ |I~~ =ތ9˗/Tz&NHHH[n`ڵ 0I&BWx>֯__τ n?>>G/=*rꅲKu>>n>O dW&)?p69'ܖZ}3?%TQZZtŧ(:qmfsGl*)+kWT]b:ze'01]but|`.'Nu_cّСCY`3g$++֭keCzz:^^^>B!B!B_ILO?aiiI4hpҵDbzz:/_fp1c_CvHNN%LJ͛7m}jk͚5X[[s…:ǒOaa j *1^(/ d޶sXvW[;&6Deٛі(>^cfi>]{WoX Ys37&88R~rή?Lyj 9ٵ' T*UXĄ"RSS)--u|[B!B!4ĴZMˑ”)S޽;v|II 8::;Z) Zmu}=]>CYx1O>dRnfȑ 6B;t|m,ZŊD }%kՅP9&U㞟Bm7絛1qt򲅔%\ Z]Bt墢\XTTZ_vv6klc9p7ёlB!B!$~XBq; ---ty|||eْ,,,jݗDvxߺsN>sY|9JCj*bcc i[kPZZֺ,YuHYµեmHx9e(LL !*23(OKŮM,Tbۧk>AS/S LyM1uqHj3g޽ХKΞ=[k]~~~D!B!BZOL+ FAvLJ!CBttСCueڴièQh47LDێ;HNNfʕM~8qb<ôoWWW6l#GE>>xxxR!B!~jT*zꅭ-jBBBѕS(KKKHMMe׮] *--e̙3>kkkXfM ~~~|7X[[l26l|0ަMpqq_Օd.\HDDDڪҥK9v whJJyr8o ϾAicK٥V_~e@~ۆچ_#Z#nxI|Ž׫*xy}N9`}Z=bgLW).$ZW&x/і` WOꕘna*rjmsϞ= 0۷kc,^ӧ3sL={UFɓ'OB!B!QC]Ԋj۪֫^&WWW-z}(##dff! 0n8ƎˤIlN{ s%<<!nKחjڒj4J>,Ci06ٸV>MTS((ʐ);;; $OIaaasͪ~VZz,ΡCzy\}V{USm}cZqwlܸ{{{\]]r励ù+O%)-sw<;>cjaMEY1Z KS *ʊq! +B!Bܳ$1-0Fo5vwUtt\B!{gPfP^bV]FF0᲼ZG~.!lXcwE!B{$ ]~d|B!D5ig7g6;t!B!y.HY;~]sw]oooBCCg}]֬Ys7SuV g;{6<> [nرKKKc"B!BFI$vɓyyy'iѢEr͚5cرKK?ssscߨu;~uw5sehʾ}?~ =[rq~7ziXGI.]8zbMaaa2mڝNB!B!D$jSNelB^^GUWŅqQRRBHH6m… ]#|||0`A<_'O&22UV !nGpp0&Lء!B!i鈈"##III!%%]vP(֕ٳ'˗@R;2ssGk<M oۏkx . E7Cq5t++ T,/>kNBNjs 8|1s QtIHH ..\]]Yt)G__~5͘1{o>^~e}]v/`߾}?~aÆըc۷ ֯_ٹs'|ptt֭3FWǤI8q_5,]Ǝ[cmCOӧ}vN8M:tmMHHGP4X=<<8u>'_abbR~݌ݐ1fbb¼y8x gƌlݺzFApp0ǎc֭<3(5dbmmM߾} !ٺP~ء!Bd;fffFNP(zS2ȑ#i޼9DDDpc\+ Mi) gJI*-[땳ދKL]~x-z):vxx4 t/+R}AKT)I?r]xRz1 Q# #zͮ~_:3K1fp'y$͟KQ1xO9=zQ>KKKʘ?>/_]vҥ <or!pwwìZ|òeHMMԩSzuYYY/d.]?EEEХKrJիWaÆ1wؑ_~EV9s ;vyCϭ53gtRN>͐!CX|9ɺ봮mW_'|ҠNOO',,CrI;vV ׭z cӦMcĈ;$&&2{l7oWϘ1cxYlOחŋS^^κuʪT* b zB!Bt5Ĵ SLAPPZZ͛IMM@TbeeEn8qGۛR)=G/=*9K5ʩHY24J"q{El%sبW>󇵸<9LL[Ztŧ+E'|&τק)1l@vpe5p< i3Is1pD{fȑ\| Xb/OӱcG]bzǎzׯ_ѣyGj$-,,XbUީnp_LMM#;;C`fΜIVV[6Cz|neĉuV֮]ˀ4iuiO>a| om۶1{lSQQAܹ3~aP c'Nf߾}{ܹSs3gdڵ??iL{yyݑc,B!B$sss駟C 4`rrrtr -[$ LL[tBKJH饋+21qtҭ8:1k}aGO֨K[L[Y|z\,S'm%" \,,,n8KvHNN%Bo$>>MsniӦ+&&&zlyy9ϟW_ƻ EEERZZYCϭyfmQQQo߾^mYkk;z}ڵӫW/<СCIJJ;jwL233ѭ;;;9s3GZ-++g!hlJrrʩ%9q_B!MPILjʻLBٵkjJEvvg<ݢP(@55?[絛1qt򲅔%\ Z]BYs]ua^uSܿ돏Ǭ'UlUS7\*˗/ё+WZO>uޢ"$w]SPP3?3Qw4$C!և~7/'ԛڧpAqݲ.e]Ν޽{ jѱBE[;!B!YMᇵQ(zwfddWޞBcZ⳧1o sH+G)%%%XXXԺ/))vm'1_ ԥ;w矓kMnBBB0`:tϏ?2Ty7dwcVVcGdddB!B!?>1P(1bڵ  ѺrjՊ]D`` l2%i~zg78J% S3/Xi>E  :ahS8?}[\qq*3fnzI4zp:u5)cYr%AAAx{{ӯ_?&NXS!11={T*155eܹ\ӷo_K[Ν;so{zF;1bD񉈈}3l0FI-x{c]υZf3k֬;TVŋ$>>^o!2:~&MD~hٲ%oy_2~xONVgɼ5ÃzC!B!B}bZբRիcǎeĈ8;;BLL\tt4{K.L2|}e.JSRB̓)gna<_UJ*tp<GS\DѿaLCtu_(mm߶۾F+#m/>y饗t4[o?;wd˖-s:Q#'GeѺ}dŌ=uٳkK_8~8| w'۴i_5/26mbȑ,\:ɼ-gS0$ݲz[{tB!F$ڵ+:tL9Bbb̫Zgزepǜ 6?o6v(5̝;-[ӓٳg6mb5>?zhONf͈㣏>ѣu.Fll,ӦM?7aB!D+-LOjYuiM8>lģ"B!q5;j5Nb˖-lٲkN >j싋?۶mO4'N_ҥK)((`رu*S%44kkk{wNB!B!&̌]P(jLQ]N!JabBmhvo'e<^yS {?^o/%D>ҕK@Y̅:T~H')n_u*`wE'rsfÐ5ѣ>>;v$,,LV9s ;vS**(B!B!BTd...̙3^z=zyfRSSk-닓gΜ1v7g|{;Cim -[)-!.R)9{Uua9H#r6o@@=\Y֩ *)3l5!--^;;;:t(tЁ,\\\ .st™B!B!$~O?%:t`РASlΝIJJu߽BV(G[V %Z܆Ǭ9t8p)#wFʯd܎fi>]{Wo2UcbU>TzB EEERZZY\ gg:oB!B!B[k2iZMVV)))L2ݻk.rbjҵJa۫6=u <^~!409}秐s[T55nT겳qppW)((ٙ#ٷujBqu CUa9lgcB!Ni2Sy\OPzwlΝ)..&66{* B}G j"3Tabٶ]e2*<֑ջgΜ{utٳgT:???"##BXL4;wsNv޽{Q???3vB!B&1P(>|8111ajjJqqq55% ӧOhms6 SW7 :?@Pr|aq6 T.GSZ9MHڪt%`Fꊥ0qtk\tlj`ѢEXXXPVVOT888J"..ugsϱ~&NCTÃPcV![n֭7(ܹs2vB!B&'Z-*^zakkZ&''bbbʶoss{R6mo̜hg=C٥5^WXm(mH~52uߣ))}4{ubJΑ߯u7 @Pm?V.'oٳ7|}v}666_^޲eKH||B7v4 |ώOz7fpj{t11}!4˜d cC'OOO Q\\6E-i-˸sС@*-5Wk^UT[zƍՕ+W-///>SIJ !hт6mڰ{n6tž={̌˗/s%zqZQ|+zlr|c'P?aL21ɸ Ah4 ~ ::hc!BU$&&RXX3ؿ?:t`ڒĊ+B! Ĵh0 >oBaBBB8pp ƌc0oGgJ a{L!B!;Jc B!B!"i!B!B!w$F5''g4۷5v(B!B!Bq59vJppp 33#G+cbbB޽i۶-VVVrNe~Ѭ[LzM`` !!!deeѢE Lii)fB!B!ni鈈Tڵk.1Ibb" DFFңG<<< NL)7ϟ ZjNRR1'jE5lޗ=]h˚={ҙ5$jlӮtӹ}B!;N@QPcjaCEYao>=(+˪]OA\!`bn (mfRUA‘ό!h+@[Zq ㍖yB'ffftBAzzn{rr2͛7///tuZՕ_Ow{5>/J^^9#G6}u;={_ ؇M!po7G`ayr\ܳMঞY=(/ͭ笝}{t vh:[ zajnKI1rۤ`cwUqhwL0e l޼TÇ3Ϡjh4ٳxb0`?EEښ=ktwDZuU.RPPEԩrő ->]׽2B!D`bf@VnRϬ7v8 \Lk;h w5ֻ; vvv4XBMM&1O?%:t`РA@v?$;;///Hii)qqqcG pp0#9yDmrLn=.j\V-C/2bmKĴB!B!dj,RRR2e ݻwg׮]ߟ'O @ff&^^^kQk4ڛS5'5JA!B!B!M&1}=BJR:V[DF`ccwœR׽3%ՓPyVV&؇K!B!B!FV( >055}h4$$$ХK233uSy<8q vdƍС8R ciiB '223gсޜ9ԩ-}B!B!iiVJW^ڢV!$$];vлwo%;vǏK/[ȸq<%%j:'X>脝)_;cJ!B!B!+}b`Ν,SZZ__UvT* ww >"ڷo3]!M̲e8{Mo;T!B!0&姟~Ғ:0h `Ν@ JrH:mt;cPhƥ m-!z"c&!=Uq&$KrHf~Ƹ<0+G1Ֆ-g}bZP0|pbbbԔÇu5k;W\ښ޽{SXXxB!Ԕ cѨXغa@qN<#~ښ˫JQϩPTEd^Ga֥;ot ZDBM{I'1CZ-EWѸt?co=p~V>]~!n'Z-*^zakkZ&''bbbt4 :uё 8x *]B!Dݻ !664*;@qR;la$9 FTE2}!i"2"c9BC44T>V222駟B!31cpEBBBرc%%%M!B! Jc B<Ӽ lܸ777̙Æ 5kO!B!I1-Bq"**?zÇO2n88%KB!B1-BqUTTŋY~=&&& 0a !B!QB!wB 00{`mmMJJ 7n4vh>TVx[wrjEA9c#sʩ ;TEW0qʩ%9qG^>nĴB!Da )+<i޺?ܼ;aniGnF,wL :6w$\G'h].=&WqtmEAn gj ĜG>GQsj5*f +^X+?pJ_ _p#B!B!w5t޽!&&tf׭k4t$הզ7g}GEyielpa/|)_KG(̽Lr!KLwGt&]R:T25.O\_sѮXv8x~b -sYI|*[#B!B!w)@Chٲ%۷N*XXXP\\?/cm}o>zWb=s~=FN)IˊdD:1]< -wgqqlGD@~Vo5MS̝NxW\:(m. 3$fC4T=B!DC{7iٲ-˵lْ7|(k'_c"swTEWJ +rjeP0khCBiwL[YY1doNYYYe PVTPQQRY|/ź_=IB_u.s+ICvq'yѮ[@J!,Z퇵J ֎%s1|3܅eƑpk[7lwyxz1 +[Wm+M8[!1B!ڰa믿HHHi9WWW Ɗ+OT%?LAT [7Mzƣ<MܧkT!FvssƆѣGU%_yOYY֜:u82]\lx :ԭԫ!jIIϑC~3,$7ZM#%JEۮc+ӟj٭L!̶\oF]nH̆hzB;W_1տB!B'/_?mj/ HKK[WFTҼysΝۓKs(-ι2uՒO $*>˕FIq+ݳ}ҢmJLSR[k6 K{m]uu@]MAR]]B!0!wI !B!O>1]QQAvvvmo?uG&((K.ѥK8s挱P/n&nNRVW4WjȽG ĞنBiBQKvQW\vZ '}Fz)r2.?? ¼Tb%֍Cۖ\8 z } D.1dg\U!DmBUZ]Vs=B!;!B!5ĴٵkAAAٓlBnnCU\.vMА7011'?';>ĞU20>QLr5(/#VzNk?s{U<8ez=>rU1ub>k%vnLwlbN,5  xɕL,!B/jpyefΜeŊ/B!@YںzC޽穙>B!hWuPZ[[[RSSݕbݺu,YZٓ3c ѣ4i >Kǎ7^ހ]{v&oYoC$yT\q[K{eg@AA-o@*xh( Ҡf׷Y}i0 3{OS 'ISOSvN^?q}vm3.YDAzݦյuk aw1=6e$.`jnmxoC> eyq7l<==),,񬴺>;vz2:t7jKj/mW:֫?wL !BJ<\p7 r9\ž={5k...7PჇ#L̬ne9PiC$X*( ƫ7~oZ|iXHqcwVzX{ң'h*xTh*tKC>wm_f%&֔>uO^STJҎ`䇵^?q]SQw_$( lymG#&;50>60={.CijnPo|c_=3Kr-@6HbZ!qss#//Z"ݝf͚a>3yd{=f͚_P.t[m4@qvLHx7// [W\aܕ԰M@ cm@W,ȼt+owL+ T%$ܣݥbSt.1y/߱*>[^9IQA}zGSk51v m0"4;B!C~7.\u۪xꩧ5fff\|K.ѣG\\\ҥ {ٳ >777OZZYYY7EG-F铨';\;*ʨFSiJ2ņWשj5)HTbD!i!BHRh;t %))+V3ؿ?Ge׮]|7|:A-B!7#i!BT*3gA$O<AAAXXXлwo߉'3fL5kְf)B!hڔ`m~a;ۛP<<}9r$=z`ȑ9l0B!¨m۶eذaűe˵ӧ8::r9vepDX>|̟3v(Mܹsٲe uxh۷իWaÆ;ΊN+ptcp|u+cX; cr } /+/ Yxv!3v7eȹ #66iӦ;d!ɓ'TJBV;><'Q^9y?ΰa5:>~xGPPׯܹ'<<GGG~mzms-鶆ѤLe<ެ\za1,rCx>5i;,G?Ntsꆃ9s3+;ԭOmyڙf39s/gH_l"aH{"ǣXXmn՜qϷ~ј*/X[[ӷo;tƅ?5oޜE2|ݜBTE۸;!V5.Krn&QU {*N'B4󇵸<9LL[Ztŧ+E'6x[BSZB]h)OKi2ĜyEVcn=HY@fsGlLv5.OMSbڐsaH 'N5{ oooF˗HJJQ+Vhx"O?4;v%wءW~=GyFb‚+Vp9v`Qޏ?\1^c]X\y.ռvf>H^|Ez8%7õ2kXĴ% . ,21S`+G?bߣ(οNƐiE](VZ\!y:,b^<5崰nA,8?Vou.KOO˫NB\^^>B!B{^OL[YY1doNYYٝm+x]"FJ/]F^n Ys37&88R~F]rghwnc:8EGu#W2sx/v}wNO,!dfi>]{W/MqV2\ү[\*ֶڵkGrr.)}#hltL6 \]]111ޞ3gԨ7:9v"(^h̲L̮];NNC?~xXz`0̑95FExnxUTaJaE!%ɔK0WߑoKƜs853Ɣd^S6N[vbX8s0jUVVs?/0 ;wӓ˗/siB;=xc"B!ji777lll=zn|ů ϯg h.j}W}3-,TTj:JEͪ wB  ¶Wlz<xQCzSapv %q(ke3ϠA|=};Ϻ}ƩS\,}BCC]ֺv/ƍ9y$; {6vhBLUTB6E@Ƥ7UGuyݦq}'Ɗ?1m(sss&Oɓqrr`Ɍ9:4%%<9 ~ vQ$\@+ӱjH{MqGw.Gg:Ӆ4O8߆?iqF#~3z ZCc֔} q233} 0ظq;v,&M2hN`1uTc"ΝKxxA;Z[[%ݼy8p 6l !!___ƏΝ;}̳> oPvlgN vvvܰLIkpEƤ!O<{t ޽)ώ$g~#zcӓ̪Z7Ssuuewww:@E{MګjjU6n܈=\R݋LMM֭Cw~$ ֬Y'_'N;4!B!0*IL Qoa4 z!c!hM)kѪU+<==III!!! !B!Ib zwMg',B\/88ݻwBll,qqqɜB!BQEMXᾈY!^~~>cƌa̘1\xvAIICޜZ-5-JRUKNBR|#vX:ԵeemV\kET5&o4k;[h?Jxݨ<:۾XңT?Vg;W՜㺇'׭ڼ~ioC%=CB! 駟]v <2g{96n܈!^ui/Z-ztS k*ʊuKFBiT٢41CibN֥ wn#PQWը05m9.S *ʊt\2/4 1Y^(M-ه?QZZ5W۸|Ɣ emmN۷٭{9 ' Sq87,[ܪcU4ұg~Wrq (8kC'Ib| sNgP/¸qHOOg}]<<sz!ΓO>ɸq8pK,1vB$^TEX;?`V åMҸ{W.*2DIDATJӻcZu;/7;ea1mO<;>y&|$tSӀWשF=g:'w/E N>=4Vzq{땘~|z4 Sc(H?gC'5t۶m6lqqqlr@FF%;c͝;-[9)m,clذᎶ -y3~0_];,οwXkm_ʋh]Ⱦ+Mr.ˆeڴi|Y&PN8ԩSyꩧ0`$ER~No'7.;; {]U1  {b{Wשs2|ܶ-CzS;dooO>}̬m۶$&&֭[`̘18;;;lH0` y Ӯ.q $<7_zB6A3a,,,MBcǎOhnw3v;9:N>s6(6[~m~H_x*p5Gh&7'.z.x:Ic%<^yxm>jՕK_qQ~WW܌3ػw/_׵kW 6FǏg߾}~z?Ν; Ύpqtt֭3c[F:2xopqEbŰҋ73,'94}j^;ZM#vX,=H"# 3rF3:gsgVv^[ڵ3,f r.s_3ԩ_={o vX,?*6Ŀ; C/wS)t \v7 lp}^#44kkk{Gϻ+n:VZÉa…>kI& " 8QQQ[Qq:+UGm}U۟mҧZjK{`Qq("A6aBIIz{OsO\w\~m/0f Zzj(J<|:uNL8qB}~i%MMMzjܻW:^HHHm |g0 <-=©/-}DhvrsQGP ۭFwGpsfLo>/5}I+1m&2w?ͬҾkXh c1m&nccQ^jj*\]]"Zpp0;K.AY""""""GOLcذa8~8d2Nٳ'7oD;CNJW(!T6Q/lyB{3F"llQrC.UАgڇ'yBtx y.@z&Dq?W%#o`wrϝBCiHi2.l 4[B#gFi.DAܳ:y*S 5P^ $LMM!+֮];$&&Vy1X(ˍ D fΜ ___888@$Zuz!t؂XuR2B2dhbkI,l"ƶڑ+VNGba" K a"4V}QQZ}4}Sﻵ5L8H-JE<5!8>3tRC@dP yv"cZ]"/0t(ύb)DX_֕[EDiGGGXZZ_Nxc~~~ƁW[P.X}fc CW! ؼ@|$P|!{al8>‡As%9=w cƗ&NP1sk\]#'mN**.dY)t}"(ުU`kkk"!!%%%XnzLWPP~ PO/4 'mzqLrDDCR`O=}X&_և\)GNqM!jNnobtY 5ǪH.DV1XU槲D"QDDD)*&yZ&?f:FaV Nްh≼{iV,l|aޤ QT/~;v`[JJ =zݻw#??_]o߾С~j%cwoģL\~PqH[_$(aY*Ur9~>Pzfv^9]`d=9`(Xt 3 ]MdXcTOgֶEw,&JBsuƎN0jb_a0iӦm߇;\\\?B=z-[pu"''nnnծFFO077v;U}-,[T8'#c|-.e\BRavrƂ_;׳?4] ζ1As0U܇HqhQ\柱d{{H6mV:' $MPD}FiѩS'?ptt#bme>y|,Zb~0i !V*!UP1}9M/YCX#{GMM!zȱp&̼S^JDzǜ{8TJ%wnAPc{o`?}&^ Vm`ޡ5.,{Evp]-ntX]UGp9CôEk~*Eqe/^Ν;Tkۉ'knnn߿?Ls,JѣB!xbX[[7ebccѷo_Դ3G'N`n*DlA,vD?~1J p@c1>\c}=aM"Sv~ vx{`knӪVo4vL찲Jtt8~onވbxh-n՝WXUW幻ծ}bZW^^^011ѣ1m4G:ס,,DQ(|mASdtςyz]RZW{ߒV~ :A)8Mɘh1?{ MN@5ʺƬɐse2lCv8x D=6JbȻxB^G.-GU9~H:~Z?cFwn85 >s 1p@mEEE5k"##_xwW<~!pI@*ƍzQ޷~ [[[;v W^՘Lٗ3ƪ’B4 aa\t/CTάѦ#t׆\CAIάkӻwAʘLkkti,ys&/`ʕ)ZElYĸ0wXUp(IzO؏/nĩp+RR /UO1cƍv'(2*^ヨL=JՂrʖnFU@FF.EǺZZ"f~InY<&L1uT攮~XYYaƌAFXYbF#$NđdlÇxbjOWTK7l۶Сs{?:yyyezε9NxxZ6ǟKp4 ɡϠ}xL1_>Yk]3K ZRCe @ E{r7U[2-=?$ w}wTr9.@IN6.amm 獑u:p.J9YlK;w]&"""""""ab5HgP)޹@)VX^T_yP(ЫW/CA: Dr6Vw^ J[ٷJ+H+""%""jJ[@dbyAX%j54e"cKCB PkGDuuŪn/NKEچuZ1-んO!F˃j^Q%ܨ]A9V(̊MEEE?lsN}Ƥ7vQ{)w)AJ+̊Au*kn Yۈ лI"'4t5ennaÆɓdO-]v~CTT &MEDDDDDDDDDDWϘvtt%|}v(bff&ѣG>}:^|E:uлADDDDDDDDDhtRRvءnС())ٳg_s DDDDDDDDDDJOL+ H$u 5 Ɂڷo{{{\|л@DDDDDDDDDԨĴ.T*r9z Xdeeѣ4txDDDDDDDDDDJLL8p@kɓ' yb'oCB:K7NǏ_ 21MDDDDkٲ%ϟ///H$EHHV 6%%% '|bЉ`bݻ>Ji,^U)  k;?z*_U?7>^_ȐT*àzi"""F&33'~ aΜ9x8J봶w!X 0t(ԀUV3vX`:Svcb$$$`Նn۶-FT@lޣ?G01B$7l`:T"""GΜ93ghx".^~:^yCJDdPi v򆕳7R9-.?.IrFr!"4Ĵ5z]y*<0E'!+ G׎ulmЈj$B!F@TE0GQz_>/^[~РyPf-{KG01BvZ7~S1s$vPР:Fm3K!><. 0; 7 -: EI.g3tQi0i???dee!22Ҥ.e-;Gtuu9}CRl0ZcP!M3=8"i<?#7+IWu!aӧֺƿ(^153É=o=HD1tQ:///?Fe'v͑Xzz_k~7f!<:.q n ۗ6#~IXmJDËNBSzǔРJ<> DDDDDDDDDTG6l?LV26}3'!.etRjbf3fYX.U?6h/Daa PS [xN$^cY^3&zǕ}jDDDDDDDDDTĴ#,--^'>|l߾Uթ=RZek;u@8eS1c,p1`93R*0f?Lٜ4QډtPN(2~G=ކ FPȤ{Ss+(R( !@C 41tm  YL-DFѫ餤$رCcСCQRRg"??R2*fHU2UwހE* `dl^d4oۿĴ@ {8_HL`GwY&͆s;ŶʹٻPhRpt(!""""" ?Kɰuo X?7:ypsxtJEOӟ:l"F' $ֺJee7OWW0\>yُt )qХ<8 7\(WO|V#?'Q!22[0;"PNAs =Pc?)Х\5$5]3s[rv?n%B7Yh=Gsi"""""z$Cr YYY & DDAOL7Tt]7GSS1r2pz!7¡YGLƦ8{V@h6˥xa9|)Rd$CH&혅A7?B<ȿ9!!+EHU.6,MŘey|l"2tQ0- - -D?. JKK2 Cաm%mfPOWTHNN6Ko`۶m!JGGW3...׺ۓUѷ,䄠 ?9J(+?VʖQn1Ϧ{*4)1Mu9 gLQbbӵ.Yp|3mf(t͂Ҳv* [t F,zggg{! $$}3s E֭N833g349۶m#G"&&~~~(+JqZm~nV4tWfK0,.*!a@jj3f 6nc֬Yhڴ)bbbf\zU͛73gbÆ 5Ĵ5z K$;vLT* sŴEk$CbP8p ƏoPjE>}?.\Sb8q"58p˗//_զ3P(ȑ# ( ozck~D ^G.zp*bx_ 4;&c'Ը-pv"]baS=ɓSy8L 0W`M]hw2|"R 8]5.e`ԨQCLLLq;88/ٳgqUݻP0k,?~ׯ_#FԸ-777=z}ԩSqulڴ /Wa=00۷^CDDDDDDDDT43HTX̓RDjj*.]WrZhn@YT!s0hWv颥Hh1 nv?<Y\,!׫Ֆi6h'YGW< K a8vPOGRqX彏"= yN(ؿ:˿B²Pp#f-[}PeHetwܩ0333lٲ2 }Ю];cǎܹs_6lVZDV-OOOlܸGźu;u_U\RRPtI\pzA$=<<]vUZ&%%NBvv6b1|}}1i$ر:c;4/@X:,6Zxߘ?@i2k`3t$gEze-6FƎHgB33`eeD#F?ܹs-+!55xBOLcذa8~S⍎'$̚5 ֭-ΐǪeI{w`3i!0,qybysP;إ-]fKWhlSJ:'SS h׮Չrwwǟ.<<۷V[?#,,,eyD" 99EEE066.L;;'aii :ϟ۷#77Wyͅm @UODe0h@>(NYiJ.83g:rN.SD"M%U ɺi/gaҤIHMM#//vvvؽ{7.^t:[[[H$ZG""""""""IaRRv؁ݻwo)))xvލ gffkkJWDz6Lݐj* fܻ.5ȱHY τۋa֪ ;tz)sEtܹ¤'knnn߿?LUΝ;ӧڷoۇ#Gb̘1h޼9|Mx{{k\Pҋ~G¼yhӦ -[sssZu9DDDDDDDDDRCW}d2qԩ F[ C+ʦof-,=d ܷFNpy99A%ojUFOc]DKuǙ{AY(wtR(RCMz)s|8p ?f… _qqq_ѦMlٲꫯo_?`oow}HLLqΝjU&11+W_|`\~.]g}Yfaܹ 4.3fܸquz i@YԂrʖnFU@FFc&L1uZSygiiÇc 1t8DD#,R l]x m  5BVVV}7/L6 aaaX~=7oU)h.uԨQCLLL!988/ٳgqUݻ*7{l;wϟǻᆱk׮駟py\v ;FUĉqyb߾}vN< oooXYY!$$!!!Ųe˯򊺎Sشi"""_ //Ǐj/00۷ǛȐ @mCVV"##㣵!!!3f 5k|ܹs:!47GG,*B܂ِ?Jwgz(gbOEG!rXX+{4 /!/WEv Ƿ?C(׮<Ѧ\ -Bpw脒< ij ҩ͛'''\|ׯGnn.z ɸuF]x#::^^^(((@^^tt*~V̝:u¯^.))Ahh(:uUV.#<<8}t=!4Ĵk׮ B[n~:\777 4r\)=lG枸hr%99xGR086,vW'(c3'M͠ffxǐ.M\Z~U97H&VS6CGq\-,MLxOA)8%woktRo ,M␾ؿ:C+1ׯWK/7773IIIryyyXz5J%>|^{ :uR'O8Q~߾}G~ӦXz5ݻ ѹ`eeD#F?ܹs-+ 55:DDDDDDDDDR6l?LVa@HIIkΉisΐǪ)~(eEfDM"&pa "[ЪKU,44USϖrw ܓGoߎ\rH$hM4P.X~nǞ7AdkC (hyBvUIgAҁz8= Bܳ7,Ìp~}"#<9ӑsH=D~rT:WIII}تU`kkk"!!%%%XnzWPPGqq1`ggݻwŋ[[[dffV[[[qMDDDDDDDD?LJJŽ;{n-%%=ݻHKKsu!{&-`{2[PqH[_$(aY*Ur9O96K)-̬mhXxwXgޡdq&Tˑx)kW"b6{O"# )ɰ C6m*v}ť}# ѣGlٲׯ_Gjj*rrrV:adTwBx"]tݻw+,ߦMU;"""""""""CiBDqS((..D"Qzh]vE&MбcGxzz>|Xy'~`C9TB>#c4sC_臰4 FB |}Kz yG;:i$3vlF?-Z%醌m m;r,f 30vqסR)Q/R3bjyp`V</^DΝajjĉHLLڵk 777SLp)=z@(/uWll, ;;;jyg7D6ml2ת v,DDDDDDDDDPӺsХKL>/Ο?pP"r(>ݩpY G :qg}Gx_A)-@տoI+?Mٯ?k`7$o澝Hpy;}v_EPpLI^.6Cd{ԳgX Z ͰQZI3gΠVTTYf!22_58wyzχ~///3cϞ=ر#,Xxnj7n 22ڱi@iZPn]ٲrM{??*0tP=7a?SNiNŋbp N'˫T*bRo`۶m!+++@^^CF f\\\q3ZUѷ,䄠 ?9J(+?VʖQnq!amm ::Ii""""""""zOT_~1tu*""Zn\WzTmXg094w\5 Xz5BCC 5 LL7`>!Q=ԣG1f AWy-X {{{CNX,:j8Ȑ8Ȑb1$àzi""""бcGܻw8s ͛{{J/Zc!Ptz7GG$ 1ydCADDDDA <'EDD`n۶-F/ZO#"""j޽QF @JJ 233 5 *1mmm޽{W3ݻwk,`񈈈0tDDDDϕWԩSزe rrrj*Π&"""""JIL B9ڞܵkWr<|С=WT*~G㏆(-~~~BddN;w0( CNDDDDDDDDDԨ4Ĵpy{zzI& 5tDDDDDDDDDDNOLcذa8y$d2NABB >QSvtt%|}v檷G5tDDDDDDDDDDROL'%%aǎ={||| JeЉ꽹sbԨQի9Uժ-[bD"_6lOOO $$|9>*g-?S7_F^^虱œ9sУGL4IBz?BD"Ѹ) C"@TXODDDDѣFYfȑ#! 5 999ؽ{7ƍp+m666Xx1F]aRjCELG5g 6 Æ Í7o!//DX~=5KeT}bZ۷ !""";vĽ{3gΠiӦ7tXԀdffDfgg9s`ܹpppz.'Նƙ.cjˀ͛7̜9+O|/ z!@hh(;DDDDT}*aP״iS|8uN8^/cڵŗ_~cI5W8llqQmk޼9ZjӧOZeT0^SNa˖-UxV ժ={K.ҥKQXXW^y:t X^ٳg… Tcն;">>u|Vx{!rҳ֕- -D?. JKK2 CsdyJXdC 5p...׺$+INNN ܽceܭls*""""""""""[LLQd&A.cafĩ .C7󓛰qh}i3C""""""""\KLm#GDLL E"жm[#??qㆡC2-hJ_95ì/n8r2bPU /ƿC!"""""""zA%ѻw /燎;ѣD1tP޽{]åCƵza+_Жȕyƚ8F~N2BjT 9r$㣵񈋋{pvv~ӹ m3@VZ$5 }u=ĶO.9t3νgo'8m& ^(ġ-ӑC_]+;wHRmqE ڎ#_@sYrBvF,O~k5uY1M.et1; 7 -: EI.g9YkUV'w/C e?Bhv7~Cnfb?cz8B^J:I'V?ѵLU^v`i`ivpʎ>DDDDDDDDT31l0?~2Yk׮q1H$bРA(**BLLu4nzk%%\6uyQ,ՆCKܻKc]Z8UOmJXN[>:ǜsS3k<:@x>BRnBm3}ƬШX.ՊcQG}B\~  7G2UxY U\;^|9Ɉ ?W~ """""""'aii :Dcŀp DDD222 ___a{{z9/QTZBQe5:֪mA5bRCTWTK"'=-挤0dyh"< Ƶ3£e% ->bLJ;eN[Tu,R+}ں7\[O>vҼ䴮cCѥLT*ܻ zLõw ^Y~ """""""'ctCEII Ξ=|Bk=WRUiY(fոLmIaN,K4h8uX 'kK;FP**fJkh޶?Ŏ3&-:IJzmi^sѼm]9Csq{*ZD9uUe@.+Y1 ލ^#>B`aWwI_1P( H4n ŐH$P*P*C.]вeKTTT̓0[pr]S/@ @o`܌v/LD)ulߡKܼ꒹[&Nmc:ZzǝKsRet򛉄BCKߠS>d1ѵQk}O7aVuTJd&WulT?kl?Nn>vJR &$9G^%=Ӻ:q0h !??v횡C;(#Q{u',7XX;!'3'vXqlY1 p*D9W̏/o' +%I2AP,⅁(Kt!j}dEޟ@$2$-GqE]FUk:b#06Ýj{e'Zv=sLc,jAue˂re7{ǏmҪ[FFm%mfPKOma37j96hE=zOWTHNN6Q뜕#oCe @ E{r7U[2-=nhѢ̐@$$$:RJ IS-^HMM5tȵbup2s[c>FF_>6 K/aJ)~q8b b S.˱y&0sLlذQen OO ;w_5 !nݺj]ciٲepttIJe,^""Рݻw ;v ?v܉lC^l/ye1p@?s5 R28p/__~N'""""*o׮]̝;YYYؿ? !!2 ׿4&T7nT빷oFӦM4^""`B#GD`` |||h.\@bb"F6mбcG\tIvg oĥȿr q (c C [AoW!qǺ0w@qzJ@w:̼ڣ݉ r˃ s˜F8hm[r%쐑>}@P`׮]ضmFӧcpvvFnn.]>H}Ŋpvvo$߳g^uM]Y-f 7=wu]ףy3L^wn9O?}cĎUo[k}Zq;_S0y(J~=۪}5r`gN,@2 ӧO?cODDDD4gΜQ?5kh9|0BBByZ Z qI"/^ĺuPXXyЫW/( \x?sNИ1cƌdff>Cxxk0i???dee!22Ĵ@ @IIzBלV}u}_( #' ٖ9Z?eQ̆Q̽;ԣf]}"a{_,:ÐEG"@уlcf|quwܩt{Ϟ=_bh߾=6oތ8;wУG{Xt)n߾ {{{@GT<*Djl1 K-^܄؂X\ϺS99hgUO1i yox >>80"#q$HU]}Xpk]3T7zt)˱(#___&^ҥ =z-[k׮7nO? GF\\@+V [n^urOz۹sg̜9'ODPPd "" "1///ڵ ܹ3bccQPPDvL~l:s[}j_TW4[cKWHv0,ӵcQ^jj*\]]OjѣG8qΝ;C">>1l0o兮]b۶mYڵNL<%  .Ԕ9 'O>gS'ODII |M,Xx!T*m<Ef:\uy0vtҌǻ3tedQ1Q0mѪZ}`jj \^x͛ϟ?,>|+WĴiP#R7ZZDhNƺ;9wJ\>JT~jyw}d2: """"j((( _gΜ3gгgOC(#{?{Ŋ+`ccc. ""iGGGXZZ_쟁cEvv6ccc׹4 qް 3f>4@ tHv X6jD"y?/FFY$XFF /[nxW1{l?Pa_$U+R6!Ј T/fc2A6۪}7[[[~@DDDD|XyJR݋ॗ^{gl\LJtRRvмpСCQRRgj%Q\\ +++4o\ Xs <ߣӝXDһa?}&L\!Pi=fmA`dB0o(bxRXXڴiSVZA$&ֶm[q\r۷oG`` v+8//ZsFP(t~nsssX[[#77W}q]65u鄘.-F;v,y +02H`xugVm컡i{5tDDDDDÇ#GB.ѣGxumxğ'O,"""jT DP(P\\ DƺiӦܹ3\\\ЪU+wչ-ۑc0My+짼Jǜ} hN' s4uJlIa=d82vR>x":w SSӊ㶵|OOOؿzСC1ydnM6R.s]o-[@ i`mm]a{GƉ'0zgv7GoD| Z[atk ?G.s+|l}ex[5108:TduVvZ661Û/1G=5QC"`Z1PzܺeA岛e6~~~AiiiUa>s6Bhij &`:u\+W-ZTg? 3f̨6/l%]XZZXx1BBB 5BγdyJXLT%"i͚5֭ѣXz^?|0,--ׯa]""rqqA~~ h-WEOrpp((w|XY*w+[FǍ uKgR K,DDDtT*/՛6) իQCADDDDDDDDhN+lݭܨEDDDDDDDD 5.LLQbbTcR)6nܨŐH$ D||'"""""""""jTDb$ ;^V*===1tP!::]v/]v!;;5 f*Bt-33Sc{׮]`ddd̙3dԩC'"""""""""jTvvv7oJ%RSSq%tӦM^V*HIIAӦM :Q ΘNIIS̙3I`iiYB!LMM!J具z NNNJ0tDDDDDDDDDDJHLGGGHMMETTOD"x{{A ˃BP v^i0SyWXX\JJJ `aa[n!&&`nnTjpyʰ^77v\(Df͐bp9   5`"H=Cc Θ1bbbb P*{̭[___DGGK.066Fhh'""PT5%%%"""""jj' "1-зo_A&!99NBnnLll,N:___YYY@vv'"":VQ"[R2QejjZI5 !Ѭ>zNݻ{:\"""zd2k|MDDDDDT!e"I ri"""j|j]qq1D"bw X HPLL"XYYQbll +++5rM11MDDDRE CT"!Q `kk RYҍ5Q4cRFFFDDDDDT#ưRiMBWi"""j0j<@|B888pi"""""X B畆@l eٽAzHgSWvL&5amm SSSNADDDDDD055 !ɞztCJ4???jJظqz{3lmmq=:uСWXMk}BoX.EX(,ȬQUQ}"R*\_\\bR}tE剈q+K2T*uB7V "1 ǎS/+J52Baa!\={:\lJ*#f䞷kVmCDDdH%[uHWxnhV(HOOtD"/YfJ+f- R/fRnizXٹCm@(BhvBzۀMmHK8MrG~s@-""QU'DDDDD$} -\ &1mggyAT"55.]BffÞ"3>-jm3{soC¦Oíu'qOQeivG ɱrB aZ嚵艬(a,Gq+5""" 9kZH"""""|hADb:%%NBvv6b1|}}1i$رFmSktKɌEhV@ËNBSz%mZ@!/DS(KZd9GPHCo65rM4tttqjj*0k,x{{#88V6}3'!.etҼTxr*yQ,UG#>x!f. H[QQ.+<؅zEDDTj2tmSMDDDDDTtCMh7 [[Z;,xbT/e=V]=mi]UtD}sAnkpm >}gw?HIN+EDD<(DDDDDP- 21mffkkkDFFzE,Ij\>*)#9?8ѬeODСU|ftQ膜n#F &&999/Rw888LMM舒H$CsXXX9"1o sѶ8TJd&7thDDDOUrT!DDDDDG]$rRh i@} 2 8ursseLLL0m4r&Mкukdeeaޅj7wx^t̔pOZGVo'L I#+Ju1gtCNc|!`Z1=[[.=~\voVe"""j$xV3=*)]6899!((@rǏnre[.{ a%s1u@DDDDDWc45*="""""?g&il1~Fab=g#C@DDDd(eDDDDDTkB Ϙ6 cf]=777л^gu'NСsL 4 nGqƴ|}}5IRlܸQ ooope$%%,nT Ɂ_d֨/{S-^HMMڶj89qyelވ1 >6 Wʑ\ө̓oVf{Zen޼(̜96l0XDDT? j"""""zV  Hp1R޶m[ի()) /W^y{D"1H%9و_vbծۈoq Zⶋq?aOW/@&:""$5Uѕk0Sy( og!r ␘Ǐ-Zй ujA4_:ފpPôx+ b~:z>S}% >f^%6K}h*ףծ??x:ތE65WkЪoԨQCLLL8]{ǣ?0qp0qV`qŸ]6A]?# rd$wXdɸ<2R^N7@߾}DDx̎?#""""vvv7oJ%RSSq%ty&&&JЇU߁HX◼>h0dё9yD.}a8;tBI^}x6K3x_Wi[^}}/mq>h'N 2JrsnSytwܩt{<*(MDnqS!S8+L󘆥bqbKM/nBlA,g]W?C_/?} wN3UVC Ssz,___>}ZMDD$NADDDDDObZ "1SN!;;b4iv؁ Dڒ'!qXpxmvb 7ׯ_Xu[A!e(w]~zۿZx:ՙZ>}sZo _kȦ#1\c b5t._DT~uW'[5හq8fxHLsjj*\]]7""O"""""khT$%%a֬YFppV={yؿ?JJJjKq>ZTrHCCj_x咼\̽;4ʜ9s|ǏW]w[dN=| 3w턓>i ̜[nkkz-v%R],mRraSj=fܸqz>.rҳ֕- -D?. JKK2 CDDDDDDDDDD5VTTS9 *XZZ"!!a O{r8c*J۷^NHLbc@͛666s25* ƍCAA !aii R F\|D""## >Q qqqprr#ܺu \h899%%%exSWYFc&N11MDDDDDDDDDDu1mi""""""""""SLLQbbDDDDDDDDDDT&""""""""":4)&N11MDDDDDDDDDDui""""""""""SLLQbbDDDDDDDDDDT&""""""""":4)&N11MDDDDDDDDDDui""""""""""SLLQbbDDDDDDDDDDT&""""""""":4)&N11MDDDDDDDDDDui""""""""""SLLQbbDDDDDDDDDDT&""""""""":4)&N11MDDDDDDDDDDui""""""""""SLLQbbDDDDDDDDDDT&""""""""":edwnoĴ; """"""""":4)OѢE C@DDDDDDDDDԨze'CCC Q" > """"""""":4)&N11MDDDDDDDDDDui""""""""""SLLQbbDDDDDDDDDDT&""""""""":4)&N11MZ._d$''cʕZf ~Wwe̟?~5dÇGrr2,--  s^%u411ׯ_ի`jK.˗7obƍpss3H>OF~4ZOUfϞӧOÇ@@@Uk׮ؿ?"##?VVVzcbb+VƍyؽHNNΝ;.SSrr2vQ1X'E׹DPPf͚jţk=gum S ]ѥ |oMG]+..N}]ѧzGo߾ /"{=hiPWFFF1cF{ ;;o&M#GPTTvڡiӦ~A.k3vX\ps̙3QXX}M62 ڵko> >w;вeKх\.ǦMk^C\\v܉:˴kD"ܹs1e}ӈǭ[ХKip\p˖-CHHLE#8q˖-S/ػw/{xw4K!>>^1cW"3%%C||<Çw5edd ,, &M{{{̞=[kD"Add$BBBb ⥗^Rojh"ܽ{Ç~Vƒp},^:&&&P*8wpe$&&jԡ8'''|w Ell,N:aÆ_}}}w^8w\}Xkp[o}O<7xn/sƝ;wk.kJ%:ޗ'L2k֬wy]zt}v۷W\իWdD"ik׮a޼y8s ];v ??_zw/HNN]}a|ȨV{i:u|:tF`\@cK' pBl޼>qH K<ԣK??}֖.z].eo߾Jf͚il'戈YXX^.?5v.1fffJRd|0`~w֭ 88/Bu PUVa۷/-[9s_xѮ];̙3yyy:CVVzއ߿?^{ /.4ǎ:i8y3&HpڵtI%'nhՇ Ǝ kkkd2aݻ'NĺupBC}…7nϟ pwwרCz-c….ocX~=<==u/]_...pN}bǎW O{ Tz-ʕ+z3g ??/6x{{&LX,ƀp᧖@ @ffz]npUB͛7XUgφ@ [˗/c֭{.N>ѥ/"Zhٳ'\]]~E?8rHʔx7o>׻ܪU+믿Vևhڴ)6mڤwUgUž~=tyBxtѣG̙3@hh(FLb֥zѥ]G""""ƪ&B!1{l<|Yfؿ?w!$$fP+ЦMlذ055E6,YT?cԩZO?EHHR)](>@np]޽sU__عs'T*ܹÇ7лLUvލtrr€{?HKK:;iN8|D᧟~B||erss駟شi=z}7e'%DZIDATpY߿?5~UR2 0-Z8^~n߾=Oܹ_~z>Ǵ>,#pB/ZBJuXuY{mW]k6^ƣKa8w/>1k|Y\W6US[?ԣkBDDDDX:}yzz"11Bׯ_ǒ%K4?9ݻwѩS'~+X[[cȑx饗sHHe˖i}ŸsNFѳgO&Lᅬ^{M:3&&FǺJ`` 1qD|0aRRRp…j>J) ^oݺv킇}]HNNVojRT/gff`mm {{{ܻwO=)) YYYe]j1|ػw/3gBRO?ivHHHxjC3+;C ԩS#@Y~SرcDGbb"*bzt!C'Oƚ5k0~xDGG_7oN1`?uƏW_}o>|=z믿Fvv6N>SX~=}]+-_t:ݻ!5^Ӫȑ#Ѽyszo}x^Umکׅ>^U???XYY/|,ZyHIIQ/WUOmS:-DDDDDUKL'%%aڴiP(HII0X"5@uG^^vd2X[[fΜǏWS~~F:@Y{{gI&UO@'iy2KT*xWcҤIسgOAWM6ERR'MuU}}edd <<DصkB>*8,SRRUɤyqqV٧՗^z ׯ_GFF2227`۶m>|85k 6+ڇ}[nmӑT*J.''ePzyyi$ҥ }` Brr2Q6}toFbIpqqS_0drrr20rHbJKKæM*=[O?ɓ+ 22Rk͛7ѫW/|}} }P(({lR{_ ~cnn\kkkkmvo7oĕ+W0x`T3g"##qu  6h|1X_Hj 6lxV{,j{߁nqk[Uv}]<.TUF(bXvq믿LV̺S?SUBDDDDԘջtUn݊cҤIhٲ%.\.]h{Ukx"rssbf̘1 ,@֭Y߿C=СC̜9S}!2!!!A۶m!0{lhUviV0e :۷o׻ PkРAԩ)))8}4/_@`.ӴiSx{{yJVOP۷ǘ1c~dffjk4ٸw^j?JM6a޼y8ŶmoiӦ xΔjD 6b ٳ|AUJJJl֪Uԭ[7_WU`Ҁ4i$jRxx{͜9RǎW;={Ԕ)S`j׮]={6mjL>}.]})!!AڹsL_jϞ=2Zvo'NsNC*))IGΝ;zUΝ;kΜ9:w\e"##'VϞ=ںu222yfOIIIKXo>EFF*22R;v쨰N]vշ~(uE_}֮]-[H^x=#9r>W_} _=:~nv|N墣GyD1110aS}?9vXK:pZj_~ET:ǤI4{2un߾>3zqqvء_k֭^u 6L۷oW Իwo~wwW^ _~eM>])))ڲe֯_K*33^fҥN|0`{xb+>>^EEEjԨNѣ3g$iƍ:|{7n.]؇9rHr?~,ݫaÆ9ǝc{o۶VZ:}I&GQVVn~M4QAA֬Y|effjNe.U<6mڤh)99Y?6lؠN:ԩSGVXdڵK͛7u]g/7(,, ~)ױTNIRZԠAt,}̙3{lk׮KzǏܹs "׾b 9sF7o5dEDD8;Wi4,ݰayG۷o_>H111z7?A{VJJ.577WWV߾}%dɒj-`0TzLU+:rURRRslBnO)77WZrz^zʺ~)_ѣGkתA2}p]0jl6{FhڴiJLLTFFդI2.^Xj۶ZhqE\eeeumWڽ{4irQSxrUXXXa/;v8=ld2CJNN.SVZjԨBBB.ڋսޫ:uCNe\ .\{N;vT˖-{L$b(==]ݺuhT``Ə4ʕ+eXTZZg}g}V}QӦMtRf͚5K111jҤ}OԻwo+((H}3gTttF-ZhҤI hСںuw~Q~+..N͛7׍7ި'xBEs:wVի?Igַ~8MQÆ kk…:{//jРA0`d6j*uUc*~뭷4`M4I=z~^3''G#GԱc|}NϞ=5e-X@ڵkfϞMj|ZOKj߾}JHHP||vi/ӡC}ڳgf֮]GFFĉܹӹݻwd2I7o TP'Oւ oj׮]ڳgƍTd2魷w^5JIIIz=M:UwVzzV\>})7j([͠AZJfYɊRZnݺzO<C Qbb{=jرѓO>uO>]_~} /ūVtvv:w DFF*!!A]wݥٳg>P$Iڼyt\߾}tRKۧHo߾:uUPTT #Gcǎ/y9R>ڶm{QC믿VVִit7;Vxxy{eSq}ͱc꥗^R5tP/Udd"##W^yž~|ezqqvQ=-OݵuVjJO=FX.M _~eo^)))׿aÆnp*tR}GuQ}JII=c/xb $5jHwy,Yq=9sbhƍ:|k̙Z|8qh?jܸa9rD|>r?~ݫ3g꧟~r;&88XǏΝ;m۶)--ͭVZ:}M6R <~٬9sjj׮]oOpiU*i&EGG+..Nzᇵau^N:z״b %''k׮]j޼:{oFaaa0EO=:uHjժ (%%žɓ:sǯsl6W9CdXgΜcSTT]v]{<?~\Ν#GYw[KcuݻդIKٓ {Aر!&I:tPrrrjRFRn6pUV:|KS SǎղeK/IX,JOOWnd4; earJY,;S}}YGM6?=tRf͚5K111jҤ}OԻwo+((H}3gTttF-ZhҤI ՜9sʜgСںuw^zy7kL =ܣ/'KSիWOfϞoVqqq-[L;wTff =:OAA맽{jƌJHHرcuqqׄ Tn]m߾]z֬Y1chZbڵkAyfݺu ʕ+ꫯwѲe|^4IARiXmpf[78ۦ sӅeۼv.]O:Ue|}d2>|/_T ӧOWhh.yy/p LDDHʑT"anlqm]qԩ֯_B 矵~z_W{j5GugyF7n͛պuk 0@5 _AiWL`U&_W튚L:v$HZf}]35?TӦMSll+::Z˖-Sݺu}]-]0}i?}Qկ__C 7 1b~fmذAw:ɓ`ڵk٣qƕy~X֭ѣG^FceWuzYm۶Mݺuo{5fѣ-Zӧ}NvUPTT #GcǎO<&NiӦ鮻R||gyח Z%ԩSŋpB>|XSNΝ;5x`=9sbhƍ:|1chԩZdf֮]?X%@Vm~X"`_5|2)))jݺ6ۃmTNIRxx"##xrd֪}0} 7ĉN۬VӺ`(uVq˗RW~zt~NZj#G}ެ,effꮻ%UW-N#Gԙ3g'?͛7kӟ(ou&O'ɓZlԥKկ__&Mmj#FÕ5khʔ)ζ7o4hqƩA21bo̝;W>|ƌ|j֬YP$9,K{ )ta6ݥKSNUY<_UY&""B]$H*T0\X8LVɶ.urcPL`U"x4^E0 *iWL`U"x4^E0 *iWL`U"x4^E0 *iWL`U"x4^E0 *iWL`U"x4^E0 *iWL`U"x4^E0 *iWL`U"x4^E0 *iWL`U"x4^E0 *iWL`U>|]fC&`:00Uk?d>M&_d2} $) @EEE*))uu7'Ts_n Pk 4^E0 *iWL`U"xp`L~U-R\\s)??ߣhGmO6o\5n饀%W3ujKңb`1KJfU[V-7Y|];+9 @kv L&TZ xOM?y6*P {ոސ%x寷4H \a/|bǁ4X}]%ʃ?3L]vh>DmPWX׫,G( xWcKA wGL&BCC+O| '&j?N( @@++[L( BcA>}L 56H| '&*k5n׬_BigHmڴQbb^~e}&LP^4`f_WL&=ܹ6mӧOk߾}9s222|]=VF =CUÆ UXXt-X@ PckٲfΜ)I;w>#_&ZdPE5a_EiYŚm>|9Ơ 灺ܤ,)a JIR@P*˓V_WW zLI.]ԵkW_WP}:t6lT{ٳuw5->>^?]ڽ{Ξ=֭[+,,U z-ժϫGE@9[VE5wV7ָmSf#N?}FeZD]SFz."ŢѣGk۶m:$`0Z57o5kh„ ***`W^yETQQ \s"""ԻwogQqq=lcAw}ݫluU͚5SZZoPmM>Gdze4zo~Ѩ{Osl٢dG񒤵kJڷo/IjժvIF[ח F)00P{Unnnׯ$r-mqqqjܸo߮nIڵkWey衇#G~zԦM_ /)''G 6Ԃ 4zhvmNeJJJԹsg9rD կ_?Iʕu~LNݻwn?={J6nܨDIRo6k ӢEqF>}o6nIl*IqУc5E .@/4~5V͍a nBkʩLKTS3}>^{UΝlm!tTTdZlnذח HIRvvv333%I 4o;v옞yk2e$U[ӧOkz5|I}YAA^z%^zz5k,gΜ<_~Y?W^yERi0&IVjUttrzZJ:urW+kcFQw}222taeeej֬5j$IjҤ :%Kh[ %_7isjhޖF 4oN׎?'Jݻkܹڶm2228p@f͢3P{ TXlZ*W͕s[$˅T:6uMޥTs]jp}OOg+<.esIٵ !fj2bB;{s^t7(ה)S4w\=ZGo_$I~+clڵkϪM6jժ.\_~Eqqqjժ5j3ff6eZբE zUүB?ޭv몄\nKNNVrr+}`P˖-5e߿_&LЩSh"cW\֭[]vܹ;y?=iX^$I֭Ӿ=zhܹ?nݺ)&&Fw}&NC*55׷KxvչYWb4礭9i6Gw~oxd0CgWi0طJ`)/5%I%<W'>FD~'͞=[L:$Ij۶=C'[OKpT``$I2dޜ*NzWVCJKKq)ya-~N*2J?ζae4!5kbGjӦV*} 6f4գG讻R׮]SffZhFY,YF&LЂ d0ԴiSIRLL}ցk wp?-v}.$A&CjuGTi}ƒ{N֢!Txlo.<|^pR֫#cHUuZzlzLBsUll6lh߶gm޼Y:uҌ3n:5iD6m$)==]ҥRSS{*''GJOOl~oƌj۶:uŋ+55U~M4IE DDD?׾}ԭ[7hJOOL˖-+;;[fY&`ŋK*W{1]wuٞ~AwF=4s[jOm]vWV\Y&޺uxCiii_M6)??_eXo>]z%~h\PPഞ[TOH:_o3jRߤoбД˭V6j*:}Fe0t]҇ſRN흷tvzήݠ_P;۩9qGE?ǡt(o[s__:=Q"MV64X,uZRF-|] xUytieWʓnxk^em OM?UJukVel#+~>ܹspM >ߢ} #}]=UY` fCy0OG_~';O?6TU<%(9sPRprzmѪ&`ZrrrbTY xOM?6 A%Qe o28$\ &U\d09.ۦF=PPPPjjUAAVFFˁ7Innh} 'fa |#1}} UA~_7N0K Tj3Z`gf33 :vؗ UB6I2tǹ?֦ ^תiu۲ .X,&ݾA~ >EmORthdr_W$r@Rπ u1!MTt5jxF:vIE69f.o*.ʂimURi(mtf9yш5kv,**bL&ծ][EEEvܹDRh[8]ރmZ1vfp9~cX233]vwժ"|/44SzΝ_4v!8δcia<*}aymN/i '6'O1 ԩ\fیbV!>KFZj) 'N?p6I*ܦa<+#486y(9v .laݶ-PRPFw h4*)o\#N[,?>}zӱc*}a~ m=<ƴm8Tvi^նmdu +{kXRƖ`lr\:dҸƶ69v].*ohʩe.me-m!)V7(8v ]p !]kH<5e[ zB[RnPa5 '.ǀq ׇ7cl\j(hr(lp8Qe{Hs|[j[%%a>1 WFqU6T2U64T~ mv i[:k%m]{L|{HaeCzZ;/Nn+Al7kfC% .PCױ۵W(;#Gls1t}cOgǞV9 Z;cZ"˥`uhK9]v(U<[cKzLۖR= ;n77Vpגk.k`l)g5Z1+--7ƴpEK-.{MUCUrRzU9衇ҕ2uT~`mu)z9_zU'hT,;.4WRW*1]^8:k mn|=]pQ^\C +Zy*I|kr ^k ʪᆕ=аPZS&t.+Zv _ECp^і*i~1-U[Zy]okEGE.Tr]j(mcڶ^rU=+:^ϸ5F9M})}5mjc ])lWKu^HWܓ`}\wlyeWe+*SY eiOب,teWyATu`}1+_J8NOƐ&Ý q;EҒ ֫*gu\UcO"H{r>Ɖ.o'++K/izOWճyC/g@]ƚv_ղl(p2Uϝ฼}nҒ%tw9fOChBkp4$TPsUa63\YUjv'v|%`|iƙ.|y˕+'}T̓їr[βȀ!eXIfII* 5(1 2iHHGIMP 2.10.242022:01:28 19:36:276< JFIFC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?+м:_]q څV$LT=oxj81JP3Fƕwqs` gZb0DQFj=>Q]_`1"GGu4VS"qդ"%>6j`} OKypZ3ZFhʁ~@ie#0Ĩd9t Hy_sQp VA8p~Qӹ7o~UV?|P?*>?kʏ?*EZ|ʪ@?|P?*>?kʏ?*EZ|ʪ@?|PysAfU#T((?_γJi-mFX~4bode. n3?^0>~Qz~u ;=\3i~P8_طFyʀ"ܰqUػ]ݺhQEQEQEQEQEQEQEQEQE%x?~<u +Z,OSֲk^el?xր./!Eܼ 1չ.mͱ2 1ҫhC3E#I$ NN5t밗̇0؀/F"kT1OeFlq[]ˆI0mSo<6!ī:v>bw*I:EgQ\Y{IZB43\luZOP0HϡPt?y#>۟%eڛ[n>q}2-ۻ!JW$̆H' ECE((@QEQEQEQEQEQEQEQEQE%x?~<u +^x8;ײ}>3Ҁ.Jk)AnHbxr*uYEI#!Qb@usD3mD\g?£Le˕-OdPUGy6&69zXuI# m !P>\uTak)a'҈l.ci|o(v9U^FIS6L;F\ cqTdMV1@Ȫ~̄y>- |*b֬$nN*E`E@ŋ.;w5GVe{S'AW)'<Fi` s.̜Z]TZs9zqF0]Rlg'>1޴4Ȧ"ıpF+x(Έ"aQ[On9 T=5rieQWŮu>ݠjAeɾH9`x.G4]ʔT K&2>]E0њ@Q3@fE4QFhQ(.QP??FPZ?v9ǧֲ+Z˄TDTKx9~TsQJ.f[ױ;Sc=~ifʕ֛ }j6(*dJW]̸v_FZBi>~өA},e 1@68ҪykFgYj1\/K=_4ڌ{W%K=_4yWuyWmY/!aB xa ~d%p0*|^T4Ǒ|n\SZT޲FI3zGƲMj}(';f{UI|#D,D^Iֳu=3RVbl&(wcڹ/:_ѣΗzhǵZ\u$j!1'SyWt@vO˳WZ[AlԹWqp=}dg;#T*x?VYcXǁz5u;!=+KƷ3O#쌇b%yyH`;?of 'xVRXL-qҞu{ VH]V&8ȉ2ˌ|8=NQ77/*Mpg?(7z@GZK]&a m>dE5ģgݎ0qTOu"(`1zI%dfJoZ>ɵK9B  28ךO&LK 9n{g\zW3*Cw8y)&.gkftu6zЊv鄥kN])2ےBsQ}s2ȲJJ` 5Mvy~_f{p;u '&l95f(D*z*z$6l[< ?Ҫ*3Vcjqº\MlwQ)%rz/ߚ&`AupF?PqMYw8M)!p2y$1RJQʷuPqN.̊h'GRqOH@qԒt1V"Q/JEޥg@QP??FPZ@ـ2K6/NZC)f8Ǩ$}A\:t.#5(C42 8R3%Ķ!fu9 t:;ܝJb?R ě8prqI}tMFrZO$&CG\}Fdh(]>hp!R\U>9ǶiSc 1N'jiBڝPR?pmjhMw2yۆzVu)Z5Т*IT ?vpڟ7P5`Go#n+UM:W700)!XCTnI)FWڬq#lv={r?w¶Дr>"0cb2=*\i#IAyݝXM79k$000do )B?Tj7}g zZ*PW`z԰*.,? W??FU#T(k/g1?VMk؜->cڀ6-3W8.=0z )2xg*铃pzVڮcsctàzf͢kP.W$u [HpR9Kl}wz_QOnʊNRH@UQTbaB۳=?Opx| z'MNӚƢn`(+&y Q(FQEHQ@*z*zдO1A#]NpFq/C|.@$a7? -eu~[(?UJy-gY :%C@eu~[(?T4]p1qQC|.9M†`:~ HD_?<Ο<>LqHBTd@z]ߖ wvy+6?R-eu~[(?S--ct+ȭZ@-eu~[*Io<sT0c#=jX?~Ws^LesQT~@I€-\ǀWQPr3Ǧ=}յw0@M2فsq\{U\E8~T8sQY2^<\ MCuj$漞$}(:w >hohoKBݺS}}CEM4ThohoBy>ξ}Kh:/jG@ξhohoR:>ξ}Kh:/jG@ξhohoR:rB3VZ>Z<u лmYV}V+G-"DŽf b/c^W['HH 2a>@fup䜁Xo 8­Ż)uU@:\L8>lqU+p?b ޿WX*T3MM*ɮ 6b*eHAڱh m=!gX͹2m+OHKfY3ұ( i>5/p:R N.GŐ`}soVt?|Au味9q昚^avlgQ&@?5EoCiCeH ,LyA84NdjԞzqWGdV!dT 0޿?E;z(7@޿?<iPz(m<h޿?E;z(7@޿?<iPW1U1ei^ǐ͠mm~c͍f!^cq7#9OC@TV44SnD8ea G?gQZ 'qK?gQ]asmm4+5UҊVr8 EhfHhe~(>Ү+Av-kr\rI:m4*f3 }Bq%`HUp ?4Et- MB֗1sOYكzPuG.OjoK V5sv]~Y4gRգNq>ۗ_G]w ?|Ǜ>1QW^%iF+TstV7jş/m\&@ש/mZWpW]xRAי _ҠeX9#Y}M09 aU8S)MY MVKHDj՟E2 ~o~+"ߛ ??²( aJ3K7?QEl\(H%wpHOs?²( 0#d@sGGVE7?QzVȪQT07'v-%tEXtdate:create2022-01-31T04:06:48+00:00r޿s%tEXtdate:modify2022-01-31T04:06:48+00:00tEXtexif:BitsPerSample8, 8, 8>'tEXtexif:ColorSpace1I!tEXtexif:DateTime2022:01:28 19:36:27-0tEXtexif:ExifOffset190LtEXtexif:ImageLength13334tEXtexif:ImageWidth1524$UztEXtexif:SoftwareGIMP 2.10.24}B$tEXtexif:thumbnail:BitsPerSample8, 8, 8 StEXtexif:thumbnail:Compression6epWtEXtexif:thumbnail:ImageLength223o[RKtEXtexif:thumbnail:ImageWidth256(tEXtexif:thumbnail:JPEGInterchangeFormat316[R/tEXtexif:thumbnail:JPEGInterchangeFormatLength8334i#*tEXtexif:thumbnail:PhotometricInterpretation6 tEXtexif:thumbnail:SamplesPerPixel3ZtEXticc:copyrightPublic Domain1["tEXticc:descriptionGIMP built-in sRGBLgAtEXticc:manufacturerGIMPLtEXticc:modelsRGB[`ICIENDB`lxi-tools-2.7/images/lxi-gui-script.png000066400000000000000000003442501447016333500201650ustar00rootroot00000000000000PNG  IHDR4+gAMA a cHRMz&u0`:pQ<bKGDtIME RIDATxwxUnz@:RB/R6DO^cNJʫ6"$BJz2!KB 乯kݝ93̙d=g(¥Q.z|u4B!BLW-\Z(\Zir.5B!BFuM媛_$ %J /e9!B!hjKK\2%FI2B!7^J2y hu銪2ߒJV!B!tWk"iQk-&Uij!B!DCV\]-M$kM"kJ kW[ٚKkB!BԝjV@]M-M5̷QB!B4ucm-72Jk9$SUnv}B!B%2ڒ++%U%wjVj(SUXSY+B! ]m-%5%U݋&uM-mB!Bq-uM$DO,FMcu -)B!U)ѫj^U&e'}U%pc4 0 LU $BQ;'''k )((vB4& @II :mRRvJFR?s[ʒX5'U%Z{899 /((@[΅Bq" Wh`0'811q 5'_ߨRsYFKX]ղG]4\/nm ͭbG:=/ ]ZQҊL}I!udL2URR³>֭[b1~/_! !cŸm۶_tt.z%ejuhʷ@VuG._ue #)tiE\iIk"U1G}_~aҥޅ?gdd/r9kt\brt:yNvi]ṻs=0h ())ɓYe˖#p7#fpo8U]SKe.F#\DT.pe[˳Ȫ6pNu[F[>^>CЕ]պuk,ZEhjQ~St҅f͚ѻwozm.swҿk O>̙3'?vڱ}vk|Cɓ'[;D!Lbgg :z֔7&UUє<iр:'U S~U%7VհBQ$ Ux_XXțoɚ5k)¨QxWppp0v7`Ν-۷o$22[[[z DUUz-IujqttoF[[[(**&mSUS86啟ְKsY.^`:Nq\UU={6bl߾~vѵkWok}2d/B̙cu]'771 $ˊs*MZoXC{B !!-׮CG}{ oqF>LppCٓ-[ri>*G[-,,ge=?|k~C۸q#7nvtaGG*/] ^tqV6kټ#^\A-)@m}mB˦ppp`Ÿ[Lff&zyݻM㏛iӦj*Μ9CXX$WAHHk֬ԙ3g'$$`veohյ@Ι3Rke%Ee0L'1U|XyÜZ2 Etld"Ng] s-ecc3fKMMeŊ̛7)բhxG9z(gϞh;;;M& V\\ jZXQ .%%%A(grrr骪VjLJJrjkZj&...˺ObjJ Ҋ(-jVLVÀD5@N6|NC*_|Ut*א֩}[lmmWXvb޽tMٳ eĕ ToQlF*,#R\:kt1W/Mi䱩G0=N2 L+5I3(t{&k]tcǎ U)$++`#;;;6lv7H\\ӧOgʶm0Lhт~W1b~m\^7vE\9r e\ݵZ9GcRkw91]]A]kFa^ա`TI3@6šTU5wYx1 """|ҡClnb,-W ~)3fܹs('WÞ={8u-Z`̙|'oX| s\)> K\ .eS}R-k8W5&EQ3g6mb9 /T]RcPWm<,Uף A: &]:Nf!4ЦBNc}hd7Ӿʎ#]#~.3gWds4ɀVsnqex[;ZyiH_7Lȓi%P|)AtO3oW>U˗Fhh(QQQ̟?pssϧe˖eo8&S?GQtرc+*{Fx ;&OLfDZcǰW^sk 5zeccsͭےKkK.DLqFz)lllҞ"f⫯z<zkRVZ:Â8xVOVUQ)66GwSWP!ntI^#-#ݓnQގi-V)(Q1T]xeXűYE&mL厷BnJKOw#6bB_?l Peә7oÿo 6UBCC 5OKK0_UU֭[gohV3]}uӮ#Izڑϓxi3Ot">ْOXB~nZ:QlT17$r;y# 10l+_g-~.&GĜ_M*o:;J*9kyj3*˲+R:NѰV?Ű ;nh/ d _k+[nx~ ϥsNnV^ DӦMİf,Y"k_a6lছnO>~4 ܹSZ)E5WrK]Ӛ5kPYf0wJ]ZZr*^ilLȄNŁ:;؟Y68>SqfZEUyg+OuBjUBlpUH7 &;]&{Zϰ ;|֮kZUdV!|||A[C\仐\ dq%+ar&y0= v}hqz϶c,׿4@hR=r&ċ+s-V|W֭XtMcAB!tZ.z5$4HKO-NS|>yx~Nt/7-D=շ$*<8@3w-%*2SSSy[L׮]N!j,..銭Jt9I핈IUU^|*իWf͚oq13EvYhʽV?4.{h?ο.{v0`ΜJ[<4_k їO>C=tI~2nc8p0Vc~znzojСo|u}kەK^"rss%zՕ[ـ0{6m*P?ʿܴ\o5k޼yuCϷ~kEh2e ֭c޽_ :{{{UVw^_^7n9p{aڴiдiS/l]ښ7o?N˖--^& k5j?î]طo+W駟k{.^/GWvQI&rJ~GgFZojܸ13f̠se@\s딘>Kze:r6q߿?ӧOСC,ZVZFfȐ!aqQ6oLhh(< kYfu]9rڡ\25jāشiݺu{%!!?ZՋ|G?HVVGGGsZ. qi] h$77zY_nn.FQb 1A~,OZ ׅ&M( w//} 4[2e>#f͚of^6::~ٳgc0%Yd {ejՊ;vQ-[ݻ?>M6vzVXh۶m#,,o???裏ؽ{7[n38k,iԨCe޽o͛Wدwy\3"66+WVYz8TYZ?`׮]ܹ>0~75k=-",,-[sϡji֬YFΝ;c+6Jⵢݿ? ,wѣݛrJkO믿Xb#Gsά^ѣGӼysoz-q- /fo] PQQ|$S}Rq]ضmL6˗s=`kkKjlذ#9;;ӢE ƍVmAUW̙3_|+ 88;w_rQZjoAdd$1M6矧uUNwwwUVӣGL!CӧOK/QRRb~`„ /2?n:\]]i߾=QQQJ`` {aٲetڕ_|}_>#?n] TAAe]#[]2%纼9s 'Ndĉ7gymZ,9#G*111<~8|ݻ|]aXX+}݇-Æ cСt:TU%44e_|w1b͛7gժUL& Att4:u`,_#GҼysBCCO?e߾}0qDs'srJkWeYf K,M6̜9{}թ^Wq^˯c˖- >h ?^^^׏]P___Ν;W(OQQSN%;;z%&&2}tƎˈ#xiժW_ )q ;x / >€AGiŵ^QPPpźcJLW$BFzz:_5?-_~$dUBڵEq9N8dx4DUSAjhPU772dH/PNGxx8SL{g%$$EU*jÚV\~׫d8q"͛7СCuײXVOk˗{ׯ/666۵#'N ((￟9s8,"##~ŋҳgO?S5)(zuqc(֯;;;lll*2L z=W%!@:䞤Х{!qՋɓ's1&66A?>Ȳe8{,7o.\3={`4yqtt{h4GvzUtciժUnz充a05k[ne̘1rlll0LL0:tvcmӦ wq:tߟk-}Yt-( иqcYd m۶;YU{Ep=$$$p!L&&Իwo\\\ ...;wyU'={63f`ʔ)=z~ɓ'矙8q"۷?H^Ozz:zgϞdff?0w\TQQQGK-\:O( Ν#==eTU?w<3ٳ6vvvx{{ӭ[7F#|ל\!B!d2_k4N$B!Bq 1Lx{{Aff&iiiLymD!B!ãBH!B!R!B!E$B!BaI B!BXDH!B!i0puu%44FFDDׯvXB!Bqh0-:BCVVB!BNI 322زe zk#B!ם@ !B!<@ !B!HD Nqo&? RFH)#e(#Bؕ{ JierϺ˞ݺw3;;Ү+ &M"%%FastUK 2RFTQF!ug2 2A)<]nnn߿?ܳkSZQr^K)B!גk9l0]X5 h4t:`0̴vxB!Bqk0 =&MBI֭IOO~d2]B!`Ȃ k!B!-B!BH)B!"@ !B!$B!B!," B!B4QXo4߁_·gӒ.k^͹[{ !B!j`:ЩS'jk.N>m.dz0?e<-0?סk^GvxB!v (lْ8V\ɲe((([o]3 YpqE!Bq j-bŊ ә:u*X;+BgcmӖUEgO #8kLUǿ Fd`ܑuÔGz' $@Q4t$}͏8Z-)c EcL>/Ey$ºߟd2X!Bqi d;ӡ( yyy1YL#"W~ < @٣|KQ4 ksذpq{: 6Z\n׈Xc$ ɵaB!`>}ELLCrٸ)n%N.t9?KqQUEh>-"lGЩd6ZTRJ 8}| Ņ$r&B!7@Ջ͛dz} 4@UM5Q\j:yt{-/gI={spnߛs4iEj2Z؈5 ~/񭤞=Lg'Y0q] !kp d>}С˖-#33GY@\:h^K*s5t5 h(q`Oj"~-KZtVgdžEOsd珸b5] 6]ZXQz eg#(.al?zSaǃ-L=rx5nFxΤs߇qr%;=?؞[R}hnG<_lHaﺏ>ڇL!BjL&cbbhJek]͍ـ0{6m*P=S}놑@ !B!ZN LV!B!GH!B!R!B!E$B!BaI B!BXDH@PLC&̚ɬL}֧+ 4ڻv\n9gԋ/!B+$!!!w}<<L8-ZX;ko@2SO`XN7"{egxYeYd/F7 1r9 %_8q5>V5OŻqGlB!55ȑ#ާҶm[|ݤ y߷;s ".NFrLݒs%Bq4NttFCrrñ:ghiVM_23oF5ٵ=vzǿKU5UX%eܼZ`g_A ӹvg^L&qS''=_A_*nҁIDԾE]0Tz Sa>4B#En\nz?O};UV9yl3S~E_RpIA-g{'On7,zw|FUMdrjݒۧ/ټy|3楑}GВnQOf LVI%Ͽhu4k3,ght%drj!zz(6,HVZ,RR[)k=-8ˮ Mxo@0%Ea N}TirB!@fff`h߾= "33t2h:ǽ & ͟dV2߀.'FUh]kCfʉ ׇiu6x5jGDدծ2]HOv)4[{gT /9QsJ7s/J*/rDxEC/{t5I\rFBH9^ma깣<C gr"*98yքsG?_hiz}!?LQAҮǝ9hXu9^ձwelXԅsNQhlH=suա%a|8ghmnґ[UXϩ5t.E7:!B\@Fsĉѣk֬x{(Nu\3Τ Eٿ~WW 6vΤvu59c\6FFry4Ld&ҸEOZtN-}J &-{4h:_,)\!yl? @qav< ܱ*o];-Rn4*%ճޤx7DzbFWZXq<|lIO2Ouӷ57~V::#GҮ];7nL@@C ח'NX;<*E2\ݸ#j"-b+գ):*IGSiiݸ# Ύ@Ӡ85ƷiWyĸ}^Ժ$'S^?RaZt'LY\Фecը>ag%t@ &-eOzLѣֲ^yD5n-v13?ڻrE˩kvʶc+B!Dm<4jԈP7n$''b Z%CU~Nr,jvL~~( ӪhmCn#"lA-hmx0mVWs7>M:SfA`]0OXǓDܡWy:Qt:JUKaw[w*Fę9+ްh[%l?- d$|Q.Z\˶\skݜj^KGi,Nw "ՏѯҢڻ{t(z Ip߇qt(/[Xu!BԬA$=z4r:dN('}1{3ұ}DJѯq`_L\p|3;}4ư /Mo1NߘXp&'CqoE3Y|;q$oqw5c^e_p6v7n^|瘌zBِA=ya2'[H>h4:u0]Iߏ1@ޞÆHCP |Wg:>X`:16Jqavm{acrRvxӜ =O~~aw %jb,}759vUL%+-[^+1$QHEŷi7bU5悼TxE]=Eڹch `*%,=W/e1ʟAƳ)wk{Ӷr3N6ƛHEЦN^a>ԏ3M_NIQ 9kڵBK=}Sa86Yr>!1Vޞ? _~tUӯ O~j\cL{W GRKDsp#j"nyܼї䓟Fݻw|.Ti"hҲw~\ғݦVg˘)`c@zK2/; Z]CI6v:wt'Qs s괍}&t rT3/)Ǜl~YsZs?;5эsi$y[GW[4mݟSҺ8r2NNuLf /kc#2 &Ƿz0]φB!j Hш^'33\<==Q2b"A^K*c,,Ɓ=9V/Ep?gTs;U()mmhuۡ]:Ryg1 ii$Id$GhixYi_iל*z Wf cR&'#]3))ǷiZc/iv0IK<8޷Y]k8W+CS~˶ 86&6sh%)x[On~ӛhؓΡc,~xg.΄BQAta5LVa ub[\EFr 1dĠ/)2BQ,b4ѩ64>\n(.2w+OhM:vB+^cW֭T hߢ9ٴuh4O$>PL깣CV Td$+>UJ_oSω [Yi~W>QY!f'O\i=C )gѼP<9GII<]oUTLI ؛Jկʲ՝_WS4 qnafc焓˅x[JvƁ7ז93x\9\}7苉U:ѤE˪3!BT HUU9r-ZK.ҡCfgӯf쭃ҩm ؼy{߀.Efi(ֆ^#^ɭnFgƄ~Wf~:±= *&JR_\}_m.!d ܼL~S3J6q~5m9Vd$3$n-H @b>}Z\ d2plHېplJ4iѓݿ^q3Y`M:sL= :1g3VQ4k s>Ν 7lĹSaT9 '/t6v_Wߒ_( {WuYùZu?;1{H.?lle겭 w~DڹdԹnNMNF<MZٽ ҩuuqt7FprkDQ )'B!g悫tH^^vѣ+ի9gSi9ݛplл>aH>}K hݗ}FP\͚_g2H 9qΞuI$Doу/좤(oarçIGzr%Z=mȮ2 y}Ii"8m~_FR4&3@u&<+mac@qoKvz$.remtpz\Μ阭t퇙t6Raǃ-n [vNF#'4Zĸ=l쉋\\O}HN8 Xl1Ft%_4m3g 7㇖zyMjU>;W= ˱t[%y:c_T<-<~=ѯ2f/ڹs8vfz9úg\yBLʽVIܴJegenݻwߙ]kiii֮a}|C3#l^6#B2LĠєuy777 dFPtC-({OeN 7 W4 - t4HBfk&B!np@ qjl:q)RnЄB! NHaտ>fy'a"qUgG!71 B!B' B!BH)B!" HV˴i*nll,CB!Bk^H F#3n8bbb.cB!Bp4 --]RRRɓ'B!B\5Ν;EIIB!BBL 5kE!B! 2 ܹsdffZ;!B!n4Ãf͚qTUv8B!Bqhp dN(,,ԩSE!B!+ *}DFFb0B!B\WT #B!ѣ=za!B!uA@ !B!t@ !B!$B!B!," B!BH)B!"@ a!W}m۶^46mʰa(..&<VgWi_$n,]%c NL&4&EsGBKPQ4:KQ^ Ƿ'0 uΡ{s_8>Waw[w*Fę9+ޠq6m ћhv06}o@0Mwç^۾xT?B! d"((>&&CooZwssc@6` M_=ʷF RUUΜ9C۶mqww'++ƍFXXëDfT<t= g( >jP-foه /!!zSt5c^e_p6v7n^|瘌z[;gnF0\Ѭ:W;7?.Nfr ͺR\X6L#jbΝC1~LN~`/0,:U[!Bk $]jlٲ'OZ;JgN]Uc#j",/iqzO e&o*_nhmi,Kޅsp<:>ľ c2he^f0?[-R[=z`()-fLʙK>ٰuˤ Ԟ:-o2ZoFCXt;yRjqd-Q#B!_I ;t@֭Yr%ӯ_?x=!ܛO">jC\.Fw Գ>K^IQ.Iїj2b20K5=[A[B!A$:}~N8`N"wΉ',5b"KTU:{IejeճY=Հ%VCEUԱU,֍}ZJIښĵDqA1d$ǐd2fm`Yed$+>EWdkZAn*yى_c3xڨr**&ՈF{y_ԴY?ua]㏹ñuI^?t6 Q8iwKY_ԏB!@p9uF`` oߞ֭[s)L&obR̸)Ѵ@tCIPd۳=&66\=2xMZ$bɨg߆B+t7>^4;79 4i g&J>TXj2@`qpBgcTi=W~,պ8Wv85}(̔^?  /siqTmei!Bi]XUUeժU׏#F`ggG~~>&GaI/Ggrs&'=49;ll7M\|Nc™Ex }q>!Wїv.C˔~1S~΅̔vs0 cy+ FWxXzEal?B!Bq !B!|@ !B!$B!B!," B!BH)B!"@^V˲ex衇-[dڵ4jڡQIHwaCIL>ڡ^1G׮]YbE!qH @-tc[:l'H) 3f`ժU$%%UA2uT6ȏ~Ǹ k،W;JG+3άo;o6uX1:S7ƀ¤f|2\a#<+9QsؒNmI<=n)\IOf?IT2etQT:?ڧ׽( #FϏSN1f<==lْP/_~I;hH-N8|a^鷱wsϟ r z,/c9y6 `ܱ ҄T°-l;nX_gעtfE\~CbnӦ #553g4R Ǽ+,\;3ӢEz/sK^V۫w}dwn yj3 eC/9Qs̉/i/yI}a1`V%2גϩeKʒ%Kpvv{)nsz賑$Dof_Ӣ{kslY2?3)*ȼEaȝu[o dGAn ε.X1>o`0#;/$A:<@ϟYCNʟ)MG73O8{~}bw3 S2-=y2Rb}؅a4֖8saϞ=СCcgg /mؼy3>(T(h2e Wf޽[~V[C=ĪUػw/˖-cԨQV#_?}%EHq\L faa$n}QaM|F_ڻt}Gh[ԩ mif']'q1zE8f]'%&F4}e5.+ȑ#'>>/:7ĢӋ7Wsw?:aaqsO{0F&Mؐ]默uhk<bG8ҶOq?.=䊆nؒ)I.Jfə%;^VAajJ7p"EF>'[K X>‘#DFC#Ghڞ\}.+W\\ue}nw96 cx[h NnH5ޚZ;\z}믳w^:ҥKJl8q"`3w\rss?~|̉d 4a@6lX?7c/v~os,~g^.(#G/GExqd1Z>~-o>t:}{) H!L8;WC~N2-;4hm0Go$?'3'vq<_eǑ91MB&6/}ONiR!PQL1OI10ғ>sq{k ddٳ#6p6v qBp-ߐzFqA{MLY=/ٽ}Y qh FAQL&yF|}}-^>|8?<<[Yf׏G}>QFOrd_WnNθqX|9o&}8crС*SN׏3~]]붜 QCn"鋏m\GhH| " co4+\ .^;JDznKAu*5q2M^yo?#rh/3 ;'-ِJxFONOs(ЃC/±c*#套R³r EQJL%i**bwAAr9XXFcCW({2SϟÞ{j90&vgZ:J::iuŽ aa-6s0 !!G'aLKCRc|>33Uwǽ.BB9};rbj/G]v5ZN#$$ÇGi&-[ƽދX:s!߂b"""ԩԷUjdMGnN7nZgŸGwxSMz7K?8q=zX-Khi.>K.$҉q{Iǐ'\NUMdߪ:{K7w\ & JRP١-]?Niņa| ~BPEeiqĄUou$h @JΝmEFFTT[[[F͂ عs'|PQFFnn.iiiDFFk4ƏϿ˪U mƮ],ڧ-[0q*穪Zk;G6QzQr @j>2-"%ס#8ܭ/2/U%Jbq fqEgY$= Kc9O!R`5h4xmQ_O]'Y>ƒ!yi%iL@DFQ4Uce^l"O/iߪc֓fʼn/x;;!ߐ?nԻhlQ5*/y+-W+))psp׮H+I#% L,^_mgg;7i.eؖa;Q`ZiɋaECl~,<1e\bwww&O?+w3V.-H?nꍢբK}r5SkRj*ƶ?+oWXΘ-`=:(§__ٍfmoA57c/K.kn ϶{!Cc|tx{3EDF3ww5_~Ť=k2>Ltn4^8̒L:W_ts )8Cŭ2w^&5[ުTSZLaW.b{}LRaGckz)沤-<<UUwތ=$&&RTTT:3Ol~,}+}Y%Yix 9F4Y%%%\r2h:ǽ 5Q\ˑ]ݻ%= &;u\=;u9$s߇P-^".r?4.c5Vx?QuxT:ųQ;{c^c_TlTz m++.%7 _TWՏ!w~ʆE(π+ YH 222X`% ;v,uGc4Vl%8QKJJoGsws=T93f oVF#<GleRm:d=59KCwiUd2[A5gxzUK_H.J6wҤv/po{}W$)1gDމ .8M6h`Չ?}Շ ?V$jZݶr 9&i ޶ޤkcUY$$_i^+V ̴*kc.))x|UUILLE]KJˋ uki뜇YYYZoe6IϺu Ȃ't g͢}cFmХ@ZI9TP?1_.I_k5>e] "##ҥ:E;;;:tѣG1LVbU*z{&9'0?#'/;BhtG+VK`` QQQ,2cH!3%}-_#+їm`Q %856'<˹S{?oՇSVU5q[{jq8a4h9#;7ү'TxMzRq2l Jr҂2N9}HǙ;Y`r3/!D@Lƍiժz+DDDX|II +V; FcN6l'NUV0f4 qqq@闘1c0rH7nɓҥ ey|?~NݥVMəiׁC@x6aߩ3pޓEZK=|3uq-ټ> ;#e:ut_t tvlJ=anэGG?H-N߀ҖǷ;W٭3:ġIm>q‡3wH1&~nܱ94~̟TyJ+V0[~^FcW!_qG0a'4 *ƕ GTGf͚5=STTd`BVgڒv.4cFhҲ7^9!荨KaxO <E4tQ#* ƿMW8oPxwV3{'"~̔s8}I>)1Gl!U t l߾b1o<Xhl߾3g*ɓ1c:u_¯;̚5 oooΜ9oa|c.whhқ||)I3ټ2\T#OW1PAOsiAޟMqoV矬4-[9s&}eݺuYmNc@[i<ȜHlA5`T<[Sh,dcFfG6d,6 ԏ<tƳ2mݙzu~$ދz`ki!ĕv^CiRnZ{gݻή5ZnFC=tЈGQ>s\\\xᇯsGbvܨu59;;xbfϞMXXBza2 +#&&|Y%P 0rϦMjG{ʽ/{p Q%Kq*k:tԉ/1_;n7nw}Ǟ={B4)B!iB!BqݓR!B!E$B!BaI 8e˖]FY;!IHwaCIL>-dk׮XWWWk">ҨQ#܈`'ر#7t...}v[:l'H) 3f`ժUUދeީlOXujW !1_~em۝fp9[bsPlOk;4vg3'j[Ri-G^j=={bġCvޔN:'^m*'as i}<)΍fvl6l"UӶ4včFVs{P_7^q/3fG0-))1c`0\3eeܹ޽(=ǎ˄ hժDFF7Tۺ y,< ^zgW4K밶cQeKM糝Ǝ㣎j㊊Jh:O/C涀x7]>[-⻓17fneL1բWxx8L<˥DZwU`( "j:Tz{.ٓ܌ӬaR6uir;䥑xjMNe[:;ɨwo"?'ޥYAL|=y5j2]%9{O?'.r˿T'F,;p$:Wvhuv g9>^W^qOOzR4MB&sX!-:BCVVVeZhСC9|0+Νc̘1xzzZ;|q hٲ%,_w:ZGq2dEüy0)l7fmZ~ m\ژˌj< )w*=n@G׎, ]BRQvO]wsZ׸=vF絝y7]i xN o4O|oc?v?TX_mT°-iq[)0ٿ*äI8q"'NdF+pBN<L-gРAܹ^xӧNv-kH/Ig֡YY-K밶cQey'kC/Fn|5#PQ`|{F7F)*aP ܩyj ;YϘ,Yn gggK]2bg#I{E uظyzx-_7Yp&EV( cN`벗(M/uc4?M[Fn9λ%&pȿt1їո|ZvE\V0w}81_P#"`˖-DFF,ٳg9x l߾b:vhvyn:֮]<(2)Szj˺uxj2_~y9F/“O>i:ه_i_4Q]G](;mvKL2ևqtguK|4&/Mʠ(x6vkvxwѬQt:cyx]bkDw>k\&]289x/syK,:|C~:Wy㫓_F|A<GL|A<4jdrd> )ؕYf0oX0,vO-maah ܻ%u S6\̒3K8wN SٕobD ^x,}Ox=%RQȉHk{rH\qIǿ>m~Ƣ_Eaĉ8p ܹse@pO?4gΝ8pz ~YYXwv~c#0&:eN8:u"T2gzkj.W%uhɱ2֐^NLn YEɌl4B})4hڞfJO5C3f((h=[;cSsӾ}tjRyd$ǐr&+!?'/ԡFkѨ'>z#9ɜ9Z--;dω h7y $'s#FœO>ɓ'-^ƎˡCdIDAT|߿N:Y.3~]]붜 QCn"鋏mzWd!7ԃſ죯p0º{Rx(}:r*.թ4ymRȡH4<Ǟ8fCz*m>9/?͡@z±cǪwzI:)E)-umW &uuhɱ2.N1(||*X3mLrsԡ):n1ս+ZGlɋs<8q=z\C^o4-;}Ʌ:LKNz<=T(*ĿUt6nZ ))ɧuJ\<nґC[1mه&-z{tUuKi565¹0 bOįYJ5 .^nk kjv1p@/_Naa!(bqqqXQJqq6lʪU0L4jԈB%--zߧ-[0q*穪Zk;G6QzQr @j>2-"%ס#8ܭeNƐ|*Pcp7(:|"d,]XxR=C1ׅF߿ޏzzIuF>#Gx0A6$o $ ځh4Z ‹^T)>%[ul5xz2 8{}y;9gލz a0FTU#/2qes%8;`Nui%iA m Pz=ewRG7$>>OOON7|}?{E?p3RK HPP+ gAN= wyEQQЂKHtHȒHv@ |߼ݝgy0}Krr28;;ˤIxgY`_G0EQxHMMe֭ŗij6u-y$&׭/۲5=+RmhI_4WfBx󨊊BrY2&~jZngx;mLi7O>1@:bݥ;+W6ک % VjG xRC'=_) E[* .PSIhm䜋"pqͫu0~·<%Frb}MqYc0p|ק|ȴڴGQT}K zioMiҎzO3O=Ea)I$XKޅ,fO$7PE8D>BwCuUVVR\\E+QUΝ;{Xnİi&Ŕ^zjiILLQ}Qn6qZWsk5E}mhI_4WUEtQ4EFMqM1Sw [Ֆ 4SVPD߉DGWN1} IIV_LiaDn~[MŗsfTWm&SXq$%vGM_gC^.R\pM3zˈ?zG_Eey!)qz]@Q:9> /CMUE8خUvp$׼N#hy79,L^ۛL!!!ؘ^jvPd|Gs=888fZ^^^n:jPOO뮬v~ sU~vC{_ @er"{]xOUڝʤ ͠&;tlZ40.O]8BBBȴ˭%2 Fzל_M_UEei͌3)l>6:stY!(Nοw'2#FlU[]F8/:or6Vs8A6/ ܚR/kuoTrpp|)mڴSMM tnݻwɓ,^S裏Ztu%T6/+MK?Sn(NՖOcތyGϮgjJdMhQ*,<).=mяN&&&ϞWYV@^f(n91VǨ_3;O{t7i`ԌԔ7w/t|q>r bV,MesF.W 'axÄ8RlXYeͺ\l\3NJrCyɓ'i&&OlI&ѻwoF[oC9?fǜ9s b…n=( O?43fwΎ.]ХK|||,^Wsիih.81s뇷%ٔ2[҆Esi龨jXG:>i~ 8pncA3p :p Ҩ+Ǯ]ZݛX_w#8sk\݃2Ytz;4HpBι(RPU=SXEߛ]!xvװt4mhh[BRVwoՌv w@o:.sEaer; =^sߎ_Ʊ_0F=L[OYQWXŵ)̙34ݝN:˪U0$&&m6 Ĉ#㧟~"//Ϫu۷WWW֭[Gii)˗/7]Tje7o ,ёD^~e_NY܆3d)MQh_{ySD곋(ڱ˓J~ %eeDſ*smB#eo@ NO /kDD-bᄇ[RL3nnly+v]ta}5Z trDmYX֦-_ ,?cO5ky;mm۲^:FÇfi|#ڶ%"O>ፘ7jptO<)^ qqy/MK^k \.NYmu3FiꗣiO͍r9£>jv1]vxŋȟ'Ӕ|Nرcqqq᭷2[_ͫj񺚣^PPX;tmjTO9Qx;FX}t#z?cѧ.|SlIZ͙j|{[ CCGfE&q%ǫ]PPHؒXj`Aj7am\|ЉBv_·)/TUP/2%t8k8{f7]dgs8?N iu9æ '6|MhS9e|ݟWbt8۾?ňiOK^fU!ZyJοV>W]￧tXW_ё?-]q̞=I&1Fg#n<{ѦMV\|#|,]tq1^o::thP:=7yhu_Sc aݺul۶ .888гgO>VzX^cDFFtQBULa9TWW_4=#qC)++c-] uZ^'>^) dɒ.B!B*B!"@ !B!B!B!,*΁tqqaذaJTT[l:B!Bk#zr"##)((ht!B!*ȼ<"""iB!B\^ B!B\y@ !B!B!B!,"B!BH)B!">z򢦦|!B!V@3gt:tԉ\VZh(B!BkdYY~!B!<9R!B!E$B!Ba B!BXDH!B!R!B!E$Ax7 E&#B!hX Æ WWWزeYݻӳgO<<oRXcUjqk;/4 E1k/bW0}GJvЛQ.7oۀ;0fm:R^ɽ_mƚ%F~Vy+/&\98{f7Iw, !BzQQ.j+PPЩ6f9̓l^8xQY^@ٓ.}?d1&b;eƣHNr6JyO2m9}<'_V>Bz~\| 2yk\_ZB95#1زfȈiphTWsD`Qu4`_!B JAAM*JبG(K(/la%䜋 =1394H r k خ@MUqTRZIVڱFmh4Ԑ7P 5U$lC٠cNYq6-}` E^sp{Ѻk/hE8EաB!uC}[j>9/@mcZޡ{#6CцрP5pt͟Qӗ1j2V:-R !BqȡCҽ{w;|Tj4()8ۨ4(Kfg0(ɻEK Օ+j~_4V>N# Da1`b|{ iV6T.HRP@Q@~$ oR[ƛҢLӅ/B!ĵ EaĈ6*xѢʲ&kB$F̀66J(uDl9\]Y UcUeٔidZ/x5ydL#M|}.֤!$[ՖfeFVୃq_ζ Q+=^䄓dL䄓|63+UQYc#cZ{e+m?{snz`} X߸Z׉Z:\k,w;ՎQE˚cSHNʔoR{{n7[7^2"I[],ױcHHH`޼ymK!.UU!>>-<NI@S^^Ndd$LS]]ÇXnL2劏է&/StձcG ǻq2vXz /#tU,>Ҧի{3Xrb 7m'g KʧϙKN |=-+=ALl|| |’ Kcſ N8dٕDEosۺPLJL{$l}[%کv5''r3<9"E8txy1-iN;_絿P!CX7lɘ1#FrlU[&N-e{v;[UfUQY'sZ&d'zb4BӨ¬Yixg>kzEE~;)y|'Y6Keɺ> ?O~JhNM<Ѕfѧ(=;&.v:c˒cySx_ٱc?0/pYl:,ٸq#cҤI\ ?߇j*BCٞݔ9_2~a^y8.Y{yl“6@c`wAz=ÇoR!C+իig%E$=zj=Y,$ǩ8c0 EGXr<_sKp8+Qvwn&7c}QllA/׏SNa4/4? g))*8Qx]yfdIc{tp;|$^fi'2|Um9v1ވyϓ./;v2rr=OnU.۳\ɯgPV&P2?!4.&2/3WWwTJWW$zxچQX]hq-yRxGS0}jc5ĽcQظѩ#K=fHFyB6V3g<g9khfy9Y?|=%%ye S{dI5W,6z eёEȲe8z(r _(((`޽VcC~ƽ}Y[U7m6޶mttvSM7/GyKdWfsVrN>̀شiS!`'sAQYYƍIKK*ʄ=#￁:Rֆ]ByL".ořxׯMp$UI 8KNRU|ξ9 橡Y!E_T;|̭pn궱^s0kTj9 1DE'g_}St ԵK[?`浟wQiڰjȼ XCu/lTw^?m>,|5ZMruGȫ3{?2;&B8Pf(#";B2+29Vp3M#1[V^߫jzYm.9mꯓ'܏t7ߤ}N5K6Vc72jwUev_l`,/xwB2)?i4 ۀ b \vso]R1֖ɓ'zjo#R^^)..&''huL>~kXQF1sLȆ}A뱯n?/!}Cy5>M:>d?})zE?&m3w$GoKgHVV(iJ#p^;;;u7L~~>_*% ʤ<Eա9mRy33  sE{ӒiI[۶,:iz/*+sO;O4Fn뎪ڸrDkkVzfpdj˟'/¢Wtp3jF QàLˊ-6P- O[OYsz.3˿k`cS&{egN۳ߚkoN&"ZWs˚m#4ɬ_J3}z97 ))*2 DkTu=A{)޳l ۏCT&:R1M撓cnΝs=[Hbbbشi@L֬Ych$>>}eg4ש_UmA!ȎI,_j& C<\s&3oö#TUUaccSophI!H` ә5kS5tsF~۱*:%++MivF\]]%?=Λ̊k |63U{>4IIhhw/]s4T-k۲f웬?v#;wX4bh\4WEACνwrUa ۺnNne.Fj&/&n uIK)ԕ΀ݻ7wq?wuW\52 ݯ9&m^U.\zR⡎Q~:;WǹsM+ޖBVq:+5C\}T%'[(40.B]8BBB> pG99W˵=w[w|w%z;6wa_>2*2(. 1yU/{10jFRRqq1 +A3Xh>ݥ; ᶤEve6٤(."4nM}xqjuFD lk1qK-81ȴX1Bۄ6z=Kri鯦˚uuiӥv7=]zXA34[6Vc称^1zhNji???훔!J"k͸ ǰ޻uGQQ7xxx\Oee%w棏>{0:ҥ)rQͷo mM/7yDKVlmպl|{Elp\J7:9iFU)<JuEDDгg&\ҝY3d yUy,OXn+NY#ak6:5hRR3[tv_w+ 1kb\.]Cpax[?YeOY5x<!tmӕ8mY̾W)83 t dAbeJcI-jc5'uxL/^sT*.l?*->i`lrXuɫ^ 0;g73fLgp;Vg>誖`yrt_&,EG%sdi /P/QVSFTQNUgs.O֫4?FDv)MIM tNėij7K3}t^+ %ۏ^_K9eͶ{7b0]09'y,1땃k?Η)_ޯo!f(-=ɉ3iQci gN T6T'e屩cG}k׮]v]tR͛ǂ ptt$11_~l/ŋIZZ%gggFz%y ˙?֯&r0aQQQ6)B@-s Nz'>Qʹǯk嘢( mڴfo gggk.]Fql0+_oύuZy}yYnvvvxxxtwwl@DdGPi1hvdhH_!Z8@={gX|9MJ#Iy/h2ب6<(^swt3dqH_!Z81z.5+>>*M#V!B!NVqV!B!WB!B!,"d lOt*ر#7o׷yn.^ѳ~?=7zE)K-O>a\\\F!h"tqqaĉw},Zq՛s,ZiӦh%_Dh<_:Ealܸzw+zv`)ɽ-I|c_uNN8Iƴ NN8g?#1誗Fawg[ֶ+O>1Mt1-#f7mSWC۪l>Zci۩v כcSHNʔoR{m:7[7^2"I[%,ױcHHH`޼ymK!͡Uzr"##)((7m۶m2dyyy-]ljrI}~1U)IW|];vdذa_y$&2tPmǟfbv=PPx;mf`ɉ%ܴ&<$YYx5|r}KN,Xs}7{7]_OAe/xytE=,ٷ4>ZH#ip;͔9ys_]tޟN,>ci[3g4B!Dshd^^DGGS]]}t:dzo>JJJ^Ow?W?M}~d!(({=qs ]~O\=4M's֓>g KʧϙKN3 |=-+]O\}3%wK',)Y=qDINNnt;W9]rX=-ampj-][9-csG@-#?|Q7z!kP~7+p{!cZ&ٮϚ~?o~|'Fs-D0 wlJjD߉w=?=űls'paS'_4rSt_6'8G>)95 C6X!>>NIetokwiS8tN , 8N,]ve6QEQ|{[{'!>>PPgo7im_~:Kgo^>0[2p$oǽA3ب|z ^gm⼡Cٖntνw0t!iUm <fbK2*TĬ,b(TŲǜ96?=۲-k̶ڒ\Fg9%ޛfScFur&dz:u!36Y?[,'׏={0~xx ϟϭjZ>b~az-&M… 9skdž\9ލ{g3~~-?g>imY()ej W%+9gu^yy9Of]%iB7=Cpp0|Wh|*NZ/?EL_P@HUq&kA(=IURRӺTUߟ}]6cnz>gߜڦ+g:SKQmXy1kRk9,|5څ/6 KN,!#,ojc5~H""ٓӾlYtiSOs?rw| FhqhhLY+ p ,v9܇FmKhhdVf2}:EgQ7odQLuAjKm ʤ14m'M6 q:`[XOHJJbÆ űuVn66n܈hחrOqq1999DGG_vltZhѼ:v3_74zϫ1iR􊞏LX0fIfEU:h4E`` \8fI!nH'''ƌ۩hR^U)Ih5ʤl;mҺ33  s[Eֶ齖mJƴ rna=TxT+z:8uD m*"9`AquV[7C e=T5/:߲Ʒ̭P!=꼒Ĵۄ::w4+%i+ggr{Afe&fڤX>> W-h&Etݼw>DZ1CT&:3޼,4Ē}BZZ %% ߦܹ֭[Dze˘;w.^^-wnש_D jGo}sw7KIx &Mf$ns;%PUUM,I#B4 1A6m̮zKЂ Xr%M{D=_vݥ++Mi~=6ڤ|K9jc5yUydWf[ؒXJkJӶ#^b>AUUQ,֕΀ݻ7wq?wuWWuRMVePOs<@UUU6_wkQu_~C"uv &*s\GWWW .;4B!DSsgeܸq mFqqyهvAEn߭'UɉhF˾L7;M re0#$$IӚUŘ֡H,Mk/{ݥ; 4FG=w[w>OՃWOd^$FHve6iQ܌ԲTx 1e5eMmStE6]UmM\O$&Z rX:?&9kJx{3m[4} ksjӦ _vv%ib(b+E[#z© SY~wEKuO7ǒ}BHH666,44Tݻw{nVZŦM _~Wy9utxz^ PTTDy3*}6eD^z9ckm'M_gJE mR3 Ư.7cνfy5}7O<ڵcҤI=~7nf"$$///L$%%򈊊k׮( 3f̸l9yd6mɓs/Jl)e)lKO{fDowvjR!Z=s1MrwwSNjժfS+}[7nދ 5g(t|-.73-:A{ȹ/%`8ӓ‹E>|8Wfdoyrt_&,EG%s)Md^$:{dmْC9\p_$}A':=K_(f-#sv33`&tyg3ii||cމ{ǔsMNVEϮdɋȊ֍cRR]o.cMND$\]]Yn,_tQR͛ǂ ptt$11_~ W gX\6oL\\%XצۼZڄ&L **&B!J<陵ٳg3i$ϟ/4Oމ6)5ws]X_Sq}^}UxU( mڴ8;;_tR4B!ZՕC  PS:k>u@ ˬ[;;;<<<Ζ땳ޙ``vZW_I(Z'888гgO}Y /Ϗ˗٤4B!DsR]]_|Mq3͙y;.]+2FŸf4B!Ds)B!Bqh)*B!B!< B!BXDH!B!iqqqaذaJTT[l1K3l0 d^qq1\O!B!,*H^Oyy9 8rrrؼy3V{N`Q!B!,*ȼ<"""P˦!;;@ !B!\ -#wl_.V+jڎMk4H !uj Æ WWWزeE|}}6l~~~hFff&6lpL|nٓ#RRK;ƾMopb-]5qFc {m0( 3eҜ۳{&o~z%[ZԨv,eVC!NoGV1:qQM~^Myi~Ó?~,Rb_z !)zr"##)((dOOOf̘AII ?ׯ'66~i˜?Mh v~UoDORVgKN!*%Dn~3-]VfEQsI1[ǷSVm}w@oO:ub7QQϹ}-B!ZV1GDDv4 ٳ6ܹs-]Klc"{~~c1#_ndEHyi'~A1kpt⁥'{;¿ZHԾiOpnێ,;CCHi:Շœ$"7I̡oPu6~n{ \aZ*Y~!5~7bqX!N.>ܻ _>IC-w/6qh=&5~>#bTWۧt;lqoyڷ!?4l]:#.h.f5|ZXm4Tq{фMΙ{`/iFuoM~ckB^f,~; '7) O6azeIZRfLlX"{E6Fav|sY3%v~"ga4Te%ټ'fq([,/˿'3_OiQ1Ǡ[fŤ'E6wۡ/)q;2KshufOYIǓLqŃ$1p6˧!È95q(3]GJvΙ>T|phoί`rΝ':ff.K27jt;lmJ:("h !jæzؗc+jSX鰷_~7p1FA=Zx1پCF_b 6mMiT -}` EɤEp$#6oY>'9}Gz EQQT=%Zb(/? # =~.a/>aw.L#l`c눻ogғ"a%䜋`"=1-2R"(-$+Q#(5iiD_I@H\hڎQD[iH==&u#Y`Q69}2SPɽ_}AG=шIJA"{`ʣ_XS4H r kU;{?1 {)O ,]iQ+y9Ifj )s}iZbs5\m* <9vB/x=vc4֘.B!y(sP\ڵ+QQQBqFN P%!9fi$T'6|~1pt͟Qӗ1j2V:hidIfUANơ:EgԴ\ӌ䜋]!(䃌y+zO%wTVvzUUsY6o{n/q;>{#RZhHiH]K9t;LR'72r_ 4SgEyd&jPjurpd < GwU'ptޱ-gO>S^GiQaMK 30j54jʰs:dQUQhNueiQι( IANl^* ZEBF7Di0&??bQ2*r5I@`OIFDMu%1HMo2 GRbw;I<~UQQuΪeRUYw`:2TrOQ]Y}el- X:/xǀq1j!ԎPGf6s'`je9s$ls]YBQTn36li s@Ә|/dt_@sLW,ʧumhII"|SN|滏o'?+lPMҩp:ĩ۽!SXF#999ߦMʬ:x2ϊQiiFRwE8t:lh5itA5lדD4h '/^劢ם4*ҎҾX9suDCHODӌVիTW_܂: 2-,CocۗpUcUXjZz)H+s(h%xӅ#^XlAZSCr %죴06M$|88{!M3m?ֽҎsX˒6l.ֶsCTvx<;W\/F2rR ͷ 7#y$HCp[[ZB("TUOOO兛P'С}ŅݻLll5wU3U1uoWz OAI݆f4`4Tsp?3!ݼW`{gă Y~@Q^ spnǰ/DwVNEFӌ5\Mo&.v՞WKG!s9l* |3XUЩ4x߮8m,E%?y) 荛O(( =̽dY_XM##0'N.mU\p "g0/QOي9w:#eo; ΣPUg z!2T}11򶿚7cUݛc?P­~Fqnێnc9^ UlUٮ^zq/^yZ]wkGc2|0j2z߿/^x¹m;I4#}o~ce6Ww !fZV{{{̙NW;ݝN:˪U0ř.sM7QRR޽{9yd43o&'<3i'~Aue)F?)/Q]UFι(R65U[}ݘ^*Jؿ 1-?rll1/807-kTH6$EoAӌ$Eo]ǡd^͡7/`حKs"/+/vܔ&vً)+"z]4>8^zpŸغ)+Fj"WӱDbiTOBsXҧhaӊG7yh* 9}GΞkΉ[Pሏ(OE.kTU%|tM~)֮ Yu 5{G7o~$~ӥMNM;?`تǟ'$ުGF[˂N x5KŒرc$$$0o<]vB!H^Oyy9\`0W_j*cݺuTWWůWM^./*%i:vȰaX~}KW\#tdWfV[)=ӨFȦAo~@σIˆdZOՏ)=Gc)YbJЭ'}dO3Na8q"$''_W_? g{(u֥*<  <9UUYb .ޱ=禞c(QזQQY'sZ&玀;Z2Ȝ/c:D3|+.B!ׂV1ZҫW/bbbs.ϤJGKvr&dz %$>~i8 6Y:CI}nIOȼHf_E^U۲YTl|mp /;v2rr=OnU.۳y$&Bv 6g^y%^<"r{}ߣX;qh@螢(W_UEe0̖7w/mm^cp))C;Wf(#8#-o;ӧO3`6mtEF!ZpCAAAs%a.cyŻ#0RIcfiNm@1SuL8Mwk` \&UUg߾IIIlذ8nmƍ1R^^)..&''=s1[fԌK[ݞgn r۶/KSt ԵK[?`浟gqigכ" a(gmNl '^V[MQmXy1kRkd>:^{h5-' w}D~8we):;7u  {;Վ;Iw}fmz}Fȹs;nyT,,QMB!hZVkݛsΑo状nX\D{ zcx:Mei3JIB T&%`Ea EQ]4 9)))ݿsNJJJXn˖-cܹxyy]Nhq92k$M#,+vp5#QQ8SkxyZ=f7MﶽqѻmɢUQqG;245PPx3=iXKcRm4ߞUE΋gs,=X;?uV+ٙMn*lllB!ĵtss#((M6Y=JPu.Cp2~>|_L1F,W3KF puulUUFEt[WFF~; wqu]^յ%(T#{3g-sS~jǞ&4-m(#`w^˖ >=vz%5#yUym{2UQQKQ W+N77r+s1j_+J.Bp#={F}XYIQV2}:8iycu E]C^xݭ'UɉhF0 rـ.$$PRSS;VVV{n># PrMtxzz^r}ДƷi2g<ҥMMpA3XH/^TEKwJ.:XΡ4z\u t;q/wTx99W囕_ Ive6Qիƕ@K_UTX=sC;u.KVCTat3 t0T+gsT*Nl? kMcsY^6~="Avo%Vx^DD={lONg0TV(Qjs]3 +NY#akjO :- )^xB!׺V1ޞ9s昦fөS'rssYj)P g(-=ɉ3iQF/%;g^'+PPy&w_7˫xWntݼCi A޷NAQZ\npko ⦎FsNcDD-bᄇ_Ex߾}n:JKKY|:̛7 Hbb"/hJxx8fŊyf.Nz6~/U\I*KbElrQ^.=yةvsj>:ef" J < ^e5eDE[6nnly+vP{o)~S.fQMիzJ[|1 e'~SǞ2{f$<1c#/x>.N:.䮠X73gpٹ1amR>B!:jG%:y}Oaaai6ڿ mC c{/;/\l\Xf`G֎.Z9֏#Ԏn8/;?cSjW$ONf1u8f웦{6˗/'22yU!$#-J@^ɹ.mW)8K'_P.B!NB!BqhR !B!B!B!,"B!B@0l0|}}quu%**-[gcc N<jB!BaV@zˉdL3|pt/BNN7J;UB!Bk^šGDDTWW_\Q|||HII!99Rbccۻ/B!ׅV@6D4m۶@Ϳ]]]IHHh !B!uULa޽{ts=hiDDDp̙.B!B\n{tԉ<1bǷtB!wCzÇs!N> ` "ӧ4)B!״HNEAiڢ(JKQ!B!ybRUUQU^=^^^ԐOUUΝo߾F;u>B!BaV@3gt:tԉ\VZhdƍ1 &`ggGii)Ga-]|!B!.4儇tQB!uC)B!$B!Ba B!BXDH!B!R!B!EZUXOU}v7>8پ-],!BтZE°aՕ(lbQFѡCz=޽.E&)]ͼ}ξ_X^ ŒGi!Bk@ z=DFF2p+„ pqq~ݻ3e+Z fvoX?dn+?A s(+l" !B!n@"#""EQ h-رsIN޽;vj*)KRpn xrӣҍO]۱~i(Y~!5~7bJk|L3[,bKBYI?}v/)7Mhtl9 v2f܊Bz'W s&11+sskOpnێ,;CCH>hZQu6~n{{>(ѷG{l c֫#yh-mc{8xSQGJ\_>aZ%nIX!N.>ܻ _>IC-w/6tU!B\ZEUUQBioo.UaJ1OygFeyi0b~M%wʌGבmȇtl]HBf0Q^gOs PY_<Of>Ң b<ɇmRQux%Ϡirç_l>\=?=j"߱}<'_V>Bz~\| 2Q}PX>Y$Fm6T ERJ2Uv!Bqm!ZQQAvv6zEQҥ ۣ(JKS6\sQ U'F}ڴ]mdNPSvB!צb k]唕ѦMHMMeeƓO~V]A8H4HYq6%tyڲ_llhai^_XjDe}p-.n0mB,>R!B\_ZE*xyy뱷 777Sz!!!vmo̔x'CXi4p*r5̢KouT{.֏a_= 筜\-+q.a=\~ʊ,/$͜K_[/C5># p˿}FWSUYM B*YrPWWW:4 ( @Mߞ<:1)h9vθzBb~%B!D+&I&IL[8B! )B!Bqh)*B!B!< B!BXDkm`{zǤا:v͛m"V&,, 6EB!-y`~_ry*`߮],bYYY+ѽ{wFͨQ2dQTTdGL<#GҩS' <͖=(u;‚KQ^|E>̖-W枋WwvтWd]-''슭%e K933!CρZB!74GGۓ)Py?z__#бcG(++n۔C;ǏrJΝ;ǔ)Spwwo*ԫ&/St4;vdذa_+Z!MXn3gٹ#B!Zu@jƆ $99gϚFႃMzٳg9rڵJzaEkhz;# AQLiϙl’s&)'N$99䋖?;l޼{κTU_~l2t:)>*+V`…-甆8t1o9NLwgЯQ~P):o /eEƴ 2ek;a?=k?ϔ'??OͩXДos9[qj)RמEU_z-B!>zEQ()NLJ'Ni#555dffモ(2z<> L~޾9,LJKH|>Rqm`{tN"xn= Y [ @yIxa؞<'IDAT.[&UUׯNh4^2M~xWxgܹ3˗/'''~ #Fd=C i>̭@ClYj̧#?!4.&2/3WWǶm#2|Um9v1ވyϓ>dڡCYtdx=Y?|=M]ju1Sfɉ% ʺa؞,MC|^yy9Oflڴ9X!B\Ze9tP jH[[[ڵ+7tׯ777Hv(LO3Kv4l7siuU&&5@mXˏxn.^o̤$6l@\\[nncƍF|}})//gCtttcnz>ge:EܠM]˺u|p&N`^y8]r5u$?更o0jWSYSx֦EC#2/5KS_;e4"00/B!i߾=6l啕SSScuE[7a,.1^IUj2wGwb.B"EKyTt DF#^6f_u[WFF~; gϞ;`͚5 z $ꞷh 3΂@j.;JJAAeJ !B֯U0rHuƷ~Knnr@VV~~~GMffU񌕕El%׈q N<]P_]Pll/֓D4k  l@uhh(f@ee%w棏>{ */޴N%H,Mk/{ݥ; Q2uuʬ(? f@^~Fw6]U/WO$&^u5GݛN#88+B!>rԨQٓ;wǎߟ0ڶmñ'**4 {ľsWl||q9 t* Mi 6@UZ |Ӏ妱x̹,/_?yۀ nj|ɺ .p`!Ǽy޽;%} !++5k'bԩ̞=8wҥ&Mx{{qFRRRطo!!!S*U߷r_;oy+;7 avQG}ԗ[ n\*ޠgY2>n1CѪ ȍ8я98|p:ޖ% D`` W\oB!|*{(T[VYUsK__:uXFFF HNN$Y~}E'lSj|B!w!B!BQITևbV!B!4 B!B(" H!B!<xxx关3D?Ntt1#ݺuv899yB!B=*ƍݻپ};ٌ9WWWc8VKNNN"==-B!N4 ܹdYJJ 3fݝDRSSCRѶmۊNB!BT:4ZJEfffE'E!B!ek׮υB!‚7 6dΝWtrB!Q,k׮xxx}v*:9B!BPy(*=zЬY3m&G!B!d^V 999Ɖtj55j@VjŅip !B!Viڴ)666 >d݅ 8x L4 F@5hڴ))))|!B!G H^7|SflVZUB!BJ롛U!B!! H!B!HR!B!"ҀB!B4 B!B("  G0 :mi6 YG3E*'~Zѻ_nj'_=i_FTtDN(읎 sA_B!?///h4$&&rq OX3s;VX?xh0Ǜ+[Jvq{?uЬ(|>Azr {=oP=s]Z2Ztzt\SwG!aS*ƍɓ')((]v9~DEa)ғprnXʾZ)qj<d5GREM!RŃ<B!*Ro@ vi,%%3fNbb0Pk4΢ȷqDűz}B@]Zcm[ī>3{L\z1i!j-z}?L|z*.<" By.'6*N{I繟$po6;KqpEFr}hfGMˠE2C_ǹv 3S&GC~ny o)N(C%extѯi~ '#RѪx:G5drzNXq]i-?Et7ݧcʭTBqz}E {2Q͹#k߿A}\($Γ8J|%9T!A RwJERyOa*JjButGRA;rnP~[#`LjB( 9̱]LÖ?qٙ)D]9@R%>{ѥAʉLb:Ͼfkd(Jh"inRin4W/ y-E8 } 'gwx}XLl 03|N~b4["==hoI\IkӠE"o5>A03o&qB)%\BH6& O~Ңe*B 4'gwjoǕr^U^ Opo5t nƊN%p#%?e ՖMȒXyDu#Ę>5u>3=cFJ$!=O'P)`SKA~.N΍3B!ĽzLiذ!>>>;̝=# / w|=f0Tj 5h"ϖ+=R[j$^2~''+UjRz]zz^1?7;Zh K>sqC{+یuRyX$-1.9zVkM?H6u Ǿ3.e*Bqd׮]`;˾@<6 s7k0)IMAމT*5C-^@FJ wBRtfOT\vV2WӼh"Ҽ(BR!YT*0رf=y@ӨEHufh45xV*w%.VvY".S!Bh@ ///9VTbV ^GZ5j62'qj.MHM(Y1o JZcWpp]mH½ZX~1S?ЪZc3::xb} zHM}ϫY1:K}ՠ=hl硒x>:-X=GJuwMOi;.uMtEݒմs88զU Tj*N9uSm } hn4ڌ$&,3r/K#At;[s+'+lPkK !BO~ZiӦ0|pu.\Ӥ_A'1< 3,}}Ȍ7/ {HT*F'[7.~b/}H?~[F?晷Qf?CsG`emGoPՕoG%r3 ;S8cq^3s%.u<?w7 ~zdл塢Nkg]gFZ4t_<,CK&z ~mvU*LZMce@jb(?&1(CУ92ceNXҌ0zMcemϨ?c<,YB! ) {%UŖ}V\WN:t8Q#+:Zҋ WTtrB!DYfa8sL7 z/2{}RsCw"\^#NB!ҀDmg;~j~[9YI!BK iIWټG$B!}P*B!B!BEZZ?Iۈ4FQ*:I&7n̾}]|ϓ|ڶmΝ;qtt!BPၗh49~80۷ÃjժĩSi5T*lZYgBR1{lC||ɺ:uEݺu_x뭷J1j(~ijժEXX+Wĉ% cԩ|}B!B<*}JqDDD{noNvv6#G.??gϲ}v|||HIIaᕢAiܸ1ݺu_~)֖T֬YCTTTٳ'/f˖-7>c5jd0ƌC*U*:B!xU``Ν:uHbccٿ?p/^$((X8|0zu*ڎCδњMʹ|s_*jjzci4d5**5Lc Dl0 W|EͿ7x \g&Ldd$%օk.KI &pY~"##Yr%7odԨQ SӧjtݒJ!BQJ߀,VERy<j񪬴3O/oļ53-}Pk":A[DnRg;$~)y9j<>gFN]w@VM̹T5$Z}˕Zܹsjbaիtر|E!BCـڵ+鄆,Y&?ˌX7pj>9/8Lnz >q %uƘ^^^ؕҨh44oޜ-Z`kkKjhѢq[-[h߾=&MA̝;GGGcA,zqB!v~ZiӦ0|pu.\ƞ.]reGˌٸ-xB^8 %&}%-=inT6D")߯ 賳p}fu-AMNp 6~_IV$HݶDz7oݻwtX6m26nܘ}rU&LN?w駟fpBÍX*LAȕ+W,ZB!BTMP+*質碗毿ڿuСñ2\yPk+w'NdȐ!L6Oa*UYl'O!BqլY0NNN9s(]b/CWg}.z_{ e`cc3IIIrssc͚5:u"B!Ŀ4 |֯__P$44ij>B!4 r/̬$!B!,B!B!?i@ !B!PDB!B!y( ggg4 ?~R7oޜ!CίZB!BJ@T*7nLDDwfdgg3rH\]]KV]t!55.B!J4 ܹdYJJ 3fݝDrFÀ8qt!B!T*}diZ-*L]t!##C(B!P6 vJzzICݝf͚q CE'Q!B!*MÆ ٹs'888зo_:ĭ[*:B!BQ)U{ ڵ+l߾4rgggVʈ#¶ٳٴi|!B!G{(*=zЬY3mfx~:6l@RNyfEB!B= ^zၯ/Zrrr̤D2??NWbB!BUZiӦ0|pu.\D!B!x(T^o1{۷o !B!D*B!B!BE)B!Bi@ !B!PDB!B! SLyON++:9ԨGϢNCf!Bၗh49~80ݺus&߻y&֭CW.hm;!:@AA. W8{ \{0yf9.[Ww=oP=skE'iz(Ba7 U*7&""'ORPP@v9r$?ư۷N5 ֡y |Ƚu4!B!ĿPo@ vi,%%3fnҀ,(( ))؀L!5! Ztxƞo7 U*ZuOǾҘT._ϩ}PqkXV%-*$ =GMˎ1uc-*Tj:KqpEFr}h?S~Y3 Tj NtM쫸h6 ب8=|EjuȾH0` o5gҬXԫ'9}pUO}~sCv|=̲x4 Z-:uk ;3]>E|ܱ@ZUo{.߬<|'Fj4g}N|iL@z5^3anB!Hݕ7 6LJۍ0p-Z+[0{{7<ƞ[*Y1Z1 Wµ~5CӠEnED~nֶU,t{Js3-B=ps#CL1+Ͻ!^eʹ8ᯞ\߂ ׬xrF|Fz OМ㫌̪?B!ªRٳ'Zb۶myYN'5!ԄPC.Ws]M~^}(%̈^Ӟw=na'ʈ'7' #LVvN5Uk>^Gzr8.u)V.j|Jоlqmz̠W(ȿ7JF{+88ݾxr=`yN_Щhq-ڏF}MF sKBY\굦zfReJ HQ3Z+S݆-ƱFZvx&^C :^Y $f94hޛ' ]AYXR6#hcε[TV'RIK}|[4lїZ d[7c 9Lavrd =}}DK&޾Yi=TCWhLc,!B܋J?UVӴiSlll>|ɺ .p`ᬋVVV ;;;~:>>>W.(_C߹u._O~n̡%e|=sG /n|>>dƛ߈v$S 3ӹkLjpJFJ#~cs;Q&%f"!~!q zm}gF֚+~Wg+ɻ}pq -c0艸:uLZMce@jb(?&1\V( -uhm8Ӌ3 ƞ >xr3 ;S8cq^E%e4wJ{?ƁYAWY/0YB! ) {%UŖ}V\WN:t8Q +:Cj𔯰qoTtR䏥uixz;yVBZ+[^z^YNB!*5kɉ3gt2PPb/CWg}.z_{ |6UpNs >_xttnHND]CWK޳uD]9\IB!04 ݠ)q@x>N@iV,}ǯ@֒ok 'ɾB!idB!BT=U!B!' H!B!Hh4l߾sq9^y啊NPȺ~CZaߦ]5nܘ}Qvm1 J~'IFڨ4>hAE'´ڂAԳw߶MYUxڶmΝ;qtt|$BP4 =<<?~<=saԯ_Dڵk3ffϞͬY;v,666bt:FMv8~]ZYY?@(J$m -u;RNqf7}Ǵ()ԩS+(BTJqDDD{noNvv6#Gf͚=L~W~\RHAj ѯ'/*a7nLn_*:hY%umpd^eW_kQjccFɆvh{KN.?RE[;II|t#e]v .;tG |||3f UTy/BP;wr)"##euؑX|}}\t\E۩[.'Ns&'N޽{=jiӦgپ};C 1kjԨSŅŋ=ڬ/_ڵkye߾}sj57ndܹ@֬8v6 xLOVҚ>ʵ >WhGqp<o %~D<Ķl6{ kN?faTP#~D 97.r ]|" #TVwOuhZw~O!rx(jQTdf>\VS^=Ο?ϰaè[.999\xsa0ʌ3.. .0p@N:ewuJm[Éy'ڟUV¡C,j2 ""xkۻ3Tx,aŜH9;|}>|RbZ%KHMbwnYRӭf7t&8O9N5jȻtٝ7.s&u꘽l]6o^GlfVիWر#{5;B!\d׮]IOO'44(֖si?Nzի-z{>[nQn]<==j5Fb׮]ٳ7ҫW/ƌiiܹ8ȑ#ٳgzڵkɓ'y&\|c„ 3 DEE)˺N=9ݍ ȹt$L!#׀]/oqaWI۾(l,f mVCC4jSO/ sL z|b|xիy]֎eШ4Li0'ϯ~ΠڃpRby}z&5D/^J<چ'MM{='_˴Gq}5j\qԼToݞuMwdF#jZ"܆1mc%43\VZmM޴Uj\l\͉VcKo, ZƕW]qʝW\l46ρw=#Bk׮xxx}vҌu:&ˠASF ſq ȱc8p & "Zmgرt֭ؑ[3}t&O|יDͽX>|ņ]!x@t}|?Ԛ5eT@IoFcV)_Fד?,,)97I]w42(~I݃VӷتmYp~YtάQU[fxwwRR~zӮ7IKuRK}*<]q]^}ܥnU=qrr"==CBx(z U*={UVl۶,zK\WZlC {gϞiӆƍ鈉Eejf͚U*??[[ۻnOӡ[;I&XYY?7k֌h_ObggG۶msrr56T4 5k4+ECXK{M4W>7~_!sIr.Ǧq3wmonE^d8y? t:BBBhҤt,Uvvvf9 ЩF'ZTm :³y2JaYa%ctZu^cO$N V<ԳLdLSúmoד$r⌽e%=,7 fҪj+Ʈޠ'V?xɳXp`PAڞVYf\ȸP4Casww'88B!DP4 {ꅗGA₋qZyŋiԨmڴݹrY;v ^ϫJHHu:;v0|pSNM6ر$@`` ]vӓ5kx&^уjժaccSa̙3:u0dïjlߟ &ФI\\\>|8jclwwwT*G6y \R+$$Ĭ!Ն3mZ1fh M+y1Q-rpI\Vp{i1P}8 J̺^^^wl=6l{eذaf9$@oQt0C?DSo 3l:̦M&0p6,}]Ҿz{\m]3tDeG1ؠVtɉK/*5Vj+^iI0WQ?0L}|ۤџOy3n:wwqzgjWKoi:瞇Cڛ,KcpT*/{ڶ9?< ZOGOQú8=b"Էnի=#BʡaU4mn… >>deefD.E4uTfϞ=,]ԤGooo6nHJJ #$$mL\fmȽJMgerm(^ZB6RkįI\7C[:-GIgpT* ޷u|Gcbr.X ņ01odg[oO1p8: |yKMҽ>b=Y,4%ddx#þ.zvh_}aCKPkd@>>m6 &)r96ZTmp\q^z +]w4&ǠA !*{(T[VYUsK__:uXFFF HNNjժL>]O [-^䕋g(4~=УCMwd~ʎڙ̂L2 2چ#/ɯiR ?3˖-ɓoB!ĿQNNN9s耂b{>Ssc$>>>4>XfٸB!xU!B~Nӧd&ϲ *-()߯B*ٳggϞ,ȇ>?0N_|QB!pRhܸ1>>_L(BCX ;wԩSDFFpww7KNN&))rvv&//k׮)Nݺu9q;w6Y>qD݋MdjiӦgپ};C 1kjԨSŅŋ=ڬ/_ڵkye߾}$R6oyT-;?Mw|dG'\(@a/';Px>j(vŞ={cƍ\p1cTX~DDDsNBBB8p#GDWWڵɓ$''se֭[Nh:0aBI&qUmKPcRDگ>Fd6n] %헟` )"°oά ᷟcG0qA2Emkz c8>|Hwn#}j{jTZ+\O$u#I~IJB}ur1uPVSn]JWrzDׯo)Bo5 iذ!;w$??0[뤥ÇSNߟׯ{ʹZ-ʕ+zBCCiРA1x2Iϑ#GLJwy)SbtܼyWu^:hi؈ܺM& gOP?lUڜAÐ_>/   {6pa9A4tGѢY:uܶi}=\\A1٦Mn^cT*w<>+4 BP aڵ+l߾իӠA݋`0+4N89v=uVQT-~/@||=NWGѤI{6k֌h߳w^ڶmkΘ]PfMQ4Nen^Wbh'zyԩSiӦ ;v0`0H׮]f͚ƙ/z_N=V6666ʜ9sSC O> 3a4i ÇGVa#00-[Jbf7 oܸ+WJ}=ՠבchk81hj(( 1fuΘCΤɬd?gkl4 Sr-_ҪVmuT>jCG&1䓰Sj> .3fc;G jj燗vvv\v}Wnnn*!BIT4mn… ?FKsIٲkPQ絷кAqxYIߵv_ I 9Ajy(w }v _|BϏ)?G3sh lrI^uǼy޽;%{5>] D``ɽB!V*{(T[VYUsK__:uXFFF HNNh9r$111_<_>_|ǎ#66>D8p0ٹs' /a,fK/\N>}+++}?ښ#G /?*w%8;;j*._LDD{W^;ϖޖ.*Mg}Ɛ!Cxԩ;vf͚%¥pB"##i{~STcĈ,]/sE'aԩ,Z?Aw^VZE=6+KtR6mg޽&ᔞ7^zcq>r]>(:t_dٲetԉ n\/eV˗/ߟ%Kό36nhg߾}ٓ;0e,XP6h :ij>ˤIHJJbÆ &wѧON<ڵkiڴYa4jԈ pr卝)))\Rf&O fڵoa,fK˗8pNL<|tĈT^ݤ$,UeţVh۶-O>$zb|74kFɱc|䶔w!*]2%% v)S^:ӧO7$::liCOy뭷&((  *+5kITTk>0*8ydcΝ;yf.]Ddd$/ VVV 8cΝǒ%K8wYiV̙38rHi:u*___cCQ^)w%eRx9t`Zjs|||Xz50k,!(SxիaƃիWx"> 8Ь|. 7o<.^HHHK.E}Za\r ^xJBՒÇIHH+9)m8~GO,_7R{:?g}֢C`` ]f\h͛\z+WciӦ * NYr%ɓ,\~?1,,~ %aX[[b >cuLoCVVVa6nȖ-[8qƆX"͖眜u"$$p5jԈcǎ|r4}+S+++f͚ņ LF()SK{YTZnݺzjyO?%** &(:vPϖږt=*aDѣ(00}_^|EFs=iڴ) 40 SV<4lؐ ϢEpss͍~VZOн{w;> 0 mT4O>yҭ[76oʕ+KM=ͣiӦ<Ƌw%,&O̲e/ٳ'se„ ̞=[qTZƍsY2Nǹs2^,׏^xKҩS'|I\bW*Uزe ͚5gGX$Jꡥ()/KҺÇi׮SLa&(*Q;5"Vqqq1Q;vёѣGO Zh#F`̙ >-[n8s QQQ̚5PreunٳgK)h4i Y޻Ƕn݊5k,8}tn^nݚ;6&PߺukryڶmZVH(;wӾΎ)S`eeUG K)/Ks˖-?l޼mq͚5㧟~b,YNwtذaԪUuY4,Y^ZM~~q` //Gy\Qœ|m[yY i0HLLF;L8kr!Xt):~/sE^k׮?M61gԩcV<'ۉa՜9s'xDx+++.]JPPhߕsaժUlݺ(=_رcXU^Z]^TjԨaQn]rrr8z( \x?ܤ8l0ׯ̙39y$ٳڢej~S7]֭[ݻ8qeZ^9oݻ8llV-ZDLL QQQ]8;911{Wi&"##<]ÇŋM\IYT*fϞM^^=G6~q4mTGs:u[FҼys>3V=͚50{^'77\Y|9oVw+ws58d߾}|ǥUTKk.gё$ƌC`` m۶%%%5jVӧÆ cٲe ÃH]Ƃ x8~} s,KL4{{{{lBƍKlˋ~˗~gfӦM$''WhMFF.]bʔ)V9r$-[4^]iǎRۂ˒P"J1g5kRzuRSSIHH/isvvf޼yуիhprr2پ:tΝ;ӥK:vȰaØ?>O?IX4 &5z h4& LBBBʵJٙul2-[fFFOj<pE~W!!^^^{%)-/K9u#22ҤF>}h4LĜƍ7J1 fn:6mڄ;gѢEDDDQQQ|6 ܸqV/_6Ɠlչsg~i @ݺu̙3`…=s^qttdܸq,_k׮ cIPxkq矌?VVV|7q;J[LHzoKt̟??sΡ8}4;vUV%+9vPR-s^E*uRRJBB}Aj ^y0 Y???VX~ܹs9z}u֭[ԾT* SLNgZZz5j,Q}G[ntؑ'|kAW6EUTWyƍO?-u]AA#F @q&88F×_~yY, @@@dzrJ+F>(cwۯPhݺ^z˗2sXFÊ+qK,)qbr/ʕ+8::o駟GYT*.\ĉ4i׮]3)7nºu ݩ^ײ´l7776l`WPx߿r5&//h8{,̞=sZ<̽T>&##h֭k`0[oQ~}}.]DttSZo eРAԨQFCrr2~- &|cRnm))VſWvuu]v矊+wrr2xzzըQ㞦NmooOXjN">>'"yyyY,z=1118::hSz=&jZjExx n%,{7o$,,)FC۶mtEvnn.?dذaөS'/ҤI= BI)9ueζ7onRZjEDD:beZ^9oXzg1;&99t{quu5 SVYf`ݺuatK^iK;yyy\p޽{Szu6nHNzϽe?>mڴg֭[w gooeryyyhZc/ZfŌ7Ǘ)((ŋtoccC֭9wz^QSN裏ү_?G9{,'N`РAʓ?JjVz8::R^roT>jժԫWDk.>"""Xr\l2߿?57靤D:u֭GT9ۺS=TR^J׀tvvUVlry4eqFEz9s&;vT%,ϙ6m3gΤaÆxzz2m4^z%)((`ƍ :)SТE ^z%7o< ƴihѢkfܸqh4iwEtt4WSNѧOR-r[e2nԮ]W_}3f̖-[+Ӣxzz'aiڴ)899FFFq^2ԧo3fPV-yyy<{~*,|||_> ,^֭[i޼9AAADGG+>X1 3i$N:ERRjι, `֬YKdddC?;g2vXUViӦ4oޜ0gs&U*˖-'7OOO<==qss3uڵ+O?47_Zj Քڵk\z&++k׮LXRVhZ<<<֖5jI&M/`̘1tؑ]Gyݻw[4Lq<"4[*Xr%cƌCۗkעV駟J#yyy̟?ϟo2h4̙3-[qҗRt[m۶婧cǎ < 6͛;J곒|6w[wJRP*y1k,9p~mJŦM۷1| &00AOppp`͚5t:֬YCLL"GiLff&+V0Nc25kIN,3y`ǎ,\YftR~!8p[nq$-,]ĉyW9s n"""7|E1n8nݪ)-BsAtbst{{{{o&W6Y^*wtpQ{= bС899vZmذ_~(W^aܹ,Yf̘a򣒒0[TV={`mm b2d 0NGNN , ZMHH ,0[,F\PP`|6 ۳l2jԨANNNbɞJƒ%K裏8qGXݛf͚q6Jt[:SҤInݺšCX|qeVQRgsu*x7`S=J-+*E:tpb+MfffE>}%K}NοEi*:)B<0* 6ѣW$ɟFLJ ^{NN,*Z*U ę3g((W{}ث3>|=РA:vȑ#G/g*#e!xӮ];}Y,ɉÇe˖NJ, HVˌ3x6mZgOB02HyxrʊNF,dB!BT=*B!bHR!B!"Ҁ&Z-G!..8/_^Izh}G|Ƈ+QT>s̩[tx <UVIB!Ij@ƆMll,.\`ժUԮ]vOv"##9s _}i)((W^ԩS̄[o˴kƼDFFr }r=~:۷1cTHzRT̛7?KLO4DDDbRz-:V{{>N:yfBBB~m۶L<8~cƆӧOMvPTL0;vLXX;vgϞ%5i$;Fdd$&6'Ν;0`@p۷g\zn݊Y888osy8y$3cs9֯_oVr/~zT*E25,ȑ# e/رcYeGiv,y\(I0~)̚5:%i6lׯ_/q|]rLGnxPvT HzM>}Xd ={d͚5h4NZT*1b.]ʀxILLٹwgҥ3m4޽{M}g 2{N:cj֬Yaի=GO?-ŃСC^|E-[FNXp!z'Nݻe8q"ǏgϞ=<#0ٴhтuc00 UW 4C2i$ذaI|wӇ'OvZ6mjV^xNZ2kԨ ,ð&??CҿkܸqdggsN E2U7bWnrkggGJJ +W$<>>dee|_^:v,u\(I4tڕ[n7вeK*9448 6@$KcN(9QYU/Oμyxw֭7ofʕ|v1efϞ][IILLd7,ވIHHPyѣDcNԈ3,Vqqq1x[=,cǎ8::2zh}]~io-bĈ̜9ÇӲeKMPRWϜ9CTTTÌ@y=R [lYf<3у+VРAEe1XV-x'޽;}|ICv nݺwwwk֬Ydeeqidee1t֭1x'۶mcĈԬYΝ;q;;;;j5qqqz׺ukm);;;Lb|n+6Rvʙ3gXv-.]ѣ<3wM?~:ШQ#Aօ Ν;)L+++LYfO޽%KU 6Zjn:u<|Ru?رq$=ϐ!C?ʕ+&?Z*JGI<9!*J݀lѢ3f ::h4 'NLJ۷ի9s O<NuhZ7og}FժUYfceeŜ9sXj[n%**G_3vVVV,] ',,L>kѵkWΟ?ϦM3gu)W\v[ݻ8qIMI1 l޼ݻ{~ѣ?P`0{5S5x`JâE!**kw}ILLիlڴHr<]Çŋ)((0~_I]UT̞=<{1Fm~ƍiڴz8l0ׯ̙39y$ٳZ~)9~7KΟ?OLL =/^G%nǠ^'77\Y|9oV_ӧ{uAR{vVʵk׈ɓXYY^xVˋ/ȩSLJ⥗^"<<]v=ӎ$%%1fi۶-)))ԨQcxAdd$׮]c}h4Ɠ0e):ُ=UV1b?,S 3ƍ\ruNgֶ׭[ǦMpwwg,ZX/5Mh{QQQƲ0 ܸqj֬Ijո|1d^%us< 0uwř3gxꩧPTꡗaaaeǹ~)9m޼yуիhprr"00NNN|WڵdHoܹ@VVC '`ذa&ax饗s]T*/{fܸqy&卧,W^e8::2n8/_εk׸rX<}4_~%zرc疻 ̙3 ۛ%KZjpBJ=W( <|ꩧ8qg*+ow,ʴ<,2p@իǷ~kvy{-د-ǎ% s0TR'N3{9܈̘1=$GIF@Օv*ֿǝ3<(J$''nrϣI+999(Xnlذ.](G1IDATRWZ=x"M4Ǩ(9СVԩSǓnlkiӆg}[n1=nnn57ҳgO%88!C(ޗw}W.jŋ3n8Ə_ǣ/ҡClllhݺ5Ν3eS}/ƪU?jnSw=NcmmM*UJ888ёz8O:uG}~ѯ_?ٳg9q "66VQNJrrrNj|.((`׮]|'DDDrJXiEOFJ /W^cnYXz~lNPɶ;RJX[[3`VXa,~oZ*JGI$...j{9 "%uLJ`lݺ͛Dttzk.Yz5:u͍>}nnƉX`A `֬YKdddɏ(EƎٳg;v]㌎۸Lӱ|rz;C֭[nfWRl2x |Mlmm777c[]OӸqc^uU?8%nkk_|1cر#]v[r˪c[wJ1%QcǎԬY]vݻر#Kx,uQ1"DeU醰o5>Ņ(.\aСCzLff&+V0NcN(|֡;vښE;f0زe  ǧ\g͚e3Λ7~ɸ|޼y̚5x8~jiǎ,\YftREP?{{{8[8x &aʪ׮]cĉꫜ9s[noɢE7n[nUT3330a ~-UVիe><: 3gܸq]vqI˦k׮ߛ,7Yz2GGGz=ׯ_kEE(ɓY`۶mCRqY}JhZk׮5YaW^aܹ,Yf̘a?Oi첷{Ue˖r߅d>#N8ѣG,Seѻwo5kvGTV={޼ys Bpp0 (G K{˖ֽ}XP 2BCCM>~8*~[$J%(C!v*{(T[VYUsK__:uᘒGYm*ta?MvOaO`w.e)*5Jņ prrbfOTah!((9&R*Uɉ3gt2PPb/CWg}.z@J*4lؐYfuViɓ'Yp!B!BYi@pFq;j5#F`ܺu (lPΛ7w}nݺyfV\ɣ>x[4lؐ ϢEpss͍~{{{saڵkǔ)S={I_~ ,]N:Or ῿i׮ŷi.;;;j5qqq!B!h=C/pBɡaÆi8Faĉ}vV^̀x'ʼ~v[n 00ݻw3qDoߎ^ۻ}3)@HRH("J x(p GP8XEA !!@h&ԙٿ?BƙID&yۚڳ7k5'33۷ƩSؿe/Ƿ~wQܟ|)SpqKEDDDDD 4=ѵkWGbb"QQQ@^ٸqc~gkN'\XV;..ڏsguVϟرcSe/GZZ*r9x >?<>sՋG}bEDDDDSȳgϲ}v fc]#8V36$%%ѳgO׿ȑ#Y~=/1_<P!ɓ'3|pʱc|R)Y `&W^}4mڔzut1ahтǏp8<ɡJ*%^tݬY3Ez';;͛7yf-ZĞ={ر#IIIdddb4M <c|Ld޽Ջm5 !!oZjaթS_| 0h Ê+p:@PѣGӼysԩÃ>j޽{iݺ5M4b0lذ28pإ,CXm6-[e˖RV-Zj 7P(?ή] MddX9s&Ç_&00VZѪU+֭{\f ==u1tPfΜYWqɒ%1}tˆglڴP^/e˖Yy.]:t:={6s᧟~f1iҤ2ĺ}vjԨ-[HOO7tM_q1uT8z(>dzk׮{|>}kF|y}y^ +ls={y׿ԩS}V?)mC^Xm?^Z.mCڷo#55,X@ժU=z""""""\pppiBBBv^v-ے~v*""""""RDDDDDDR鞁l6ӦM+uyw8q+"""""rY(,άY|] +JCXEDDDDD+fm6INNf>He v;=z^zlݺĴ~~~DEE#СCٱcqqq_={!;7/;=҄2|~bccѣG:u ݻbCfM6:| wuwqwqÆ nuwyfx ӧ׿E֭|JHESiȆ Cn<3={W!`ĉDDD϶m4hPUvm∏N:aÆ)fϞ͡C0|.U1c7o[ldݻkT4&LLL$22Vx`|Wdeey3<ëJ.]X|9+3gШQ#6lɓ'y[.uw3`ƍǽˍ7Hƍ=ݛ{3fбcGFɡC<\z 2А%!![nū|l6mڴ!"" @vv6?m۶- _|Tˆ#c޽XV 77ו4Mrrr馛X,^od>|˗ӶmQJ 99*DDDDD|NիWswRJ5j7̚5k@fժU|g$&&;ïxQQQL2C2~xXb_}uX,L2Ǐ_^eU v @~HLL$** 7n?z$::믿zE[vmjԨ/:vN:nuVϟرcSWZZ*r9x e HJJ*k˒ѣG뮻8p 9gϦy@ްg}Kll,#F`͚5uO?ƍ5jN!C*b瞣W^<\xL*˵DDDDD*J@={۷3`l6 `ڵ~ґs8IIIٓ3rH֯_O/k9|A\bccšMZZaaa_Cʹs\6/g>999:t^|EN8 \9wM7Dy ԩSeʧT ɓ'3|pʱc~)Z"""""gq嘦իyh߾=M6婧rw:z̆i-Zp8r™3g_=y "<`ɒ%<裮5j(rI&1f2qFcРAtM,YĕW۶m9pkfʔ)9s˗{se۶m“O>a|'@^̙32d&M"00VZykrrWZ"""""M YnCe̙zߖ,YBPPӧO',,x&O\dŋiٲ%k֬ߟK;NfϞ͜9s駟lL4L3Ν; 6nHVV6m"..PƍԩS ѣ<<^Wƍyx駙>}:/G>L&MDݺu1 Ç3i$V\p#p 7͛={+`&4 b̙ԪULvŐ!C\6{{=_bԩ^˛kT4 m򞋴߷/KkۥuHwxە{ """""R)&$$.@*nkmb-oWItDDDDDDw@W*3fcڴil߾d}]'@ng֬Y.!""""""fm6INNfپ.UYjذ!Ǐ[nîol2,Kioyr-8*Uk$SvհуzuV_粗Ϗ(y_LYjΝuQ*dyDDDDʨt@2j(LӤE,Z!Ν;ɓ}] [2*U$@nn.ǎìY Ҷm[ׯW!`ĉDDD϶m4hsb{fϞҥKX,X,͛#**I&yG!**;GdddO?ݻ'**{\?ʗ_~ɴi\i,XUxw"**'|c7iJs5pq{ѣ^7lؐuq|̘1ٳRSoծ]8S7{ذatz+˗/&..7?fDGG3yd;&NJm)MVHHH 99"ە7[a3ϰ~>̌30~MxSo7׺?""""J@ r̘1<3t҅˗3o8ڶm뽹?\J w*]٤IbccILLdOjqϮNhzV+4jԈ5jЧO:uD- ~̜95199Yf^(JOOIKKc̟֭?cǖ{b8!&&뮻Z4ٱc 02o%((]Я_?=BCC5k6m"**{ҦMU Y&pܹsem?l?a&iiiTZ{s֕TItyGܹs9sL?r/^M6t҅wy=z/ŋ 4MFƍK3++^$%%ѳgOtB9r$O=}!))ܢjbSTo7iJ˧~>4YhQͿ޶߫(N/7*=?""""JáC8|ptK֭aТE ? ''}ѫW/j֬ҥKر#:ub8NΜ9CrrWJf̝;~Dǎ]322 t2a^(f͚oѢCIeʕ\{3뮻UVަizjzMiڴkiYʜ{Ѿ}{ϟϮ]8y$k.=Ky9Zj:VV-4\)oPDDDDJWȒvVXk7n:t?ʮ]8}4tޝ wm=qѨQ#Zjѣ2ee/w~=z4͛7N:0ڵk޽;_|OfڵDGGkԨQ-[Λo0,i/^L˖-Yf <,]u4MVXwɪU=0==u1tPfΜYWћ2;NfϞ͜9s駟lL4v&NȜ9s"--/?Z*-ph"=}9ڏbᣏ>owꫯɏnWr<o\ɟApۆ^I۱}~b]_o~7觧\5,X@ժU=zJS#GdҤItO^{nOg}T8?""""OpppiBBBv^v-ے~)WFpp05'dʕaÆtЁm۶رclݺEtDDDD^W3r̟?hz-_犲ľ30nbal޼84i6[*].%%(u ƌ3<ëJ.]X|9ͣgϞܹ3]v9ѣGӽ{waÆ1sL.\Hyy衇0a-""""":4MñZXV~aVZg}Fbb" >GaժUݻm۶1qDϟʕ+g,^x@"""""tUDBJƍ]N't ՊԩSm4̤jժR~}fΜ̙3=1UDDDDDϢRpW0XA4K4MFƍ}]M Rws-t:q:Һu*hhтǏzKsڵ("""""RaTPZhA&Mxꩧ8<>v+V0uT~vMСF,XW^ySN7̭Jڵ;woWgy'|'OqFz-Μ9:d>}:aaa3yd6mT,[ Əϴi ::%Kpۆaczimi߾R { """""R)&$$.@*nkmb-oWg EDDDDDQ)""""""^Q)""""""^Q)""""""^Q)""""""^Q)""""""^Q)""""""^Q)""""""^Q)""""""^Q)""""""^Q)""""""^Q)""""""^Q)""""""^Q)""""""^Q)""""""^Q)""""""^Q)""""""^Q)""""""^Q)""""""^Q)""""""^Q)""""""^Q)""""""^Q)""""""^Q)""""""^Q)""""""^Q)""""""^Q)""""""^Q)""""""^Q)""""""^yiZ}] "N> |] "N> m6[""""""6%Zp8|] jV*H y=妈Ha>*""""""HHHHHHHHpD`` 6[*\Av,222:QۑP(o9d(&; >zčv$j;Rj7R%k{xRA6:>H" o#%QۑP(mQSRP" """"""R9(((((2j2Ӝ0Xd 7p~!K,4M.f̘3g};,[jժf^u_I.pMh@hًN"sx >?"J_ ^|`U\E iw}#}]d)z @a0j(Hʻѣiܸ1Ӯ];^y&N)00yѷo_jժ@5֭U2$88jxx$ڨSjX0M`{Z٨Z<ѹ(Q%,&lB IͻzXP0 &MD\\EZ :ڵkIJe;w.;wfŊ4hЀ>iӦ̚5kgϾxbSOѸqcy7^:Fo߾ 2]vaZ6mZ",, 08~8| ~6eG>5k$ d>c֮]JoA8}YCpp0[&&&ƕnرۗ5kYp!Ǐ^k׮^s#Ow^z),KmJWRbٷo۷g,^#].]xǹ"66^x_׷X44^ۜNV>xw7`̭A,"!'^m4S̿?]ޏ< XPM:5#< sgK:@b*ත /C']XS-dr#߭ mnb:cGr ~8x))&?݄kjyɋrf]~ `'O$00^zիf<BÆ yݻ7i?b&͛70 ZljoϏ&MϹs8|,ePV-zi,^o .kƑ#G0 y֭^{-999dffҬY31dW%dddРALB|}[ 1MBǎ &==~J)))XVn6f͚j4Mڵkj0 W;q:)*{߫W/BCC>tr=M4mڔSNBXX/^r8\F^۳/Laa@׸mҬ>P;Z;S=BHBHK׍wIv|GcI:  gLьI6n33*MskөX +5 7™3#7۳;_Wj*;4hs=axp~rss3f C aܹX,aDDDp8hҤ kBhh(קe˖Add$999A pqnJvL矧_~|GX,FA``Wm=ɓ'ӿ"##1 =zH;vUVaX9r$k׮W^e˖͛y'?~Xz'?XNFqr(RSSyW7ovǹ ;;O>855Ӊdǎp ۗztR|A:wL֭dݾQbb"v???:t@\\f]v$$$t:Z v -U**2;}طo;={d|t֍aÆ?O222xbɛbÆ tԉ={ri޴)J5Xnǹ6mаaCbccb„ 6~ѧOzń 8x R9e+eԬb4zM>[ld[3tո+ aԺ7u''s{7049@w^>Szll+8uk֬tRF rrr\۶mcذa4ٲe ͛7k׮w}GZZ)etvIϞ=yIKKcΝTVQFѬY3NkB%w6[ޏonݰZdddpIJmSER9ξ}HII!775H*U0 cbժUl6Ə+m۶1aZhAӦM`Æ ʪ}``] 䮻bѢEl6LYd ϧe˖vmqW*{oX뮻\z߸q#zѦMV+qqqѤIN>͢Eذa?Rh_*,+.4kcrC >O38n5+v=I .rvd'% Iu:<KҼE^Ͽ¯cb5 a7uMv UȊM I|㟞2M k*'[FW%  yAXm?^Z.mCڷoGQRP3??? x'ٿTHyHynIdM"/MחxmU8 {}]?#ճKMBddd pvҶm1ݖ})""""""Q)""""""^$:"Hnn.w}!"""R!8srhzHMixқGJT^ /_Tp%)ڎڍGIm# 'TIm#Ϊ)ZhχfeeR>v$j;Rj7R%č.TP%~_O*6|@fdd迺R$NFFFv8j;Rj7RG?V/zG?.$LKCYN7*3NB[ܶǂGK?o-PY EM#""""""\YT wtR̫I&%edPDZ`: P>ɢK`!"""""gR0s]0,; +k:ǹZ+~޽2?o3uDDDDDDvEK,s Kd+A_QT:(:4 -XI ._"""""RٕehqvqXT_l#Yz#(%=VTTW7 G5Kȧg`uފz"f1 V`@IrJ౤"0j6J9$mv47@wHDDDDDp붶Kc/-]M %w!FTkm:l: pUnv}%"""""9ZX_+uGW "w' vX ֶmKDDDDDtVh/P49fA^Cdž`?mAlh ٠ 2sG[-l$"""""^g혵@jHAjGkAF>@OCDDDDDR5=F+뢍DGk1IOGNDDDDDt#>mFΩ/?A@jJ:hSu]X3n+hg^i[j٨@$H""""""Gb&Sh{) $-a.8nfT%V %V d2$"""""ZhDZV[rFY_ dmjy4&$"""""2hjhgP+Zm@{ qRsdWIpc 94UcX tj+cֺDu-ikEG ӕM/J쁣L&J%JJJlc֬Y>}:j5K^ݻ]ƤI]E"jޱc쩵$YmeauqR1ք9 ^"ȵ?ksiT*'mj&wqFzӺ[o/8Dz(gxec_:riIItRFsF{i6HRAT2fD< r蜜|Grv; B޽۝;wvĈ طo/|Æ Cxx8Z-RRRuVϘ1cn̘1yyyήu'$$ļ^\\l779!"jR&1Z|piM}ؚJ$n1l}l<{ЙTqEEEUVR]o/iii8vGDѿsC q%\ {OѫW/ O<|}}ѩS'9׵իW=O8D &J\Lf:&dN(BR8 Є:ӷ6eւI¬M KDԤ5R{LWee%.\[ n ̓9+?B@\\V\ӧOCPছn¬YQ[o1x$JPT6-H$P(P(Ph4h֠u5ccrh'S9/LQa^}Uܹ-شi4 /^*$ ϟB!",X$lذqqqXb:uXήun;cث9LTӳ(JP7֩d+Fٛ<ξZ km,X$"j_E@#))<>ؽ{7vލ3fvaJ릛nB۶mq%,Ylx`0pwXLMkٳeήCT*U"KM>uZf-vM2{M^BDhRJ0͍g3KHHDDD'0?ؼy3._x8׽^znj˗qQ 111ؿ~]ꫯ2AT6j5FcN6ً,_Q_a~g;ibD)! +\Gd2L:FC?w}^KD"ɓqdee9tL^Y I\ZyC03;;~QF~j͛(R%JբV't:]Nמ!lqB* B*ʽ.@>#0aBǤI+Vfu=rzyM>Q.]4<\Η7N:Μ9pA9sFj^PU7ofLΡ1Ԓ5nj* S3銆wVijHR %T )*F\*bdQcԨQ Fm.]?-rMH"kDQĒ%KP\\.]@IIy3F///!<<N7~GgWv7#** .\Y0tP={h4M6曝]‘#Gz+K CLL t:ǧ^@5d>Gw𑦦T*zіX'Al1ޱԩv1͠!˴2ʥCQ]}$]72럿?sԩ9?~;6n܈"99G~~0[ \.G}z رcXXX,Yw^#Djj*ڴiٳgcɒ%u(J,\2 6l@yy}ݫɱWUMMwEEE?{VIsI{믿e˖ƌÇ_A6[kG Z_-Q?yUP%Sh}vJ) wG/\FtFp5nR".TS)C"m~j$SlEW7Z*SKlII7M&AIϗ"B+Qo߾8{,VZSSSLVB֭ѦM8(]7nѣG!z聻_ekKM`07W_}~op)( O<ڵkL,]U!p $Trv<[Ab}esIEر=r96nȳ>e˖Cw>~b3FgH*YFg욳ўET!؞~EHޕ2 %zx(R>|+ ^pIP30(:zch/s}RNp( Up[7_q./Cto0qouv;V¨Q꼟s8py;//qQ:׵G{gojgfdh̙9sf!r{jnuںu+P=s=e˖Jg\o~m[R._O iўHΪāR\.]>QEgWrJZ;{wk̨([NbˉB$pa TPmTUrp@ lhO6/D2;"jP@ TS;H;lﷶr吮Kʅ۷ƍɓ1l0DDD@ٳغu+֭[s4M6aРA6lXz_شiM.@6,WwK֭[!}Y\K5^[hg@Ls͉"xNWgkt qGV*tUᷣ8r!^rȥW?6ֲBowE_B2X﹏>(&MtU^+W7]nnso]5GCth?K{q!>|չn\3gb۶mؽ{/ňҥK~svul>h4(--eN^^^ؽ{@ +FEXbi7-?>'//W J<i&\G_lڴ =^~֭[i&|72e d2ZjM6gq]sӧOǟ/9rhݺ5x msK/W^ήU ƍ~$&&bӦM3gNz5qw ((Z6؟)шz7]uj***\.Osd dKI b XU!rX~0uT8q7nDTT ^z% 4NB\\BC_#Jd۷}ɓQYY{:fȐ!5kfDGGGFFb„ 8~rr9BBBpa_ٳ'&O/bڵήգ?S'NmVoN-`@ii)<==$R ԩ[ E :toĉС `Μ9/0|_|s?`0 ܹ/ǩZjAp|xof[ h\{E||}j*DFFBTb͚5Ǯ]/B*"22wä{ػw/-[l$L }g~tRjժFywZ.FFS^^F:]:5D"ǣ<VX{r۷T*E\\́j=z4R ?Ԟ={PPP'|6l>B({0Oo111طo>S8qx7qi,^x饗Ю];}||x^}1b >Wƒ%KpQs>}:ڵk~Z+WDN{A*Yv-ϟSN9_I&a׮]Xh o>}M}_Ѿ}{ݻ۷oǨQ?SN6mZ-֬Y{{ĉѻwonj |.]W_}ZٷY5gʒ7իWo߾xwkWzSVQQѨ1M%uvZk<ƓYfᮻ­ފ'x=w>|8DQDjj*֮] ˘8q"&Ncbܹر#o( |HHHXxsWʇz Fȑ#! "hu`Æ [Ѻukl޼FÆ ?dt  6`̘1hݺ5\>ĉ-@46mjȭp9[nźuСC̞=/"t_l9־yڵ GFrr2>=aaa LA: S9SLFc=bgf؟)kcFNJ1u6nߠ)((~~ _~%n&رF ¶m۬B:t7nDVVRSS!b.a7||gof <',G"@E8t#F*Z2 G^@^f͚:iRf|ޖ-Uvv6pL8[FRRR)(M>?<>>pwwlj'lJ'ELL ݋DGG%R||}4ϟN'|ǏGPPDEEaԩX` >su=w,XoooL>)))xW`0:tO?N:97NC~~>W^yCƍ79sơ¿/<Ȩ5P(bҥܹs[ܬ3eM.]O 773r=|׉YA`ϴ-XlOٕuӧСCh^PB^% _VH^ߢ_@@``@rss]"z?xw "j^^^ؽ{@ +FEXL۰6;gV#vau2}|RRRnzf*"""""jL%ӕ" w7}]v'dwXݐ]s!11ٷ%D)H0uT7KUU2u{zx OO?kݻwNJ+`4}K\K޽;""" B-N:rhNg""""""-ڵ Zƅ 0߇LO1plv!))ٷD(Ņ W&~~~ξDDDDDD.%zxx4kՆ, Ν~L<~T9s 11N§~ 4w;b[gΜÇ 7 ]E:*q#l#ԫ3ztnK""&\.wzhZ2󫷷7̙u!$$3f'|111!X͝^}j5^{5$&&b֬Y/0vX_/> `x n MDB|kJ%xeggߊz51n <4v>xa>~u&5]uBg`HhtNDD%JR]Xكf+}u&iH9a 6 f\B)Sj*|*|W޽;=zMWr3:ct zT*`{>%s(zvR!`DIYR.faC/rvD*c)4E9(*.wvкںƸuHOj e啨}[9D1We8y"~rFDtCrR"X ҠP( .Gu˗?3FFF"00qqq}^GlllW_tf~I}Q]^;!IQc?Jk|!-(bO8-D@P$>};fĀٿ~r=(:zDD7 MG]܆"} om'NDnpCOD(Dl hȽ#̼B>zvn _/ze/Qc1Wxz_yjw7UVaش;+XdR5/vsRըD"`Dҧ <(*)wKYvzv-zK 68wX~NNjT%#D[kxUA33A"`M1OWz{Jc?.eֹ{̑,jh]])J%up/^j\ú?bF.`;x,2FˎxlۛTsLŞ`=#ߐr:=t'JJ+͆eWߛ.~ޞ/qLXO>w$v< x[tu&"wCm߈x̛7gƙ3g] 偾1QXTRobT@n~1a}1o7l r pSL̜4KKYvTj!* wyH: Apӭ~ߙBDG *,F be!eC’z ccD:w ^(,)GqⲺ@Pdb=pS1j@ҧ+^׾Z2S^*x{}VDD\"\^x8p v ۷/r9yzGofϞ 9?rM11[Տ[kl) )i})е] F#w-{ znnrsw@oȤ:]3-@!(ǒ_Frj:5:yN $(B_(r9g"D5v륐c],2^W{.icRZ^_cʸ8s9{T(tlfkrGO? . ''ߏǏ+mۆ 4{H$̞= HOOG.]T955 g#Z*mhb: *}G`}EIpwr`ѱMF ݋w+@+]A/ؾ`Y^ϵROnYmIiEˬۻFE FEVAD^A2%Xˮ2e\U\Z֧w&@㖁P#=;_]Ú-qe`,n J*g1](>]0fH/#;ȜP^ޝq>(`öH<~njF _/F\êvp/ax[j΄(b8hz~s+ݐ qsݳ$kN B~pި"t*N4W֍hamZwH\ެvnA*"`W"""j M攺kQaݭծ'஻B߾}ѧO 6 EEEFII ٽ&""""E,@r5PTT(q}v$&&bҥpwwGpp0lقD=z~!֯_#G_~AV~;vލcǎaҥmw_Ba {8lmh4(++(8w\ۉjc |zꅿ'OF֭1|̚5 {FUU^|E1tP >aaaV˰E&aȑ AJJ 6nزe LJ8vaRG) ATO>$rss1ba͚5RSN8ϟ\.(HHHAп9r'N|裏nݺtMapY̞=c6m}Q<l$"""""@ZZ- ooo_JҜGBBMV# 3uo5tJ$ ¢(֨246ш8ݻ| ƎkBP<ʜT ktaĢEoBV#!!ݻ7('>>zBn c߾}G`` T*qС.Oz???gΜ/(JDEEa„ سg&DDDDDd.@D^͛7ŋxᇑcɒ%HJJ† P>.\[o/IIIP7⯿QQQqe@nwԩSرcN8u`0_DnpQ[6lo9b*}mb۴H|ʮ>cbb9Tŋ .@&!<<α#<<,/^`@XX Ba2p/mVy*D*!*x+x+KĴ1WW\N9]Y>4ewh<PT Χ]v߿?6mFBBaG@LL ^xnHNNFǎF#~wos"""v5 ar#<<>>>Q{nkCE`` Ǝ J;>}`…ӧOrSLA>}ЦMk&L@xx8;f}K.7GY.p>AII j}9.]`߾}MRgG)q$G!]=:OT>ӶeU")?acbbjm_5<==mONNT*JpIcǎ0 dx" @fYxǜTZۖ-Zs졇Ru- xKh46>Sr D~駟])z 99y bzOubٝմ mӺk@X/su(JsQQQ@ff^Y@r9O?pp* n| wJ3gXm-QLDrD W_}???322}2 za^Ų2 ??AAAv<<zD-ʵnl=ș ömZorjダt:___zj)oZ2 Ѻuk-[mNg^7c/X-,,t """""rI.@?zrv5)))ήKrwVř:sB\\o KPsvgJ&""""qe˖aʔ)5Z(,,w}Tg#222<Yӡ%%%4 ^^^扯cbnb4QTTԬ!KR zq$"""ry.@;ptAAA[͔h4QUUh4ξ D-NQQ <== @pp0T*rssQUULH:^Gfffr/_N? hjDDDDT@:jQV j3gUUUDTg[Ԓ\*uApssCee%|}}!J bleeeДDDDD7:ID- PTJ` nUtww;FSpܹZGPPBãF:Z F'O:jsH"jy|}}: 3 `LE"$$ѨDee%JJJz= AQQ1//^^^GYY9F1*NTAкukT*NKDDDDu1$F)..Fii) |}}Vk"Z^^CR@zz:*COEh4j`n5Z1FOoooxyy!99UUUξDDDD-QFhZJ5҈r!-- oIP(`0HDDD ɔCEL#"t:] QQUUU @TB7iOQQ.\FDDDb0$&UTTooos___T*^^^`(>>>B@@@T*󯪞vj+(QK1DԤ???梢vek={39j$''P @oinXDŴ m:c@C@C@C@C@C@C@Cdή *GWB*nΖB_eHT>}]v'dwXݐ]s!11ٷ%D)H0uT7KUU2u{zx OO?kݻwNJ+`4}K\K޽;""" B-N:rhNg""""""-ڵ Zƅ 0߇LO1plv!))ٷD(Ņ W&~~~ξDDDDDD.%zxx4kՆ, Ν~L<~T9s 11N§~ 4g( --r]wH>úu J """""\.wzhZ2󫷷7̙u!$$3f'|111!X͙>33Ǐwm^;رct<V\ x93-p.Rj={ ''m߾}Is@N0Æ ìY8P(0eZ ~- _}wG^UUU5vFDD`ܸqXh}O<{׼%Z %4 f[.\PL[},_cǎ޽{D`` <^kޒ ={6222~z3g`0`ʕ8~8֮]>}8kADDDDD.%H[I]\{ i4"((蚧;| z=n}#GꫯDzz:VXVZ5 """""wCʾşi Zm۶8~8^uHRr-ή2vMU<1+|||l&2 wq6o Vkޯ "***PXXhn$""""K@k l2/^\ 8мo߾5&VM;v_QQ˗/6# """"%Ȗ:V=|A5 qq!.. ,&Mz^'Oدzjvm2e wwyضm[? """""r}L]X૯Jܹs;v70OSNT$;;uXJO=ӧ O\bn,m")n􎉉WTTP%.\Z]g!˛j5Ə_c_yy9xf+zb9 0Psǚ"}c#"""r&BQo$''P @oinXDŴ m:[ zc t \.FirIDDDDD  M攺cBBB/_^wvuDV[p///=zǏǑ#Ga :QDDyHRBRRpalذsOhYj111vDDDDDZ\YuqD"T*M7݄ 6 K.Ř1cAϞ=t$ d2111?MZ]y-šQQQqaHLLҥK`lٲ8z(>C_G/VZnv޽ǎҥK h۶-vލ j;v /2fΜ JL{ݻ1rHsZ˲md޷z+/9r0:~k_~IIIDDDDD7M@ )))hӦ z)L4 Jw wwwT*#GW^1ydnǬYлwoTUU_?Cf8q2e  ^xśL&SVeet&EgAϞ=oUV6ۺwj~~~۷/ G1JDDDDDM]XQ qqqP*(//ǓO>\1aaaXf @TԩS5-((!!"0h G'=>#[7tSeGV7@߾}a4aIg'Ođ#Gpq(5oDQ(I@ZZ- ooo_JҜGBBMft:D5ZaQkVhĥK0i$a̘13˲2 :;"""""؅ fffbѢEx7VXիuL~C~~> RC5 AгgOX|9!Q^^^_#X+**QB`0@VC.۬Cзo_m .9r;"""""j^. /n޼&L?/ǒ%KBs[/ݻwcѢE(--ƍ_&LZF^^9/^h4"-- qݺuXt)h QQ'|C8s .\^xjl2Z 8})))W}y ,ցVIbi[6-++O}Ntxbxxx<~d29bיŋ0  C^^t:BCCP(lUVVIT*h憯V–-[l#??vnֶ\H󈈈^,c->W֍hamZwF i|||P^^ DGG@ nnn1FIy%<<j5ڷoFLDbWj:eee3fu2]mn(--5S(`0+Be1$"""""%%SPgk jhӦ J%.]^???xxx`0r4%"""""HӸ!##nnnF<ګ R}elmt:BRD^@\$;^_ .@*"44yyyɁr9N""""""%Z hobYY`n2 /^th%@%Z h2==jQQQjPTE^^JJJS ,@5K(uǎOT`0 ** ̄)""""""eH{->>>V>L^@Bכ1Gaa!|d2eADDDDD\"Եm~˖KV['@ABh4,ٷ%DYXX֭[}]v'd^Gzt,컰EA@B;w0 ξDDDDDD.%HDS"<:u ǎÿo1֭Ù3gpa|LbbbGa߾}XnR>/ZIIIHNNƏ?],G*bΜ9HLLĩS駟߿v<** )))HKKu]vQsR(Dtt4L@TVVBTBd2s;b֬Y EEET*UለK@rE!3z{{cx^T*g}///<裐Xp!/^3fmۆe˖]v3gz=^}g#g?_~0  .DϞ=1{lg1j(nj3{!'' >c<#V[꫟㙙?~|ދ;ǎ:eee6z@9DDDDt\"JV={ ''5êqC@N0Æ ìY8֮]; ӧOǁ.-[֭[#55cƌ12ct zT*:{@߾}O{3åL&Ð!C_b׮]>6l@۶mi SLUW_{8zhgxUUU7n-Z:]V;N>/BC@Ezs$T**** | +QK]X%I`0mpB2%o1vXݻ1SbӧOCDGG@D@fsix̛7=Μ9sUyzzBVc۶m8p?_Rr UVH$jR0~u۽~?tvUؿ?t?j|ҰcSNEDD~:?DDDD\"rm7Ǝ;п {/yAI0o<<3ؾ}U "***PXXxyy>ᅬ~zY'@YWӬRe2l޼Zʡ!"o'Nĉ}2i5K@rhDzz:T*{1qog}Q#P,^|<PxzzNBii)wEb}}\.1MSFxx8vleqOXX ٳgcÆ x">Փ̞= HOOG.]ХKtJ~~~ *Kcո0etm6!##/nݺa޼y@|||Z-;%K4ϼ*Э[7x{{cذasz=n7.+VRSO=???$%%a())L>V\ \g駟ɓ'W * s΅;v؁7x<Ns<#;;M75bn,m")n􎉉WTTP%.\Z]g˭XTj5Ə_c_yy9xf+zb9K/P pǚ"}c#"""r&BQo$''P @oinXDŴ m:[ zc t \.Firc $u.@N6)u!"""""\ i8kqN8Jڵ+ۇ쥋@bbbɂ&N?@ ٷz GDZ~zx{{{^2My%%%_~#  V^ٳg8GRa׮];vmfC~իW8p&Nh7ѣG{"**F9}۶mCz7֢ļXnb{ITq… .\8sq6ntV]F֭l2HJJC"""{wO>6lxyy]U=% R)n&TTT`Op]w!++ xGߣ0~xDDD[;SO=ߘ;w.mۆBHMME^_cÆ 'Ν?j m Tȩx衇qF :yثr}}}h"̘1Xn$322c̞=Xr%lbƍC߾}!"j;h"˗Rv1̛7C :Lt1Mm^ʿ7DDDD UZs~iҪU+|sFF2s9h8F۶m!<<<gnS(@F,Zs}Q/(0HMMx{{#''yyyIis0n8 G׮]man.\ɓ'm۶aȑM?''֭^Grr2Fyps̛7K,AqqZ޽{_cٲee˖aÆ ۬ڹ0x`dee!99;~enִj 999ִ,5~K3gݻ AK/PVV3S(áCpDEEcǎHKKCnn A@6248pNZgL#ku***1||شiBCC P(pA$$$`={6JԩS3f z!|(**TYYY>|xV^^AaĉxWѺukF̜9~;w_gĉP(Vs~7F[lvW7g:u*_(W^PTs8Vw߿?.\AUM@.XW7|VZ5(]eeϯFhD\\{1aرgi]Ϟ=1aڵ hw}sBV#!!0ߟ[n۷wߍ={bu9tkg0sN9rݻwc=ۣ[njV7ߌgyCZ>Gf)##AAAVҐ7~3f &OiӦp7sؾ};/_h  ** _`c EQoXlYtEEE8s AT"** &L={m۶5O???{0OXs?~- *++R$_y[ƻヒ^{ j>>>殮mڴANp9#88;"%%F9r$1` 8G}cy^fKBBеkW`ԨQؾ}{WxW3 ''\%K0p@ >ӧOGJJ ^y& >>>Y'[1qDወ\젱3?3g ^|Et GźuaonݺéSc8q֭9s栰: lݺVѣGlo񈏏رcm>GhĜ9s[ԩSXf bccmɖnݺgm̬DDDDtYA`ϴ-XlOٕuӧwLL>SW,^6_p2 u䠸uZ.^0A!44<5eeex8GϞ=`{V_}]oג'//ϼx5?RYo$''P @oinXDŴ mӺk@*h4a0L&CFFF h777hZs^ 骺t?^y=DDDDtp[(H$v\d2HRi|}}둑lj :Ph߾=4 d2$^]7V.zz"HtP(4H$PoY/^ޮ.-:[egVE6mT*q%z֗,э%%GH{n~~~0刈Vu87ѣG{"** Xl;zQD̘1|@޽`~E}A'NJP=_Ν;~ q^x8pOƶmп_}ugcא!Czjڵ O<݋ݻwcԩW""""]X뛼v iNCnn.T*Q#@qt;w.O󾠠 رgFll,V\-[-Œ3u!!!iiiV;v Ð!CjbA"XoybҤIQtR̘1 XhBCCq}ˈFiiz۪_h-<~%%%;O?^zɜWϞ=1i$k4~g$&&ĉ ݀\ASg/ͥK J 䘻:ҊHjJJJju둜 X!}Ņ pIa۶m9rF[nhoKTTF_|YYY0?b̙[ѣ1w\\|@srr\?Kʳ1 s /P#޽;9|U"""""%HG P^^ooou֐dxb6 )e˰avmu̜9wFvvvZBNNy,V3[Сj@bb":tT;"-- uοWW{y^СpB_xRpytH-HVGfF5֤CV#** Z* CII |||d+QF3g΄T*Ő!Cd̙3Sb}ٳ0 HIIATT|}}wc8gCWEE@Ba(O0bw}h4HHHhKDDDDt=s^RY J rhDxx8|||PUU(Jd2e5Ht)))PxW3 ''ǜ'ND"ABBеkW`ԨQؾ}M… عs'#$$G#< ("%%x544 5b+ܯSN:uL&СCqqsXd v܉g67]X+++m۶r K>>>N ^*ݪU+|Fyy9ÈEhh(sڷ~xgi&__|R/G(V7Q+Ï?ooo;w=Tw͝3g^z%lݺJXhnڠu|ͥVغC%"͛O?* w?\͛7Caڵo[|w]""""kEfTJ LۂŶi^]Y7}zuӚ  66 8D-B^^ykp6ݝ|'TJ4>>>HNNxehiۦuh</K.-m[Ӑ oQKD"Kܞ={lo1115YB\ + k"M6޽;y>|'wAXX.]ɓ'CЩS'tjf<Ŕ)S0}t\|1L~˖-Ê+Y'HS(n:YjSN8uTH~'O4oժFs-DDDDD.х@^`0mprzj<#HHHsLVC={ ** E ~}v؁?ѣ`0 ##7]vEqq1.]T'0(ȑ#0 ֭[אA3M65׌%H[]\{p1aT*H$AcǎENW_ 'ѣG8q.z)deeaɒ% hᅬ(Z q̛7eeeu3M,,,4﫪Bqq1\QFaŊWd9BII |MtM믿~{H$5(b8wUwww޽ӧ@*bС`HRpwwǝw9Y;ݻw;*DDDDDd%@^ˀZ#..wy'QUUoӧOGJJ9)x|ױgϞ.rJ7o>3/M6/]k׮\YW 9T*ŨQch&{DDDDDx. 4_K`CmjFpwwǃ>-[E=xFPQQ G:XåK'''uKOOGAAc L'N4~Pݻɟ5 iܦGhh( & -- ˖-P=iΌ3,t ".^www|ؽ{7/^\oY6lYp}ɓ1c ghZdgg㩧g}J7jGOZ-~'<裸t0{l:tgΜ>gҵkW $''_9nqVx'1h ;w_~%~WsWSL; 4c00m4dff6.WRģ> oooիWC*?l0l۶ͼݻ3gδy]Jl}'"""zt h:Do8p -Zx^χ~ 6oތ#G"&&{/JJJe~R*x71}:NK c=,j7nIDAT|&LڵkQTT;___s8̛7ݺuG} (_ܹsGAvv..]ݻcؼy3Z-FӧcѢE8y$~ZKG}ӦMCii)>s <;wsnVBEwi>?((9~7Ql<DFFF۷oǢEjÆ ؾ};,XB;v,6mڄ۷cҤI|nj5k`˖-x뭷T*Tn 0 02EV EbĈ^ Vo{VT*D"7|nݺA*O>C P7`۶mشix_g,Zνh4Xv-^-kaÆa…̄(HOOGzz:$ j5}@"`0`0@ѣD=p `0 ;;ЫW//?;"88Xp!T*xxxK.9s&JJJc?Āj*W^8qΜ9Z}ѭ[7( qqqAll,N8V JW_}?^yaQ_Th47Əߍ-kwu,XZJ\t >|8Ə5k֠ω'bxy|l/ЂWAJ=Z"U[Ekj[Z[֪(jmU@@ $$\pAfwG%@dc;;g>QZz~|ALhh('O?1˖-#((mcjkk>|Da̘1785;o ^||wɓl߾hLƾyY`SA:sY8q"޼̞=FÞ={Xhzze;廊-[k#haa!C !((HMWM&fEQXf /^$++3f&x'?Q={9sjQpΜ9jdggǨQ+zEQؿfKMz^z%iӈeƍxyy?NiiḯgΜlmW]]u]<#<Ý[B!A@vAR^|Ey|}}`̘1ǣ~զ`رjO:dee1zhƎ 4^%j\t~j9v:u*Ǐ'22R@PP8pDFn( ;wdժU߿_߄ ^^^bZ6qqq|{OSWnJuuzɓdddW95b`ɓ(lVH___V\ի5"22#F5\Cjjj PI\\;vL2ÇYpL&:SUUEHH-Bꫯr׳tRz! opݎhdɻ˝wIXX/O? /~;os}lwީ6h4=~<|sܹVo`|M:k_WE^_W?S/^^^f>cF#vEaʕ|fzaÈ_Tǿ lݺg}g}ooopaFj\^}U:xꩧ ד >o[|||سg| jL8{VKVV|cƌaŊl߾N=*c[ȑ#XV~o2sL.OB!D|ƫ&5M;^o~vΝ;wwGM{1L&S <ŸR*++&`Z^U^^^bx >;w$[!BMXZz_[^.88ӧ9w/b2l6j{{u?۹U3q ko\GîdxgU`XX,`0`0d%$ΞA4 `!UN8_FWWE+Ȧ.hZUUEUUf3g`0T%8hYOg֫x=Ib4~/㈛`ÿuVe$ΞA: _ j$qem1|-Y&*ju{4au$um&~X,DGGc4)..j6MѼMdFsqf[8G;9$;"3H=qw o<⿅3 d{報kHHŐ!CX,N'W@^s5fvmh4BBB_֭[OYhQi>|c矫xhktժU;t+լ32e _`|?GE;=Ν;Ypay/a._Qk:Ww*.jlL g q y\Y> ƸhMX;jvy"ٚΟ?/>}hY^9 Gܹsdffry3f 3f 33C=Ĕ)S5joVjQa$%%Zu״bs=]C0`n._̙3ٹsg۶mȑ#m. jo|lllSWW6JHHh|[V\B!p%8}],))d2bח`tRdvřZz~|A ̙3ٿ?]ƌzOԯ; ɓ?fٲe^Oxx8;v젶Ç3p&k/EQضmg׷Y,/^̂ OqqqZQ{*B!Bt7 7}%;;0ш?!FfEmm-gΜ!((HQ3UgpY̙VEQ9sL21j(N>ͼyظqUϷiӦƍ",,S;u3:+X,(>|8ӧOf ݎn祗^pm  bԩ$&&r]wEiuy[ݾmqik]pvjuڊڵk{MsV!BHEQڽ"D[t޸BN( &((z hTlك,"##1b!!!\s5I\\1tPwEm˫_ҥKy衇(,,䷿-լ[HH-Bն9c !..^ϔ)S8|0c2tߟ*kL믿믿~j~mO[ۨmC[qQ!B[\oaZnիGv4DXX h4Z^eX,ۖJ}Y}Y?Ç3f O=TUU~zrssYt)kggYСCyW:=iXb۷oosZγ>o[|||سg| V'{ |Ժ8t#GزeKdkΝvmbƱ\޴*ۙaW2e;wJ(oС,_''nfBQf3Νdggc:Uvٲe-n*//wyGw!wmzz:SN%""ٹs'ǎsfꓺ"n:rD}|#&xkZC9jKSY𩫫'p{ ӱZj/z׳o߾. qot'~!o!Dp x{{cZ`j3y]wŬY@ף߿?qqqN'^^^vm$&&λQ5z=K.Uc\^^… jbCtt4]w~;꼜)fv]&'庎;688ht:п,YBppW2βZfU__Ч  8AaFk@5`OX'.W O:oҥK Bj9}:uJ G 4xFngڴix{{c0(((`Q___|A~~>6~8u4>EQRXXhd=iȐ!$$$(̘1a׮]a0HLL.̚5/<+۴gn1cpa6mMclF#yyyʕ+R^ }G=#d2 DQ~=j/݆v^ <w uTn_p LGo@Q̧F,%h4Z: /p4SIbu-Hh$++K}|`` S\Ge^=Pz*++p'NbH(Dv)|MfΜIll,|'7Bk.233N8ѩf56lgϞl6k"6lY?V[, eɌ9;vz尭ҤgclW4 hZ)))qS3tށF$P1U%_l;X0(n)C`W֗eOب+ Ԝm|VV녵 !džpzS?hZ͂ݮ]^6 $4(%yolGFF$''o6ClxRә2e 3gdԩ;v={ȁe7l$$$0|pGRRseÆ NWXXɓۻ//[[[)SL]]7nu9=͛7y߿K+F:c0C+ z է<Є;4s`Se5@g V_e@}E1rR![ff&b8u]ɉng˖-9r$9r$|ͮnAHH)))l6o$a{kclF#fBQ6n('IwrVp?Ch tqz4hAc'(FEkr?݆Fghut}@ !HSnT^^-[&66;LYѵ5999f]ȞcZ=>4Tԍ' 슅KEۚ5;5`G7|Q Qj)ۄb52:/4H+! BxQRRСC3g|V+!!!Լ4 FK.aZզp[t/ĉGI8pj*+SOVףJLY1Wc AP(z.`7w @B=Ps+[E.v|# \*ڎF'8n)\꽖$BAc͛7|r|||XhQР;w.sUf֭[G~Xx1ZVm8p˓n 99ٳg7رc޽ &$$0i$v;Y u&~\ {Oxan6f.( 4Ԟ;pn3S{>3{t ! p.E.P$` I`'Yk}]ֽ$BR^uf̘All,(BYY-l{}}="22v;>|Ty UVVWjΞ=Kvv6jΔ؞:u 8w7Gx[_?M`{HnP{h(vG"$b#ZWi |ñmXN1ˎP.1G`kRu [CWWM>CccbMa&/ݷo?;ΝҥK^?!D7:~Y~ni˵U3îdxgxj I=3] %K%2AAAN*`m|Yi7y93ҕB!BH)B!)v p !B!"rR!B!S$B!BI B!B8EH!D\8ѻH=3U:WWOtw$B.cZ]]E,3H=C{l6ٙ 444h-t|Ge)1q -Wu;xw8{g8{+swrRӵzW_QZZmˍkiNgțn9s /4{ػw/< /2C ;=z4ǏGӵ4c Fvvv˗oz^{5ƌÁ~ΌVh4WE`pZ___9e$ΞA$Ξq:zɓ'l*,,lT6l'--8GJuؑ#Gh4ɣcs60[Ffo|ĉƳ\s5xyyDyy9-Ixx8oJRRRׯp$wr`tDBz7g8{gp6=RWWh~Ew_n{g򨪪;d2鈌DѨ \S7|3Gnwzy^^^L8LqnJJJl^86o̳>OSV\IUUUpEul._GE߶}Z-o8{g8{cpuu d[ <̜9_W4 eee?d?ѣW<L&۶mc޽OwjX,|}}YdI^L뉿%3::}3H=3C,hϕJ9ӹǕڱcSNes7rfIeXz5+WdWv;Z # {g}{?7_ufp@^W R;_GE MWTYC$ΞA! dWS|}}{裏"L“O>ɪU*ydԩS %,, ?'NP>|*b~EEE?ӧ&MYYY]^ !B!\-zdG Ĵix)**(SLaѬ^???˳X,[vmr-̟?_Wٳ._GB!'MX ~3Νˑ#GXn^g2guŋ)))t]a4O~BHHYYYs=\t {_xyyqqCby<#c|I_GB!|ƫ&5M;^o~v;vwEESXf & 6tk&%K4VSSÓO>m/iFv/8p{Ӳklg]Ζ$m puD8{g8{g.;lɻgNr;@ !B!D_@ !B!pn} mm?)D-BNN}и}߿EYEQx穫#11EaZY~=ϟWя~DXXiiizR6L2BBBG=zT ƴiӈh4ryvɱc\C|r8'|4zŊ߿Eyƺu먫# dbbbbvŹs眞z<هWwyDGG_qOnn.nZlF#SNeȑPVVIMM^~]̭Ȼ%u*G楗^b…wjX.]PVZů뫚jjRQQw(,,TYVVknolx.^g|'QF(u|/߿?6`1(BYd t}^gdggcZ)//g…;v٣wlv8*dbڵښZWهWO9<<???v;vDll,111|g߿_bڋ' u$t)))>['KgW_jZhZ, 3fP]]Լ={Uo謫6?EQ(**;1vVo޽{y|}}yO 3#Fb{0|z)F#*:v'|%K`6Zzl2~c0ضm[$Djj*'OV><߷oQQQ!==(|}};c[qСVۙo޼{wGy~3gtjQWWGAAf…?ॗ^"""B۱3f`ĉK͚M\NQ>t:\s ֭""" cȑ 2ĩ3]]Uvw̭,m ***裏ضm[ev=ooov;uuu3vXSWW6EQtDEE55999N5+//h֔v],**-[h">}:ht4u)w9|0{/>>>DFF6;&uWj+N.iX9s&jb4[ꍿݵ ә;w.L6u֩Wc6tN gֻ>|뮻z>V^nر(Bqq)[o#,6lP-GLN8G}fNmNŋDGGO^^Of͚553g0||A|||ܹsDFF2bO~$pszm1L|4mGFOUa8;XVRRR$::'NH{PYY:3f`hٳ\pA~݀nj s|4x}8v6_ <ŸR*++}ַmxծB!}[\ʠ#kLqq1:Gii|ՙ$Q-[dfsqog͚5j9i$ 9t.\`۶m̛7EQoii)6mj(-[ʋ/Huu:|?{, pDZZ:/0UAmoKwOd/~Azz:QQQ50ϟ;=<((H$(::x0L<\V<7ߌVi̴m3Ӷ f}E?:䇪QLuuSqSjfĹ8{g8{ƹ'Eֺv/6+Ȏ FCpp0VݍߴP^^O<+hW_N ?~<֭#88J^|E:ĸq0`o7nu5kV&%%N6={}=M;ӉUgΖY,hN#3H=Y\- 34^4i}=pر[kNؚzEAW⩧ru5ܸqxꩧAI B!zVPPӁJX+~VM^4W O8]] ]]n1rHn*ɣB!⊹EʢEZ]] !DRsN 97aW2e*É;3`S"g q gpqNn@ !z?VhDxtB8f0zشVW@zg8{gl{Noq$wr`tDBz7g8{gp6=RWW@wxyy hv{ŖO}3H=3t+ ;ziWtt "g8{gpXJ)2thL;$ΞA$Ξb!B!$B!BI B!B8EH!B!NR!B!S$B!ByhO[n!''> h|wM/ٽ{wYhVsyu^G?aaa}vuhdʔ)$$$ 8z( 6iӦhܹcǎzSzCe8pO>h+߿?۷o'--4ŋ/uuu9sl>#%%v;cƌn?ODGGK{Hk1w0L:#Gjٳ۷#Gh4|DGG兢(qiǛͳ[QWo>*GOyٲe >ͺ呞ԩS%N+B>I׳xbZTTT|h T3}fϸ5jaaa={6zz='..Npp0t:E,Y`Wo^K׳tR5,\aÆ95}xx8~~~jM&tML0YYFìY;vlwbg͚EXXzHTTK.;N}: ///V+___Xl-U8+ffnW)"q) Ĉ#1b0m4 P?5tL:U-X0ٺu+l64X䐟OYY\^Ohh(lҐ!CHHH >>EQ1c낂ccѢE0n8222h4\{\pwb~0f37oرc0k,2e 7]HKKחKɓqjW]*t8gggqF 71c8|06mRF$N+B>ԩS[jcӦMرéM&UUUz&M@LL TUUFd21bvIff&.]'Np f3eeeh4jTWWaXoܸm۶]jkk@m3YYY`nǧxqk/&xq_l6S^^_Ξ=FaܸqmοVmf2wjW]*t85gI)l6#F ..,L&sq%FN}}=2ydv;{n dhhř)Sp:y6NFF&sb:5)S#0zhv;-,KHH .l֔IG{1oo_lU鐐Vchg@INʸ{\e=ޛ,qG5a_`hliF4f H!,IKKCQN:E}}}Ft9BRR'**N8n`0j;|h42k,Eaƍrv dddBJJ 6bbݔ~~~@cdgg(gCDDGn*ĸsg1o<͛~WE=Y$zU%q&tL8XBCCGYVJJX3iMkŐkT9yyy۷g>S5 vHOOgر$%%aIOOݮ@Qt:QQQzmmMNNfbWo>-[\jkkOۈmu~V˱lzp:αZN>7|ɓ' -;Uӓq,s"jy <{VҬGrڻPc(3o BM 8{,EEEDEEQYYInn.^^^@ci4x"NbС$''cXjH^NjzuŷIIIa$%%MQQQeO<7|ôiڜĸUUUG|| -//O0`v;h1_~Q/yvv]]*t8_ s"3f C e캖+):;v,YYY$BLrrW^yoG3C4 v6oaѢE͖S]]MAA&Mn .]bժUlذS]]b^?яXb(--/wqG uT????l6wy,ʙ3gXdIov/B!yn@tVȯn[n\\cǎmA:@tM̙3xEG ?{{3/3tP Xpǎ;=z4ǏGӵ80i$~nz^}Uvs=̰aZ$i˗ohL^{5ƌjWξ}j6ٽC aѢE]`B!Bt=hªնޜɓln{Xfgn߰a_}];6Gȑ#h4bbbѱ 9ydioyoANN|'N;(..kQ?DyyyCDFFNjj:ojcZP;iF|W%B!*n@u/EQUUw܁dBFQnfF?fR-ˋ'?-BII 8p 6իW͛ygOʕ+[\  ŋ0Lyy9h?Çk1p"##^z%yB!nģȶ*++yᇙ9s&$//h4ʚիOѣGhyL&m޽{'@|jywX,dɒN5۽[la9naÆ+X~Ο?_|#B!B8Gn\;:u*3gdҤIYl2V^ʕ+ٶm/N``:rg<z,^ك.\ЬUoooTʞ={xg9r$QQQ8^}>sy s/]e=63H=3C,"M:ܮ( %%%rGEN2'|UV}ZNmm-NRy/,, ?'NP>|VYTT>}:lҤIxyy5jviLL fǎ]3q 9wH=3H=;-zaɄve= Ddd$'O;ĉ>>ر'|Rtޙi4wMPP|d-Scj&ކzZK.Ѱ+2}fgl 9݋H=3H=Õ9((@%`Mޕo?+M^&/w|w|+yRO@CCCgG:3?g>uGM>g q gqԃB!BH///fs-jB!BέȻ%u Z_>`ԩoE}B!- HW:+ Cff&1fjwfϞἇ>-|GܹիW7E ~in~!WUvt|G9rǏϑ#G8p `޽۷ .] @xx8/2|7r-ϟOjj*cŊjWf˖-{0a鄆;CFF{o,J'|פҿ!B YZNɓeΜ9Ob…={|}G駟aΜ9}&NȜ9s &&F};jo;p ,_dzj*)???Əbaĉڵ FÎ;xIJJ7`v֮]ˊ+8s 6m"=='O:<++ E1i$v{u_z5\sMy)((`|ǝ^__ᲂ;^<#|B!$l.W+55 8{,x bΝ ,, ___oc=bᦛnh4RVVݻfʕ{n}Qꨭ%((l6ǧa6nklٲW_}d޽L<_\wuv>Cz)rrrx76l6_l߾p^uJ}}=sx֭[YrzZt6m 77EQ0 ;B:(l۶y摓,Κ5kXvm*–-[xعsgRZZfpg5iҤNW@@@Tx.g8{g8{+swrW7Y&̙3'??C_x &P__sTrr2SNeذa,XX~a/_΄ زe '?aٲeL:___/^ o}:˗/… KNo vywظq#UUUw}p9Hii)Hg2hР6k4}Q^|E۬_jO&4^u^~ehY]//̵^{UZǩjFV(qE$ΞA$Ξq r\ @jj*F~synf2339x ?xy7lXVV+#** DVV>}#F0yd ƍ0>|^x7o֭cɒ%L>ロL2,N|'?ۛ'c&LF!++ łd'dҤI(v;v]MF#ǝގX,̙3Bdd$Q;3dnVvdJ\\\aƌL8^zlN<]MQ>t:\s ֭G^|FϢZ-,u2yg q gl{.+3g2o}u;ߟ6Ϟ=oΆ g%))骆`عs';St9//^V`hs4}$ΞA$Ξ8X=\] Ù3gXv-1L|׌?ѣGٽ{wI_̈́ >>a4h.\WWW(gܸqVXKFիٲeK3$$#G HOOWpPy222ػw/7|s5 ?iiipwh_&;;o[nusvڶֿvB!B hQ5'ihhR__ӧ%\vӕIpp0k׮eŊ9sM6NVV-bҤI-y1o<x'k= Qղzy)((`|444Z>))e˖qGo>JKKٱc> IIIl޼Y}lG{vu|ۚɓ'ݎBtVdd$v#p4 7|3xyya۩۷ǏhXx1juuu9skŊ߿Ųm6֭՛O:t(˗/#.(A1m4"""0?;wr1Wo>Jc=S&''/uuuk.Ν;.h42e … =zTCl &sxt:~aF#7nѣt:VZdbӦM>|żf3ΝdggKLjNr+]t$})..F1`(--U:sә$s>#44I&QXXȡCp۶mc޼y >cܹ\pAwO<moNN7$??VlgU)LV[(֪Qg)**bÆ jcƍl۶[LYYDZ-Քz3)WsłnG0l0F#f;w.6lhQb;eՃ!k]mϝ;Gzz:SLa̙L:cǎg7&44Tm(bq}*,,dMmm7[sAAA&}zJxx8XVu>0x`˩gȐ!\x^􏰡{uֱzj|IYf F̙3̟?|,֭[#x/~ADD111ٳNŋDGGO^^^׏~;wrqL&?8wrm[[ӆ2|}֭[:ϓ'O:\+Ipp0l6N:E}}}1sm(޽{u[c$4nhhP׻zYfEl/O+FYf( 7n^jce9BRR9x>Sp wݯ_)iA9n@յ8Mkz6Ȏ FCpp0V?9s$| se<+F^}U8wHKK111[`*++y9tP彼ihh>;vÇ3`fWBpA6nȴi(//ouݒZUVg[^yNmG!SQQ~}( >}o'O6!۾};{LJHrrrZ==-[ZFQl6[6''Lqq7Mu51w(**-[h">}:EQtDEEqyWpܽ&:NmA㣖xyy}%66h)'z; dyyyuth́nWvu>%WrCtaa!fٳgvokErk(cX?~|lohh`-eff55n8JJJukkZiӦm]iΝN%}夤`Φ/{4zNm\0j(tVU=k0h4TUUq)Jrr2|V+!!!x=c+koEQp&'RPPlf̙ l6[>>rL3vX8 p[$'Nh5Ar|,wDFFw^Wo69[ʎ%Dg񄇇[olٳ1cFa}Y^?{&$$Ϲ-((pvѳ ŋjeǕ輼<Enyf/_-j6j X,^DWVgfٽ{7C a\Cxyrr2gFбcؽ{WWpj3SW]3hII 3fp뛲~m^~eWWCbZIIInItttz%=WSNQQQ Z:;`]9C|r8'|+qMOOgԩDDD`49<;wرcD} 11EaZY~=ϟWz~FZZ۷oWFLBBB!!!\pG(4}< dbbbbvErrv ܹsxyyaZX,u]ߎ7`ٰlnWAf,]Tkyy9 .Tޣq &::N(ߟ%KM'tUM>slGEXXAAAp???nfϞMDDz^O䢛tE̽HLLO-Hߎv &`4=z4@c,srr턅ѯ_f%$$j՛H!4h1δi`0PPP/IKKϏEøqh6]v` 11~DFF2k,6nܨ3f fӦM }ΐ!CHHH >>EQ1cE\w#q5QVV?+WDJyy7W%4&))):u:_ML,X@XXlݺ|l6z0* d芘8PE'FLiivkڍ[Sc(..&** &_OMM ~~~93gj9r$Gfz=)N7$??Vlo L&sm)Sh\LBrrz08W+hө'11___&Ong޽v5 U%Kس"楥h9s&=K.eРA^=^|FadggS\\ŋ  >>^-wE!((!CM]Z-%%%-jIV!G$88Tl6NO~~~M;uVY{eddBJJ|:Ff͚(lܸQ>vFhȑ#$%%1|())ĉv ZVRne59x>S233]Nŭ_~ 4Z?(xњ۷h\srr0z9WoF7v:;v,IIIvөkVEQtDEE5UtNj(**b˖-,ZxO^Q|;v___}f20Ο?ng 2xJJJGz3r\!ZQ^^NJJ IIIjS֘vIDATL&fϞرc&2r{zօڋ#lhhٳPYYInn.VhZi4ԩS$''BF)\k4frZVjkkW^ÙyyyTVVrEЀNc<=ʥK.ȉN+Bц3~xINN歷j6>99ٳgǎcݮhGO5!!I&a)(( //իZ;ې(:t `nyf/_-jj X,^eZ ŋ5Gv$yyyrM98X,_^M0ϟ՞m6 ̙`bo>Wj"W  Vv;DGGg8jjyyy|ᇼ{pO=SNQQQ Zodd:<## Çt*ghL*5M9k|wt߾x;v W5۴WCߛ\[e;3Jw'tRÛ>?O~g q gV "77w:P kwJ& B!BH)B!)@ !B!p$B!B!" B!BH)B!)@ !u ko\GîdxgUWMt߻H=3H=cС,_'HNNV\WWGqq1v"99Ç9ϼ<}]-ZDTThZf3Ν#==#G+1a|ٲeNǴ}h42uTFIPPeee?~T])+;#UL:UZ3a.\+(Nj c׮]ڵ ???xF#m6]۷ Op x{{cZ.xyyq-0vX0L-*Ssi2妛nb„ -iZ1^v`t(BYd L^gҥjYp!Æ ˋnV( 6 ͆nn+cZFҥK5jĸԙ}ϏロYf^G1c<Wj=x:u F#иO>g?#$$@`` vӧO0a:ѣ pzrRѧ <#F0bEaڴi  6PE_'Oh42x`JKK[kǎǢEaܸqddd4+k׮V`䐟OYY\^Ohh(Tڐ!CHHH >>EQ1cFq?Iaaa8oܸQ 71c8|06mR; m۶~t:7xCI{P{1lL;ڷ,X@XXuuulٲ<ϏWo>j;tЫF#yyy?gEAɓ'd2MYYzrfq1?~<6b0a_~WW+B>jcӦMرzv;aÆl&//O=#ݚZ&32͔hHLLDR]]MII7SWTTĆ SqFmۦ^vh4: KqOj/W}d21bvIvv6444PRRҢW߮e9Żj4zHLL:m\\~hp555$$$OAAvnWW+B>fO\\$&&2g|MJKKٷo'OfƌL2ǏwVL62v233Ճy1o<{ZZ۷oo6dq*f#!!Ço>;w.6ltL̙3:u*ǎcϞ=Wt W%ݯwV{vhhڄPF0p@t:.\՛Ov~/sk/6SN1rH ^gذa={Ddd$ 8h>>DFF(--^rrr^E)//9e-Z,ΝeϞ=߿hu?!qqqqy@bS:۷^^ P Mnرcj9qDihhɓjc___}f2dH٢sH!h45Jj Cf夤Đ!ChzNM4MW_~0*1]ڷ(((`Μ99R t~/kSVVV%&&2JKK9y$uuuDEE8}4uuuxyy1rH*++{Pw??0P.QQ@$FE%|7Xٳ|6[ڭOڪ_NշNsSSُ=gݒ{~cFQH(V.sd:30~Oϻ~Z@Ѡ`WH"ZҰo߾p;::žGqq1QQQG߲e ^~i9ZZZCetuucaKKK!Z?xپ};6mڄehNl66~m˲ӧOwE\\|Mt3=[fwA$#)) p H˅v!2a6vqȑk_}UcժUmx-D`\.\~CCCe$j믿ӧ^zQSSYZ!?s}} s] BkkW_El6\. CEŋ,m?+W000;ptt3q-e[)[[[n݂ (,, 4Qkkrό^ &50T gwW4888GDOАZFuK;iә>4 & 0p;/ sE͛x^K9l$""""""u@* HDDDDDD H""""""R$fjѳ/ҍyyav^ga[2$z: 4Cnyav^ga[2$x: 4$Iz ,'0p;/ C<[@ьr:$ v=j:΃0p;/ jluh~$ :ZTYMg6%I(z=z=syav^n A" -4j$)سFO0p;ӓ""""""R$TaIDDDDDD0$""""""U@* HDDDDDD H""""""R$TaIDDDDDD0$""""""U@* HDDDDDD H""""""R$TaIDDDDDD0$""""""U@* H\g_AT=M|)i$vO)zz("$Ir3΄USz9`k\gwp8xqMeYjtSRRPSS q$I+VoǡC 2*++~ۮeeeXd pEܺunOgQQcQ%FKƭ~/DoG4IDt:>|EEE0ɤ /^lƚ5kmܸ<@kkkHϧ=,+$Iuzp:Aޒa6!|w d2!''?QRR,Cm$6oތիW?z655͛۶mbAll,vA؈NUnʂF$IHMMšCxY߮DsI~Sa,= BA@R H[ _|o&PYY^x$ p ,[ ?,oQ^^RbAAA$I!I#.J8B\~2]EESSdY(xבQCܼyHII_CIz﫮Fmm2}UUUfCvv6֮]DKWVVc``W\ACCdY xW|r$$$@E<~ϟǁB]޽xAmn=/e`6c8%ϟ,˪`@GGl6, >hZ$&&b```w{Y'OĒ%KPPP2z n[N͛7C$?~ {nlɎe:f>]՝nX f<ܻ $"T' tڼX"x4ЊC]ܽ>޸fH"޽{wΜ9}!77v$I,˨Cvv6|>ߤk.'pzqʕ$ "}>ߤ6쵁~ϟ @ssn=Mv~)>S]OA Q۷+][NOu݉u}o_끟o4a2u[3uɐ$@"|w Mubi"y.>>æM A@AArn@,0 Ne9A`hh/^ą pLt fN ш<h4p\ZOwիZ/Xr%V^ I'(][KJJ5ejZh4iy& @YNjIs2hǃC>x%@+V8sӅ]P[+f3s@h[n ICE%H+oD@ss3֬Y={`۶mƻWVVVcF7Z-[_J]oW__b$''G }ECC6l؀bϞ=0 Wt "=PMM2P(ֳ?p]^K.Ů]pȑae]]]fDϳkrDJˢkIQ wز\y],*2@^uqyU}WߨؚJoEб9fw9"yccc0\.Z[[144Y!IV+)ua|ȲSN VzZJ7ՙX@Z!.z,:71]ff&Ξ=* Bfٳv'_~í+x8\pAIIIذa겾>ߏio3#]r; IHՉ!c:Ύx4"A7g w[;&'zG$F$\`7D*iB{CݳիW_#?)ڳ_yNeZ#a%3)[4-͛7 ~tbʂh8/d j`ƍXd pEܺun@jUmSG{̄h(JUWW4H"9pa$%%$IdŠ+P]] I?VQ!dY$IJz @AAjjj0<<{㏃Q\\ χndff.\X ݻwchllɓ'/*** ǃ>|GHNNZ'׋;w")) NOƭ[͛7}6n߾ըhěoLlذ---L$򺪪 0طovZ444`֭(**dEww7Ν;t^EwѣE۷oGLL :;; APVVc``W\ACCdY(x7l2Ft: hll,˓ ׋HJJٳgqm|>(yn ݻwa2rJ1<<1tvvxhhz@llrtݨSZF'DQ~N6 (btt4j`Lb=*tX@ز۾};oٌa$&&7U2@͂zjfPZZM6 n˗U b@SSaZ\477?qjxpQ CMZ h4HΠ|>tuu!55 !A@RR ###A?Z?>h(**l`,ʙӧO̙30L0L;0]رcAMdXPRRYq `صkPWW n!2*++;Bnn.:;;T~~.㺺:cʕصkפ֕Hܹ 6l6#&&F)fۻǏWizXOVORj#{޽{6-dkh>n:x^9r}}}(..kbr @͂A8q"hڙ3gֆ5k 77ũSu)))Xt)v;!IZZZuV]---O͆$D[[.]Ǐ\'5BM<$ |MON3hPAll0~P' `۶mذaCmIDBbllL;v`@bb"zzz>#I>|,%o&^Bɓ'dn阩3 ؼy3$I8XO}Tz*\Ԭzg:fz=_=K/~yE1h@$wݻ3g`߾}Eyy9]u=ш7Aӑ BnQ^^5k`_<|0(|>Z-Ύk4dff ݎի{nPڈg~:~!66hnnʕ+Q^^Ӊrajʠ~ڡp$IJYvORxO?FNNӎ''/^z IIIZJʕ+Ax*5ghc߾}شiA (((P)z鐟`ժ<<4*QlٲilΝ{4Fj>122+^ʕ+޽Wʣd–-[zjkBjQ$uXOOLWzIA`X@0p]`A`hh/^ą p0H"Yn:A$!&&(A{lhvv6f3n79rZ 555a|>c͚5سg^yd~iiiя~a8N,YuZ8}4RRRxbףɨW_}Yp:pFNNm߾6mBLL^Jl6.]񠽽~m6@LL *++YL[ fAgg'ݍa\.bhhHjW_}ӧOG<* !&  IxbdddDٳg ׋G)-a()))AUUZZZ&0> ޟ'jrݻ8q>ij0 Ap@^WyuFFA3g000TdffpΝ;HNRf3GkdYٳgQUUAzl6={'GACC I^/?~f8#er&+ox<EQٴ?GL,.cpp>EXOOLw]t\Ӄ/>ý{ IFGGj^VEoo/}@Lk`< w^W^}ippp׏" 3ўlm^iGFFBΏ4 Ӻpέ"vXhn޼Y`7YxH""""""R$TaIDDDDDD0$""""""U@* hމtsh7&"*9D4[:$;SNut!,) h^$ '|L#A$" Yaۣ<#'&I"j٠ =) ҏBCCy.m `CD5f60$is8-PVmnwDD3Y;$"#""""""U@* HDDDDDD H""""""RѴ~dh~FR VʹxL!grW";>oADSx=("&&zv,GMo4yGD"" RH5="7LF1j:LѰ!'uf(ta$QgCD3%Z}3k ʹhsDD3u͖gNaIDNl :f˳P}TaIDDDDDD0$""""""U@* NCJJʤ?)~_aɒ%s9h~o}auhjPQQlF8twwXbEvtt,l6߇`@CC>3oz3`0 Xh^/zzzߢM>A[o!++ :$pÇoA{!55u|>wp8xqMUy F?A)-- ("-- ?򋶮^{ x1?$)i رcTUvRRRPSSete7bɒ%0 ŋq֭RN4ͷ:QmRS:e۫*ߑC_IDt8|0`6&I9$ >>O9eY8`0 7eٌ'ؼy3ja07|;v J8t:x^nFKxQTTl Wrr2flɄ?DIII| \/P]]ׯxj]%IBss3dYFRRRRR>Q144;w.;o޼Wr-^YYYh4$ 8t/^<+eE|qSZC_ID {oxI w܁`ec?~\PXXׯ?Z^Gqq1|>\p!2bcc (gwލף'OK@rr2<G!999h^/v܉$8N>}nBll,6oތ"۸}vzTWWFo&233aLJ3Q`@ZUUZf۷Xv-uVd2Ν jQE>ݻ8z(DQNtwwC+WY!"x ,[ F:|2!}F]۷ocll fx葒|@[[|>_P);A{naeG۰lX,jâBq@~/b2E7nDII , P[[KÙBs a9990L@\\rX,_NS˃bAWW!2fٌC!55CCCF\\\.פu2L\xMMMp:g}k׆>ݮt}4LATv8PΤ h4 CEСCh4Ajpe ;wbǎHHHARR݋M6)iVXFbb"݋n[iW򞖖$Hiz=8؈irfAAEF BB:.T2ܾ};oٌa$&&7U&-3Z}H7@= Cii)6mڄ2ܺu /_V}-MMMjERRrssVѣG1<< F7i222nA|Bjj*B4 $FFFBA(--Uo Ȳ>}gΜddc$$$brvرX,@e8q---X~=vڅ2WYYwAVVrssrP׮]úuh"Ν;((((yCzz:V\]vMj% WFǕ`PB*HW`euȑ#Cqq1^{5UYo a8qDд3gΠ k֬Ann.󑛛SN12SRRtRvC$`֭Xv-ZZZQ__l6_mmmt?~r455Al۶ 6lj$ :.IMMVرc ICdee)X~i]{zz<@^^(]h'RSv>'OĒ%KPPP2`͛!I?Gj!ԉPu\kpgYajjRZn||<}\`@=ݻ{̙3طorssQ^^k׮E]h47Mмt$%%/eYVlOx?Xf V^D?mN 2444XԿ\p!2<\.L&-[rwAԹsP]]w}K.ENNƂiddU2vtt(Siiie׮]=.\P100?5kԤt} "^}Uh^^z^9wK^FyyyhiiAaa!4 \.V nܸ\{sNk׮M%5wիظqct5ejhGPBHmw2!jA`hheFQv*!=@=֭["H6`E1辈ȢiΆlƑ#GxWQ^^UV&쟾C{{;֬Y={W^QC旖GĒ%KL\'ՊӧO#%%/'}gCCۧU[l/4?fǯHNNFEE+Ȳ,?TEww7rrrpAe6lgeYW^ zif*ܺGltȲzn~팔`ʕ @(//ׯ,BGGǴ1- N u믣G{lQp``:n۶ JtttD3_aى1tww+#Wbhh,C$XV|W8}ttA@aa!A@WWפJZ[[!I/^:{,t:aXz#ܿX,HII2i`xxӟP[[ ˅wĉϧ} pEMM dYFFFA3g000TdffpΝ;ȅNRf3GdYٳgQUUAzl6={' p:ׯchhhF/ VDꛕ¶PXGn {VSqUUV+z=Z-z{{p*!=1R/?4=k{_z^?"zn7TF{ 7fyѦN 9?mxMWZ!"RK͉E͛x^K9l$""""""u@* HDDDDDD H""""""R$H7vSi"bCDYS@Ѽ?TM"-BIxw;"$I@!- hސev=j::"zb$!Y ڹѓ:n*(z=z=D҈H=+ږ9D4]SofH"6á ½e*iզQvGJD4@")0""""""R$TaIDDDDDD0$""""""U8 +M[ll,GFj$piL TLR&Gx%k6D4US "bbba!rFqD4-(`0(u$IQӳ!j}3+y A`4` "zRjY\gh&Nv>LEz>|9D4S7Lv0GD4XlyD4D:ϖ"ish< u瀈 HDDDDDD H""""""R$ /"֯_iQQQŋuha=puh:DDDӥ鐐ǣLÇaXp1<~xV#"z-ĠCCC!ӼkAGGPYvDO˳Z:S@͐8TTT ;;FݨFEEVX,0xa0Ѐ> o^Ltظq#VZŋÇz*nݺh47 ?~7nPWdׯCjj|~<{{{a0_~!EZZDQDZZڼB JKK@?nܸ$`0 Xh^/zzzߢMgA{gԠFWXX`dd Iz-deeAA$8NMMM|!nlܸK,`@__.^.XO&Nz_~ Q:mmms]<-DD3@HJJHɄ+V$)|(BȲ I~%%%0 `xxxJ˘).]LjX|9P]]i/*}>dYZAa/lg\fRN~|ꫯBjDff&|A `ĵk~\\t:ccc,.kj/^,8NHT:t~jm`=5=fFrS[%''brv`0 33/"uh^|ECee%^x$&&B$oÝ;w`0l2<~ǏW>{㏃Q\\ χndff.\X ʙݻwchllɓ'/*** ǃ>|GHNNZ'ǃ ,]Oƍ7`4QQQ|l޼ʱ!7RyE>ݻ8z(DQNtwwC+WY!"x ,[ F:|2 d2Ν ʗ xǃfTUUu_HElܸ%%%X,@mm- }?rpYܾ}>)))rw܉$8N>}nBll,6oތ"۸}vP~AݻߏڎzEEEعs'222yf|嗓f]ss3n߾ ł>Z:d=zY A;PΝ;zh4COOAڵk'ghhz@llvQWWz@~~rmt:a  "FGG;S溞*tX@v]2@MC}}=`Zauuu(--ŦMPVV[n˪RAPr Պ$梹V ǃGbxx>o:-]z$͛Ax<}6ty*~8<?~<%I±cǂ-b,ĉhiik.N9.2*++;Bnn.:;;Oƙ3g`2`2 X,Q׿wEII كBTUU.֭ő#Gׇbk(..Fkk퓑FIM6CWWRSS0i!==+WĮ]&PFrlذf111p\!+--EEE?1yz\Sj1zg:޽{w^f :u]ȭ app'Nva͚5E~~>rssq)466F]fJJ .] ݎvHlݺk׮EKKaf!)) /ֆK.ǓZeIr:J9ΠR@C'.@jSNhnnƎ;`0H"++ f˶m۰aÆ3ݒ$M:͛صkz=-Z255U/~yEqɃPɓXd TB{tԶ3 ؼy3$I}#z `=5T`+@j6 cccHNNFBB^.S]}DD3޽{wΜ9}!77vZ#]F#~KOOGRR~^e;UnQ^^5k`_<|0(ؘrMBB¤kG*C jijڵG*ω/< rJtp\ؽ{7Zm<SzrJоp8B;$ !|>hZdee?\a ݎO?FNNr y8?w:~*`=zjUOM;/_t˿ॗ^BRRҤҙX@MC||<ۇM6A `bh:ƯZ@Ѡ 2<\.DQIJeB;wt:LZ'ͦ\7VVVtwvv*,uaѢE0 xW"v <# $; hD^^5 \.V|z>zuuuhii8 ())FPnhF.^ .ʕ+Ȉ2( ^x+W:::40 Xh݋4Ȳqûwիd2a˖-5i׮] y~.Vz]|z\Sy}PX,?κ.dl$"u֡$ 111ؿ?DQ 0~߳hg+a6vq ^}UcժU m󡽽k֬={+h4IKKÏ~# tbɒ%[&jEMM 8l'?AGGF#VZN444tӑ> [[['ݲe ^~i9l6FNNw}طo_PFGGՅӧO#%%/'嵡׻+WT[lVaŭ[pҥlo<_,K 3S溞 ,pn$PTyشibbbT7u]ID4 Cww7rڊ!,jW_}ӧOG<[) !& IxbdddDٳg ׋G)-U()))AUUZZZ&O> ۍ4+ʽzzzp1#hooGee%޽ ۭͯɓ''V`z϶G+OYq)@l6pNe={UUU^fٳgq9sHMMEff&ܹޮ|^Goo/Nߏ^՟{b=,S1tA\Ӄ/ &50T gwW4888GDOh~K;iMiXu}|`4]v`0ի8ŝCӹM)Z(݂-Z7o x{-<䀇=_+A4N|!brP)04l?pbj4>"}&x<(ҥKQPP˗+5D A[Dshf"\}`0j A`=$""վk bڵHMM Ȉf )$&2gfDDO)* HDDDDDD H"w" ;ڍu͖gNaIDN[xDGD4sh< u H"W$Ix/L#A$" Yaۣ<#'&I"j@sv!EK#"j[XtM h:0p :UF-+LzHDDDDDD H""""""R$T(D4m5ڳ_TåU3-6S1qHᕈxT6DDO(^n,QFѴ9$EM:cͬi3@D4SAhrD4a4sIof%/s"$"t:]>FD3IEYLVZ>:DD3-LbCDYS@Ѽl?[h!,)s""""""z.0$""""""U@* HDDDsLX~=æGEE/^|ǎǏg%?(⭷BLL zzz0442kttt```` }hvUH6D4c^x#!!111?OܿLCEEa4p8ݍjTTT`Ŋa?сJȲ ٌ oe$N7bժUXx1^/>|W֭[J:F`q e~+L&|Ǹ~:{=N.χwp8˳h?h[AE˃%A"^Cnn.?~$IJd? 8v:;;nӉ{)))AMMt'''7nĒ%K`0ׇ/K4D-8NBEg}AomoGVVF#pѣG͛7UqooS[~ +ɄTY-[bu֞Y:FQQf3rHϧȲL <())` ..n˘).n݊dhZ ,_o6oDzp:AY'0~>Z/P]]ׯxz󡻻()) .#66o!{n_8y$ॗ^BEExׇ>AxPQQKӸqF#***͛7sڭը Y3(xwѣG!"oߎtvv %%%\Ȳ Qo`ٲe0t˗بUTT& ^8w\PA믿xx<477*b7NQqFb```hjj,˓9o߾1fѣGwH L#vލ~o߆fb|Vyݝwj(2[?aXPPPIpyH'cEQDyyyߘ(xבQCܼyHII_O]~OVUUZf۷Xv-?3]'677c $MbAII n˗/(p:>3rrr`28匱 N':::e*//]]],(**N|f:t0r&SllT[[F8XV|'lE3^S-AXV \ عs'v؁x<$%%a޽شifŊHHH0;HLL޽{,`0@`xx("''G9(!!NFxW#۱}vf #11oVZ`>VZx^W_Ejj*n7uVNZ_~o~vLԉN[ hn:,_<]NUUUpsgF}}=`Zauuu(--ŦMPVV[n˪LAP&twwj")) hnn~|AѣF直NK.^$IA۷3S?󫭭c)I;t D$,ĉhiik.Niexydee!77ӧO̙30L0LX,^eݻwQRR={UUUA-eݺuz8rP\\^{ hmm E+Gv֭[E!==wAAADQDwwwk"-ϯXr%vڅ۷o,pۧp88~rPLϷԍvUUUطo^~eh48N;wN R'7d2ԩS?wy˗/Gvv6&*]T dYVzFLlfNoFIBH/oA|488'NM;s ڰf"??8u.3%%K.nG{{;$IBKK n݊kעfCRR~_ .]Ǐ',!Oh47NgPN˥|瓖gThZ ܌;v`0 11===A$ >DVVr] ضm6l*,IҤVb5W7oĮ]hѢnjj_A!Xzzz<@^^(]n@>'OĒ%KPPP2`͛!I?yducss3 `[g(OZ'Mt:ɄȲGaʠ6ifRɲO>Di͜NT$Mۍ7 ^o@]]]x<,>7ݻ{̙3طorssQ^^k׮Eh47Mмt$%%EF,˲ҍibwJ?ǃ?(//ǚ5kzj/ >|vllL&!!a5-IIIQ{}>ZV9pV[[59qP_W\r8N?. wV Hwʕ}pDw",˨Gzz:rssX,*#Neyv;>S>|X9ʦN3_FYQWWl|>444Lk9 "uZO~oϟ PQS63%5D4mׯ_GGG&j4B}aӦM za-t CCCZ@Ѡ 2<\.DQIJeBos=4 pE\pW\QM>Sq #66;w vZȖ{.^:ijY3OR7L Um``5555k(LlfNoH"_z.]RmAC[n I+>?C);;fnGQQr˱j*(g'|hooǚ5kg+J7+4G?0N',Y`d:YVO~ttth4bժUtPZ dYƥK4|A:ڽ-[_f*nIe322lذĞ={[\zNSϣG 2ӟNSYN Ao5ҥKxt藖DZOV__b$''GUU6[WgNoH"6166!Bgg'ݭ,ڊ!5j⫯ӧ#]]] hmm$IXx1222"ٳhllbţGl~X,`ddUUUhiiN>}4n7+(cǔk!{.nXUU'ON*}%3Se:uJ9@2p8!ɲgϢ l8{,Uo;w̙3@jj*233p8pe$v;z=z{{qI|7J^>3ܻw$)]O:*XVzhZ*' BmhAVׯ_l"5 r_mHD?33Y7z=ߛEMM dYFFFU63U'|ƃJ!`|9~՗z)?c/Tpi2-pzNFyF999صk ^3g<>DϚpQ{""7-Z7o x{-<䀇=_ +==vMMMGEE6l؀lɓA]nXv-RSS!Œ BDDD$=u,s"""zj*DDDDDD_؏*H5-l$"""""z~M+U~jo>MD"-@" +;SNut!,) h^$ '|,#yB$" YUݘn󀎈$IshVofS$I("+L"zn J?:: ^^Q4"R %uMT:fi)\)¼O|0h1$:0p :UF-+LA th4Ȳ|1YX !'@(p)mjZ'Mjϒj1\&'L #V nts]~DDDDDD ^n?&mӍ)}#V߽{e`2$"""""~Mwa NPT0p^&͉i0h,-F#\P55Zddy:mYr(Su&Gu%"""m& ,O8GY'it֠4$ 1!m|1g )Fq%x޹.g" `d;;;>LjqBg5'js=66`0ĉUhVL&hگW#tgPDN4EREpT 85tbL&ӛZ6@ $K `IDDD ذ$I|>?v0ǃF 7`Zs`WV [+0? ĖE!̴GM牯Ѹ?8?['7qYP!2'LxƄii%|uUB/T"""""" N C8F ̀:H^lj GwLXY!"""""@n(ȉ;J?@R4ڀBDLnq. -'< &t"B1#RT t8;ijZ '?إub&'@N.KDDDDDDԕ5Tpy ti4VF5pQ\E3Zi=1DDDDDD Q.Z!@p^QVÍ8MV{ d'r'?m`p-H"""""P.Rw]Uu:6'^M|=1DDDDDD N zb@ꞎEMG 7QX#]9qBӋ~p """"".\\$Exmp #NXXN\I+<}4 *y7*mov[P-bMlQPA_ouG#,'R XPB.xL3(pD'R)DeZ2] <^O b{ẞmI(EY dײ;0&fh 7¼BL{Qup ʨ&d$-uIG?-HQHNT1$""""gՓ 81ҼTP`l4DDDDDD4.Rc4D]b'SZ)H鈈h\XNg~yۓjLGDDDDDЩ  <""2]4 .hP{m`OM8tciS)-[ԋRV2LB w-dhΟ4=\7 2ZhtDDDDDD /ԼG`L7TEDDDDD4_Li} n*A)]Hg0Z(hjh*^4G"""""vd^GJThe|Z%"""""$U?L%-&tEXtCreation Time2022-10-14T16:06:44 CEST@%2o%tEXtdate:create2022-10-14T14:09:43+00:00=%tEXtdate:modify2022-10-14T14:09:43+00:00q`tEXtSoftwaregnome-screenshot>IENDB`lxi-tools-2.7/images/lxi-tools-icon.png000066400000000000000000000077001447016333500201610ustar00rootroot00000000000000PNG  IHDRddpTiCCPICC profile(}=H@_ӊ"+8dbATQP Vh/hҐ8 ?.κ: "ƃ~{2Ӭ8鶙JLvU|Ǩ,cN_.Ƴ9zԜŀH< & ޴ VUs1.Hu71өyXhcYԈSXY+WY᜾uCH`K BA%a#FN}_"B9Pn䄗/1 t|;N>Wz_3ZZ.[\Olʮ)}S׼ޚ8}U88F ="rC|bKGD pHYs B(xtIME:8uu IDATx]iTWؚflDVQ1"`Pcfl$n$1L48j3q$'dq 0FY2"ʢMw魪:{[_nwoA2l  =P$"]eMLHDEQOf=A, z)J@eh=B jB("ryy]W"h~ׅzdTd8RtY2l()GA Q$]" OHA@QT `£AL Xo<܀\ySc xB8'c xB8'cpfKEQnG[Nyh˅n.p7KRBmH o@랭e;H\` J? 뇸(__U]3v(# ,xEYO[BQ ʌ g2ϒ {ϠC2XVzF=8Mׁ\id~=-b+K``Zy]9QwN W~Ӷ}fh46/~SL_Vdž lh:3@%Vޅ5m$pvb~,ԗ%B쳡kb㱈-/nSEœ}MA8݌mK}!Ծ3Hi> o%\;|=LۖB *ӟCx/7.|y:n.\5BLזՄT5EN[)DHwds䏫eAw'b4pYM6 bX;i$=kV[!{0W',Ib%0aEi5!zA2sOD/<2/[aɲ 3R3zc[jHT7UiLS &kT/ec \,ZEȥR# bӾs8Iu~+Z_qOantM~ nXԗ1}{[$WV \Q9o`v?w?{kcBl_YoԍN37pv&IڊP?K3I +CNh7=Ә"+{;;Mń[OEشdVd|8- #P](5ׄ1}c#{$7`,~bx!TTxu]ӿO w5q=L^Z1C,ْ, ̆3d #)?8k .WԙԷrcyͲVT-ga)tÂӶ( 3DMF3`V&!kR-6ZAvObº( n6&4cTRZDc6%`). BHN}=VG6d7:hDP^TU׌yA cDƜGS *P3S$ŵ[umеbŬM=K_4^/m(WacY$$ۏC`ZI=f lW(kO}Ytapn8`VB-pcɇ )(kUh]3I*$I"s[X]Ǎp1c1%? _w~{B_.]7Y.XC t4'%ԺRUJPݿh[pd? ]LEU' e NK&bB>R]ߢ6Ene{3ᑁoć1.W!yT>[?BҮPre[pld(p$Qx?;t $D}d+֊jOMƳ*I]Rx6m[T c|EI0yBڎi}CePDFDž{l:@6x(V̓ݟN-Fvn^gVn伮N%6"&$ >ݪ4 Byo2LDz9W'0~䣎8!t(U8g;y 1kl .I [] .SH "DESCRIPTION" .PP lxi is a commandline tool for controlling LXI compatible instruments such as modern oscilloscopes, power supplies, spectrum analyzers, etc. .SH "OPTIONS" .TP .B \-h, \--help Display help .TP .B \-v, \--version Display program version .SH COMMANDS .PP .B discover .I [] .RS Search available networks for LXI devices .RE .PP .B scpi .I [] .RS Send SCPI command .RE .PP .B screenshot .I [] [] .RS Capture screenshot .RE .PP .B benchmark .I [] .RS Benchmark .RE .PP .B run .I .RS Run Lua script .RE .SH "DISCOVER OPTIONS" .TP .B \-t, \--timeout Timeout in seconds .TP .B \-m, \--mdns Search via mDNS/DNS-SD .SH "SCPI OPTIONS" .TP .B \-a, \--address IP address of LXI device .TP .B \-p, \--port Use port .TP .B \-t, \--timeout Timeout in seconds .TP .B \-x, \--hex Print response in hexadecimal .TP .B \-i, \--interactive Enter interactive mode .TP .B \-r, \--raw Use raw/TCP protocol .SH "SCREENSHOT OPTIONS" .TP .B \-a, \--address IP address of LXI device .TP .B \-t, \--timeout Timeout in seconds .TP .B \-p, \--plugin Use screenshot plugin by name If this option is omitted the tool will automatically try to select the most suitable plugin. .TP .B \-l, \--list List available screenshot plugins .TP To write screenshot image to stdout simply use '-' as the output filename. .SH "BENCHMARK OPTIONS" .TP .B \-a, \--address IP address of LXI device .TP .B \-p, \--port Use port .TP .B \-t, \--timeout Timeout in seconds .TP .B \-c, \--count Number of request messages .TP .B \-r, \--raw Use raw/TCP protocol .SH "EXAMPLES" .TP Search for LXI instruments: lxi discover .TP Search for LXI instruments using mDNS/DNS-SD: lxi discover --mdns .TP Send SCPI command: lxi scpi --address 10.0.0.42 "*IDN?" .TP Send SCPI command and dump response to file: lxi scpi --address 10.0.0.42 "*IDN?" > response.txt .TP Capture screenshot from a Rigol 1000Z series oscilloscope: lxi screenshot --address 10.0.0.42 --plugin rigol-1000z Or by using screenshot plugin autodetection simply: lxi screenshot --address 10.0.0.42 .PP Note: Some LXI devices are slow to process SCPI commands, in which case you might need to take care to increase the timeout value. .SH "WEBSITE" .PP Visit https://lxi-tools.github.io .SH "AUTHOR" .PP Written by Martin Lund lxi-tools-2.7/man/meson.build000066400000000000000000000005731447016333500162440ustar00rootroot00000000000000mandir = join_paths(get_option('prefix'), get_option('mandir')) man1dir = join_paths(mandir, 'man1') conf = configuration_data() conf.set('version', meson.project_version()) conf.set('version_date', version_date) manpage = configure_file( input: files('lxi.1.in'), output: 'lxi.1', configuration: conf, ) install_man( manpage, install_dir: man1dir, ) lxi-tools-2.7/meson.build000066400000000000000000000007511447016333500154670ustar00rootroot00000000000000project('lxi-tools', 'c', version : '2.7', license : [ 'BSD-3-Clause'], meson_version : '>= 0.53.2', default_options : [ 'warning_level=2', 'buildtype=release', 'c_std=gnu11', 'b_lundef=false' ] ) # The tag date of the project_version(), update when the version bumps. version_date = '2023-02-21' devel_mode = 0 subdir('src') subdir('man') enable_gui = get_option('gui') if enable_gui subdir('data') meson.add_install_script('build-aux/meson/postinstall.py') endif lxi-tools-2.7/meson_options.txt000066400000000000000000000003371447016333500167620ustar00rootroot00000000000000option('bashcompletiondir', type : 'string', description : 'Directory for bash completion scripts ["no" disables]') option('gui', type : 'boolean', value: true, description : 'Install lxi-gui') lxi-tools-2.7/src/000077500000000000000000000000001447016333500141115ustar00rootroot00000000000000lxi-tools-2.7/src/.gitignore000066400000000000000000000000441447016333500160770ustar00rootroot00000000000000*.o *.a /lxi rigol_1000z_screenshot lxi-tools-2.7/src/bash-completion/000077500000000000000000000000001447016333500171755ustar00rootroot00000000000000lxi-tools-2.7/src/bash-completion/lxi000066400000000000000000000042741447016333500177230ustar00rootroot00000000000000# # Bash completion script for lxi # _lxi() { local cur prev firstword opts discover_opts scpi_opts screenshot_opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" firstword=$(get_firstword) # The options we'll complete. opts="-h --help \ -v --version \ discover \ scpi \ screenshot \ benchmark \ run" discover_opts="-t --timeout \ -m --mdns" scpi_opts="-a --address \ -p --port \ -t --timeout \ -x --hex \ -i --interactive \ -r --raw" screenshot_opts="-a --address \ -t --timeout \ -p --plugin \ -l --list" benchmark_opts="-a --address \ -p --port \ -t --timeout \ -c --count \ -r --raw" # Complete the options case "${COMP_CWORD}" in 1) COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) ;; *) case ${firstword} in discover) COMPREPLY=( $(compgen -W "${discover_opts}" -- ${cur}) ) ;; scpi) COMPREPLY=( $(compgen -W "${scpi_opts}" -- ${cur}) ) ;; screenshot) COMPREPLY=( $(compgen -W "${screenshot_opts}" -- ${cur}) ) ;; benchmark) COMPREPLY=( $(compgen -W "${benchmark_opts}" -- ${cur}) ) ;; run) COMPREPLY=( $(compgen -o filenames -A file -- ${cur}) ) ;; *) COMPREPLY=() ;; esac ;; esac return 0 } get_firstword() { local firstword i firstword= for ((i = 1; i < ${#COMP_WORDS[@]}; ++i)); do if [[ ${COMP_WORDS[i]} != -* ]]; then firstword=${COMP_WORDS[i]} break fi done echo $firstword } # Bind completion to lxi command complete -o default -F _lxi lxi lxi-tools.lxi lxi-tools-2.7/src/bash-completion/meson.build000066400000000000000000000006331447016333500213410ustar00rootroot00000000000000bashcompletiondir = get_option('bashcompletiondir') if bashcompletiondir == '' bash_completion_dep = dependency('bash-completion', required: false) if bash_completion_dep.found() bashcompletiondir = join_paths(get_option('datadir'), 'bash-completion', 'completions') endif endif if (bashcompletiondir != 'no') and (bashcompletiondir != '') install_data('lxi', install_dir: bashcompletiondir) endif lxi-tools-2.7/src/benchmark.c000066400000000000000000000072741447016333500162210ustar00rootroot00000000000000/* * Copyright (c) 2016-2022 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "error.h" #include #define ID_LENGTH_MAX 65536 int benchmark(const char *ip, int port, int timeout, lxi_protocol_t protocol, int count, bool no_gui, double *result, void (*progress)(unsigned int count)) { struct timespec start, stop; double elapsed_time; int device, i, bytes_received; char id[ID_LENGTH_MAX]; char *command = "*IDN?"; // Check for required options if (strlen(ip) == 0) { error_printf("Missing address\n"); exit(EXIT_FAILURE); } if (protocol == RAW) command = "*IDN?\n"; // Connect device = lxi_connect(ip, port, NULL, timeout, protocol); if (device != LXI_OK) { error_printf("Unable to connect to LXI device\n"); return 1; } if (no_gui) printf("Benchmarking by sending %d ID requests. Please wait...\n", count); // Start time if ( clock_gettime(CLOCK_MONOTONIC, &start) == -1 ) { error_printf("Failed to get start time\n"); return 1; } // Run benchmark for (i=0; i #include #include #include #include #include #include #include "error.h" #include int benchmark(const char *ip, int port, int timeout, lxi_protocol_t protocol, int count, bool no_gui, double *result, void (*progress)(unsigned int count)); #ifdef __cplusplus } #endif lxi-tools-2.7/src/discover.c000066400000000000000000000061511447016333500160760ustar00rootroot00000000000000/* * Copyright (c) 2016-2018 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "error.h" #include "misc.h" #include static int device_count = 0; static int service_count = 0; static void broadcast(const char *address, const char *interface) { UNUSED(address); printf("Broadcasting on interface %s\n", interface); } static void device(const char *address, const char *id) { printf(" Found \"%s\" on address %s\n", id, address); device_count++; } static void service(const char *address, const char *id, const char *service, int port) { printf(" Found \"%s\" on address %s\n %s service on port %u\n", id, address, service, port); service_count++; } int discover(bool mdns, int timeout) { lxi_info_t info; // Set up info callbacks info.broadcast = &broadcast; info.device = &device; info.service = &service; printf("Searching for LXI devices - please wait...\n\n"); // Search for LXI devices / services if (mdns) { lxi_discover(&info, timeout, DISCOVER_MDNS); if (service_count == 0) printf("No services found\n"); else printf("\nFound %d service%c\n", service_count, service_count > 1 ? 's' : ' '); } else { lxi_discover(&info, timeout, DISCOVER_VXI11); printf("\n"); if (device_count == 0) printf("No devices found\n"); else printf("Found %d device%c\n", device_count, device_count > 1 ? 's' : ' '); } printf("\n"); return 0; } lxi-tools-2.7/src/discover.h000066400000000000000000000031561447016333500161050ustar00rootroot00000000000000/* * Copyright (c) 2016-2022 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #pragma once #include int discover(bool mdns, int timeout); lxi-tools-2.7/src/error.h000066400000000000000000000032351447016333500154160ustar00rootroot00000000000000/* * Copyright (c) 2017-2022 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #pragma once #include #define error_printf(format, args...) \ fprintf(stderr, "Error: " format, ## args) lxi-tools-2.7/src/gtk/000077500000000000000000000000001447016333500146765ustar00rootroot00000000000000lxi-tools-2.7/src/gtk/help-overlay.ui000066400000000000000000000040521447016333500176450ustar00rootroot00000000000000 True shortcuts 10 General Search for instruments action.search Show/hide instrument list action.toggle_flap Copy screenshot to clipboard action.copy_screenshot Show Shortcuts win.show-help-overlay Quit app.quit lxi-tools-2.7/src/gtkchart.c000066400000000000000000000640511447016333500160720ustar00rootroot00000000000000/* * Copyright (c) 2022 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "gtkchart.h" #define UNUSED(expr) do { (void)(expr); } while (0) struct chart_point_t { double x; double y; }; struct _GtkChart { GtkWidget parent_instance; int type; char *title; char *label; char *x_label; char *y_label; double x_max; double y_max; double value; double value_min; double value_max; int width; void *user_data; GSList *point_list; GtkSnapshot *snapshot; }; struct _GtkChartClass { GtkWidgetClass parent_class; }; G_DEFINE_TYPE (GtkChart, gtk_chart, GTK_TYPE_WIDGET) static void gtk_chart_init (GtkChart *self) { // Defaults self->type = GTK_CHART_TYPE_UNKNOWN; self->title = NULL; self->label = NULL; self->x_label = NULL; self->y_label = NULL; self->x_max = 100; self->y_max = 100; self->value_min = 0; self->value_max = 100; self->width = 500; self->snapshot = NULL; //gtk_widget_init_template (GTK_WIDGET (self)); } static void gtk_chart_finalize (GObject *object) { GtkChart *self = GTK_CHART (object); G_OBJECT_CLASS(gtk_chart_parent_class)->finalize(G_OBJECT (self)); } static void gtk_chart_dispose (GObject *object) { GtkChart *self = GTK_CHART (object); GtkWidget *child; while ((child = gtk_widget_get_first_child (GTK_WIDGET (object)))) gtk_widget_unparent (child); // Cleanup g_free(self->title); g_free(self->label); g_free(self->x_label); g_free(self->y_label); gdk_display_sync(gdk_display_get_default()); g_slist_free_full(g_steal_pointer(&self->point_list), g_free); g_slist_free(self->point_list); G_OBJECT_CLASS (gtk_chart_parent_class)->dispose (object); } static void chart_draw_line_or_scatter(GtkChart *self, GtkSnapshot *snapshot, float h, float w) { GdkRGBA bg_color, white, blue, red, line, grid; cairo_text_extents_t extents; char value[20]; //gdk_rgba_parse (&bg_color, "#2d2d2d"); gdk_rgba_parse (&bg_color, "black"); gdk_rgba_parse (&white, "rgba(255,255,255,0.75)"); gdk_rgba_parse (&blue, "blue"); gdk_rgba_parse (&red, "red"); gdk_rgba_parse (&line, "#325aad"); gdk_rgba_parse (&grid, "rgba(255,255,255,0.1)"); // Set background color gtk_snapshot_append_color (snapshot, &bg_color, &GRAPHENE_RECT_INIT(0, 0, w, h)); // Assume aspect ratio w:h = 2:1 // Set up Cairo region cairo_t * cr = gtk_snapshot_append_cairo (snapshot, &GRAPHENE_RECT_INIT(0, 0, w, h)); cairo_set_antialias (cr, CAIRO_ANTIALIAS_FAST); cairo_set_tolerance (cr, 1.5); gdk_cairo_set_source_rgba (cr, &white); cairo_select_font_face (cr, "Ubuntu", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); // Move coordinate system to bottom left cairo_translate(cr, 0, h); // Invert y-axis cairo_scale(cr, 1, -1); // Draw title cairo_set_font_size (cr, 15.0 * (w/650)); cairo_text_extents(cr, self->title, &extents); cairo_move_to (cr, 0.5 * w - extents.width/2, 0.9 * h - extents.height/2); cairo_save(cr); cairo_scale(cr, 1, -1); cairo_show_text (cr, self->title); cairo_restore(cr); // Draw x-axis label cairo_set_font_size (cr, 11.0 * (w/650)); cairo_text_extents(cr, self->x_label, &extents); cairo_move_to (cr, 0.5 * w - extents.width/2, 0.075 * h); cairo_save(cr); cairo_scale(cr, 1, -1); cairo_show_text (cr, self->x_label); cairo_restore(cr); // Draw y-axis label cairo_text_extents(cr, self->y_label, &extents); cairo_move_to (cr, 0.035 * w, 0.5 * h - extents.width/2); cairo_save(cr); cairo_rotate(cr, M_PI/2); cairo_scale(cr, 1, -1); cairo_show_text (cr, self->y_label); cairo_restore(cr); // Draw x-axis cairo_set_line_width (cr, 1); cairo_move_to (cr, 0.1 * w, 0.2 * h); cairo_line_to (cr, 0.9 * w, 0.2 * h); cairo_stroke (cr); // Draw y-axis cairo_set_line_width (cr, 1); cairo_move_to (cr, 0.1 * w, 0.8 * h); cairo_line_to (cr, 0.1 * w, 0.2 * h); cairo_stroke (cr); // Draw x-axis value at 100% mark g_snprintf(value, sizeof(value), "%.1f", self->x_max); cairo_set_font_size (cr, 8.0 * (w/650)); cairo_text_extents(cr, value, &extents); cairo_move_to (cr, 0.9 * w - extents.width/2, 0.16 * h); cairo_save(cr); cairo_scale(cr, 1, -1); cairo_show_text (cr, value); cairo_restore(cr); // Draw x-axis value at 75% mark g_snprintf(value, sizeof(value), "%.1f", (self->x_max/4) * 3); cairo_set_font_size (cr, 8.0 * (w/650)); cairo_text_extents(cr, value, &extents); cairo_move_to (cr, 0.7 * w - extents.width/2, 0.16 * h); cairo_save(cr); cairo_scale(cr, 1, -1); cairo_show_text (cr, value); cairo_restore(cr); // Draw x-axis value at 50% mark g_snprintf(value, sizeof(value), "%.1f", self->x_max/2); cairo_set_font_size (cr, 8.0 * (w/650)); cairo_text_extents(cr, value, &extents); cairo_move_to (cr, 0.5 * w - extents.width/2, 0.16 * h); cairo_save(cr); cairo_scale(cr, 1, -1); cairo_show_text (cr, value); cairo_restore(cr); // Draw x-axis value at 25% mark g_snprintf(value, sizeof(value), "%.1f", self->x_max/4); cairo_set_font_size (cr, 8.0 * (w/650)); cairo_text_extents(cr, value, &extents); cairo_move_to (cr, 0.3 * w - extents.width/2, 0.16 * h); cairo_save(cr); cairo_scale(cr, 1, -1); cairo_show_text (cr, value); cairo_restore(cr); // Draw x-axis value at 0% mark cairo_set_font_size (cr, 8.0 * (w/650)); cairo_text_extents(cr, "0", &extents); cairo_move_to (cr, 0.1 * w - extents.width/2, 0.16 * h); cairo_save(cr); cairo_scale(cr, 1, -1); cairo_show_text (cr, "0"); cairo_restore(cr); // Draw y-axis value at 0% mark cairo_set_font_size (cr, 8.0 * (w/650)); cairo_text_extents(cr, "0", &extents); cairo_move_to (cr, 0.091 * w - extents.width, 0.191 * h); cairo_save(cr); cairo_scale(cr, 1, -1); cairo_show_text (cr, "0"); cairo_restore(cr); // Draw y-axis value at 25% mark g_snprintf(value, sizeof(value), "%.1f", self->y_max/4); cairo_set_font_size (cr, 8.0 * (w/650)); cairo_text_extents(cr, value, &extents); cairo_move_to (cr, 0.091 * w - extents.width, 0.34 * h); cairo_save(cr); cairo_scale(cr, 1, -1); cairo_show_text (cr, value); cairo_restore(cr); // Draw y-axis value at 50% mark g_snprintf(value, sizeof(value), "%.1f", self->y_max/2); cairo_set_font_size (cr, 8.0 * (w/650)); cairo_text_extents(cr, value, &extents); cairo_move_to (cr, 0.091 * w - extents.width, 0.49 * h); cairo_save(cr); cairo_scale(cr, 1, -1); cairo_show_text (cr, value); cairo_restore(cr); // Draw y-axis value at 75% mark g_snprintf(value, sizeof(value), "%.1f", (self->y_max/4) * 3); cairo_set_font_size (cr, 8.0 * (w/650)); cairo_text_extents(cr, value, &extents); cairo_move_to (cr, 0.091 * w - extents.width, 0.64 * h); cairo_save(cr); cairo_scale(cr, 1, -1); cairo_show_text (cr, value); cairo_restore(cr); // Draw y-axis value at 100% mark g_snprintf(value, sizeof(value), "%.1f", self->y_max); cairo_set_font_size (cr, 8.0 * (w/650)); cairo_text_extents(cr, value, &extents); cairo_move_to (cr, 0.091 * w - extents.width, 0.79 * h); cairo_save(cr); cairo_scale(cr, 1, -1); cairo_show_text (cr, value); cairo_restore(cr); // Set color of grid gdk_cairo_set_source_rgba (cr, &grid); // Draw grid x-line 25% cairo_set_line_width (cr, 1); cairo_move_to (cr, 0.1 * w, 0.35 * h); cairo_line_to (cr, 0.9 * w, 0.35 * h); cairo_stroke (cr); // Draw grid x-line 50% cairo_set_line_width (cr, 1); cairo_move_to (cr, 0.1 * w, 0.5 * h); cairo_line_to (cr, 0.9 * w, 0.5 * h); cairo_stroke (cr); // Draw grid x-line 75% cairo_set_line_width (cr, 1); cairo_move_to (cr, 0.1 * w, 0.65 * h); cairo_line_to (cr, 0.9 * w, 0.65 * h); cairo_stroke (cr); // Draw grid x-line 100% cairo_set_line_width (cr, 1); cairo_move_to (cr, 0.1 * w, 0.8 * h); cairo_line_to (cr, 0.9 * w, 0.8 * h); cairo_stroke (cr); // Draw grid y-line 25% cairo_set_line_width (cr, 1); cairo_move_to (cr, 0.3 * w, 0.8 * h); cairo_line_to (cr, 0.3 * w, 0.2 * h); cairo_stroke (cr); // Draw grid y-line 50% cairo_set_line_width (cr, 1); cairo_move_to (cr, 0.5 * w, 0.8 * h); cairo_line_to (cr, 0.5 * w, 0.2 * h); cairo_stroke (cr); // Draw grid y-line 75% cairo_set_line_width (cr, 1); cairo_move_to (cr, 0.7 * w, 0.8 * h); cairo_line_to (cr, 0.7 * w, 0.2 * h); cairo_stroke (cr); // Draw grid y-line 100% cairo_set_line_width (cr, 1); cairo_move_to (cr, 0.9 * w, 0.8 * h); cairo_line_to (cr, 0.9 * w, 0.2 * h); cairo_stroke (cr); // Move coordinate system to (0,0) of drawn coordinate system cairo_translate(cr, 0.1 * w, 0.2 * h); gdk_cairo_set_source_rgba (cr, &line); cairo_set_line_width (cr, 2.0); // Calc scales float x_scale = (w - 2 * 0.1 * w) / self->x_max; float y_scale = (h - 2 * 0.2 * h) / self->y_max; // Draw data points from list GSList *l; for (l = self->point_list; l != NULL; l = l->next) { struct chart_point_t *point = l->data; switch (self->type) { case GTK_CHART_TYPE_LINE: if (l == self->point_list) { // Move to first point cairo_move_to(cr, point->x * x_scale, point->y * y_scale); } else { // Draw line to next point cairo_line_to(cr, point->x * x_scale, point->y * y_scale); cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); cairo_stroke(cr); cairo_move_to(cr, point->x * x_scale, point->y * y_scale); } break; case GTK_CHART_TYPE_SCATTER: // Draw square //cairo_rectangle (cr, point->x * x_scale, point->y * y_scale, 4, 4); //cairo_fill(cr); // Draw point cairo_set_line_width(cr, 3); cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); cairo_move_to(cr, point->x * x_scale, point->y * y_scale); cairo_close_path (cr); cairo_stroke (cr); break; } } cairo_destroy (cr); } static void chart_draw_number(GtkChart *self, GtkSnapshot *snapshot, float h, float w) { GdkRGBA bg_color, white, blue, red, line, grid; cairo_text_extents_t extents; char value[20]; gdk_rgba_parse (&bg_color, "black"); gdk_rgba_parse (&white, "rgba(255,255,255,0.75)"); gdk_rgba_parse (&blue, "blue"); gdk_rgba_parse (&red, "red"); gdk_rgba_parse (&line, "#325aad"); gdk_rgba_parse (&grid, "rgba(255,255,255,0.1)"); // Set background color gtk_snapshot_append_color (snapshot, &bg_color, &GRAPHENE_RECT_INIT(0, 0, w, h)); // Assume aspect ratio w:h = 1:1 // Set up Cairo region cairo_t * cr = gtk_snapshot_append_cairo (snapshot, &GRAPHENE_RECT_INIT(0, 0, w, h)); cairo_set_antialias (cr, CAIRO_ANTIALIAS_FAST); cairo_set_tolerance (cr, 1.5); gdk_cairo_set_source_rgba (cr, &white); cairo_select_font_face (cr, "Ubuntu", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); // Move coordinate system to bottom left cairo_translate(cr, 0, h); // Invert y-axis cairo_scale(cr, 1, -1); // Draw title cairo_set_font_size (cr, 15.0 * (w/650)); cairo_text_extents(cr, self->title, &extents); cairo_move_to (cr, 0.5 * w - extents.width/2, 0.9 * h - extents.height/2); cairo_save(cr); cairo_scale(cr, 1, -1); cairo_show_text (cr, self->title); cairo_restore(cr); // Draw label cairo_set_font_size (cr, 25.0 * (w/650)); cairo_text_extents(cr, self->label, &extents); cairo_move_to(cr, 0.5 * w - extents.width/2, 0.2 * h - extents.height/2); cairo_save(cr); cairo_scale(cr, 1, -1); cairo_show_text(cr, self->label); cairo_restore(cr); // Draw number g_snprintf(value, sizeof(value), "%.1f", self->value); cairo_set_font_size (cr, 140.0 * (w/650)); cairo_text_extents(cr, value, &extents); cairo_move_to(cr, 0.5 * w - extents.width/2, 0.5 * h - extents.height/2); cairo_save(cr); cairo_scale(cr, 1, -1); cairo_show_text(cr, value); cairo_restore(cr); cairo_destroy (cr); } static void chart_draw_gauge_linear(GtkChart *self, GtkSnapshot *snapshot, float h, float w) { GdkRGBA bg_color, white, blue, red, line, grid; cairo_text_extents_t extents; char value[20]; gdk_rgba_parse (&bg_color, "black"); gdk_rgba_parse (&white, "rgba(255,255,255,0.75)"); gdk_rgba_parse (&blue, "blue"); gdk_rgba_parse (&red, "red"); gdk_rgba_parse (&line, "#325aad"); gdk_rgba_parse (&grid, "rgba(255,255,255,0.1)"); // Set background color gtk_snapshot_append_color (snapshot, &bg_color, &GRAPHENE_RECT_INIT(0, 0, w, h)); // Assume aspect ratio w:h = 1:2 // Set up Cairo region cairo_t * cr = gtk_snapshot_append_cairo (snapshot, &GRAPHENE_RECT_INIT(0, 0, w, h)); cairo_set_antialias (cr, CAIRO_ANTIALIAS_FAST); cairo_set_tolerance (cr, 1.5); gdk_cairo_set_source_rgba (cr, &white); cairo_select_font_face (cr, "Ubuntu", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); // Move coordinate system to bottom left cairo_translate(cr, 0, h); // Invert y-axis cairo_scale(cr, 1, -1); // Draw title cairo_set_font_size (cr, 15.0 * (2*w/650)); cairo_text_extents(cr, self->title, &extents); cairo_move_to (cr, 0.5 * w - extents.width/2, 0.95 * h - extents.height/2); cairo_save(cr); cairo_scale(cr, 1, -1); cairo_show_text (cr, self->title); cairo_restore(cr); // Draw label cairo_set_font_size (cr, 25.0 * (w/650)); cairo_text_extents(cr, self->label, &extents); cairo_move_to(cr, 0.5 * w - extents.width/2, 0.05 * h - extents.height/2); cairo_save(cr); cairo_scale(cr, 1, -1); cairo_show_text(cr, self->label); cairo_restore(cr); // Draw minimum value g_snprintf(value, sizeof(value), "%.0f", self->value_min); cairo_set_font_size (cr, 25.0 * (w/650)); cairo_text_extents(cr, value, &extents); cairo_move_to(cr, 0.7 * w, 0.1 * h - extents.height/2); cairo_save(cr); cairo_scale(cr, 1, -1); cairo_show_text(cr, value); cairo_restore(cr); // Draw maximum value g_snprintf(value, sizeof(value), "%.0f", self->value_max); cairo_set_font_size (cr, 25.0 * (w/650)); cairo_text_extents(cr, value, &extents); cairo_move_to(cr, 0.7 * w, 0.9 * h - extents.height/2); cairo_save(cr); cairo_scale(cr, 1, -1); cairo_show_text(cr, value); cairo_restore(cr); // Draw minimum line gdk_cairo_set_source_rgba (cr, &grid); cairo_move_to(cr, 0.375 * w, 0.1 * h); cairo_line_to(cr, 0.625 * w, 0.1 * h); cairo_set_line_width (cr, 1); cairo_stroke (cr); // Draw maximum line cairo_move_to(cr, 0.375 * w, 0.9 * h); cairo_line_to(cr, 0.625 * w, 0.9 * h); cairo_set_line_width (cr, 1); cairo_stroke (cr); // Move coordinate system to (0,0) of gauge line start cairo_translate(cr, 0.5 * w, 0.1 * h); // Draw gauge line gdk_cairo_set_source_rgba (cr, &line); cairo_move_to(cr, 0, 0); float y_scale = (h - 2 * 0.1 * h) / self->value_max; cairo_set_line_width (cr, 0.2 * w); cairo_line_to(cr, 0, self->value * y_scale); cairo_stroke (cr); cairo_destroy (cr); } static void chart_draw_gauge_angular(GtkChart *self, GtkSnapshot *snapshot, float h, float w) { GdkRGBA bg_color, white, blue, red, line, grid; cairo_text_extents_t extents; char value[20]; gdk_rgba_parse (&bg_color, "black"); gdk_rgba_parse (&white, "rgba(255,255,255,0.75)"); gdk_rgba_parse (&blue, "blue"); gdk_rgba_parse (&red, "red"); gdk_rgba_parse (&line, "#325aad"); gdk_rgba_parse (&grid, "rgba(255,255,255,0.1)"); // Set background color gtk_snapshot_append_color (snapshot, &bg_color, &GRAPHENE_RECT_INIT(0, 0, w, h)); // Assume aspect ratio w:h = 1:1 // Set up Cairo region cairo_t * cr = gtk_snapshot_append_cairo (snapshot, &GRAPHENE_RECT_INIT(0, 0, w, h)); cairo_set_antialias (cr, CAIRO_ANTIALIAS_FAST); // cairo_set_tolerance (cr, 1.5); gdk_cairo_set_source_rgba (cr, &white); cairo_select_font_face (cr, "Ubuntu", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); // Move coordinate system to bottom left cairo_translate(cr, 0, h); // Invert y-axis cairo_scale(cr, 1, -1); // Draw title cairo_set_font_size (cr, 15.0 * (2*w/650)); cairo_text_extents(cr, self->title, &extents); cairo_move_to (cr, 0.5 * w - extents.width/2, 0.9 * h - extents.height/2); cairo_save(cr); cairo_scale(cr, 1, -1); cairo_show_text (cr, self->title); cairo_restore(cr); // Draw label cairo_set_font_size (cr, 25.0 * (w/650)); cairo_text_extents(cr, self->label, &extents); cairo_move_to(cr, 0.5 * w - extents.width/2, 0.1 * h - extents.height/2); cairo_save(cr); cairo_scale(cr, 1, -1); cairo_show_text(cr, self->label); cairo_restore(cr); // Draw minimum value g_snprintf(value, sizeof(value), "%.0f", self->value_min); cairo_set_font_size (cr, 25.0 * (w/650)); cairo_text_extents(cr, value, &extents); cairo_move_to(cr, 0.225 * w, 0.25 * h - extents.height/2); cairo_save(cr); cairo_scale(cr, 1, -1); cairo_show_text(cr, value); cairo_restore(cr); // Draw maximum value g_snprintf(value, sizeof(value), "%.0f", self->value_max); cairo_set_font_size (cr, 25.0 * (w/650)); cairo_text_extents(cr, value, &extents); cairo_move_to(cr, 0.77 * w - extents.width, 0.25 * h - extents.height/2); cairo_save(cr); cairo_scale(cr, 1, -1); cairo_show_text(cr, value); cairo_restore(cr); // Draw minimum line gdk_cairo_set_source_rgba (cr, &grid); cairo_move_to(cr, 0.08 * w, 0.25 * h); cairo_line_to(cr, 0.22 * w, 0.25 * h); cairo_set_line_width (cr, 1); cairo_stroke (cr); // Draw maximum line cairo_move_to(cr, 0.78 * w, 0.25 * h); cairo_line_to(cr, 0.92 * w, 0.25 * h); cairo_set_line_width (cr, 1); cairo_stroke (cr); // Re-invert y-axis cairo_scale(cr, 1, -1); // Draw arc gdk_cairo_set_source_rgba (cr, &line); double xc = 0.5 * w; double yc = -0.25 * h; double radius = 0.35 * w; double angle1 = 180 * (M_PI/180.0); double angle = self->value * (180 / (self->value_max)); double angle2 = 180 * (M_PI/180.0) + angle * (M_PI/180.0); cairo_set_line_width (cr, 0.1 * w); cairo_arc (cr, xc, yc, radius, angle1, angle2); cairo_stroke (cr); cairo_destroy (cr); } static void chart_draw_unknown_type(GtkChart *self, GtkSnapshot *snapshot, float h, float w) { UNUSED(self); GdkRGBA bg_color, white; cairo_text_extents_t extents; const char *warning = "Unknown chart type"; gdk_rgba_parse (&bg_color, "black"); gdk_rgba_parse (&white, "rgba(255,255,255,0.75)"); // Set background color gtk_snapshot_append_color (snapshot, &bg_color, &GRAPHENE_RECT_INIT(0, 0, w, h)); // Set up Cairo region cairo_t * cr = gtk_snapshot_append_cairo (snapshot, &GRAPHENE_RECT_INIT(0, 0, w, h)); gdk_cairo_set_source_rgba (cr, &white); cairo_select_font_face (cr, "Ubuntu", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); // Move coordinate system to bottom left cairo_translate(cr, 0, h); // Invert y-axis cairo_scale(cr, 1, -1); // Draw title cairo_set_font_size (cr, 30.0 * (w/650)); cairo_text_extents(cr, warning, &extents); cairo_move_to (cr, 0.5 * w - extents.width/2, 0.5 * h - extents.height/2); cairo_save(cr); cairo_scale(cr, 1, -1); cairo_show_text (cr, warning); cairo_restore(cr); cairo_destroy (cr); } static void gtk_chart_snapshot (GtkWidget *widget, GtkSnapshot *snapshot) { GtkChart *self = GTK_CHART(widget); float width = gtk_widget_get_width (widget); float height = gtk_widget_get_height (widget); // Draw various chart types switch (self->type) { case GTK_CHART_TYPE_LINE: case GTK_CHART_TYPE_SCATTER: chart_draw_line_or_scatter(self, snapshot, height, width); break; case GTK_CHART_TYPE_NUMBER: chart_draw_number(self, snapshot, height, width); break; case GTK_CHART_TYPE_GAUGE_LINEAR: chart_draw_gauge_linear(self, snapshot, height, width); break; case GTK_CHART_TYPE_GAUGE_ANGULAR: chart_draw_gauge_angular(self, snapshot, height, width); break; default: chart_draw_unknown_type(self, snapshot, height, width); break; } self->snapshot = snapshot; } static void gtk_chart_class_init (GtkChartClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class); object_class->finalize = gtk_chart_finalize; object_class->dispose = gtk_chart_dispose; widget_class->snapshot = gtk_chart_snapshot; } GtkWidget * gtk_chart_new (void) { return g_object_new (GTK_TYPE_CHART, NULL); } void gtk_chart_set_user_data(GtkChart *chart, void *user_data) { chart->user_data = user_data; } void * gtk_chart_get_user_data(GtkChart *chart) { return chart->user_data; } void gtk_chart_set_type(GtkChart *chart, GtkChartType type) { chart->type = type; } void gtk_chart_set_title(GtkChart *chart, const char *title) { chart->title = g_strdup(title); } void gtk_chart_set_label(GtkChart *chart, const char *label) { chart->label = g_strdup(label); } void gtk_chart_set_x_label(GtkChart *chart, const char *x_label) { chart->x_label = g_strdup(x_label); } void gtk_chart_set_y_label(GtkChart *chart, const char *y_label) { chart->y_label = g_strdup(y_label); } void gtk_chart_set_x_max(GtkChart *chart, double x_max) { chart->x_max = x_max; } void gtk_chart_set_y_max(GtkChart *chart, double y_max) { chart->y_max = y_max; } void gtk_chart_set_width(GtkChart *chart, int width) { chart->width = width; } void gtk_chart_plot_point(GtkChart *chart, double x, double y) { // Allocate memory for new point struct chart_point_t *point = g_new0(struct chart_point_t, 1); point->x = x; point->y = y; // Add point to list to be drawn chart->point_list = g_slist_append(chart->point_list, point); // Queue draw of widget if (GTK_IS_WIDGET(chart)) { gtk_widget_queue_draw(GTK_WIDGET(chart)); } } void gtk_chart_set_value(GtkChart *chart, double value) { chart->value = value; // Queue draw of widget if (GTK_IS_WIDGET(chart)) { gtk_widget_queue_draw(GTK_WIDGET(chart)); } } void gtk_chart_set_value_min(GtkChart *chart, double value) { chart->value_min = value; } void gtk_chart_set_value_max(GtkChart *chart, double value) { chart->value_max = value; } bool gtk_chart_save_csv(GtkChart *chart, const char *filename) { struct chart_point_t *point; GSList *l; // Open file FILE *file = fopen(filename, "w"); // write only if (file == NULL) { g_print("Error: Could not open file\n"); return false; } // Write CSV data for (l = chart->point_list; l != NULL; l = l->next) { point = l->data; fprintf(file, "%f,%f\n", point->x, point->y); } // Close file fclose(file); return true; } bool gtk_chart_save_png(GtkChart *chart, const char *filename) { int width = gtk_widget_get_width (GTK_WIDGET(chart)); int height = gtk_widget_get_height (GTK_WIDGET(chart)); // Get to the PNG image file from paintable GdkPaintable *paintable = gtk_widget_paintable_new (GTK_WIDGET(chart)); GtkSnapshot *snapshot = gtk_snapshot_new (); gdk_paintable_snapshot (paintable, snapshot, width, height); GskRenderNode *node = gtk_snapshot_free_to_node (snapshot); GskRenderer *renderer = gsk_cairo_renderer_new (); gsk_renderer_realize (renderer, NULL, NULL); GdkTexture *texture = gsk_renderer_render_texture (renderer, node, NULL); gdk_texture_save_to_png (texture, filename); // Cleanup g_object_unref(texture); gsk_renderer_unrealize(renderer); g_object_unref(renderer); gsk_render_node_unref(node); g_object_unref(paintable); return true; } lxi-tools-2.7/src/gtkchart.h000066400000000000000000000055771447016333500161070ustar00rootroot00000000000000/* * Copyright (c) 2022 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #pragma once #include G_BEGIN_DECLS #define GTK_TYPE_CHART (gtk_chart_get_type ()) G_DECLARE_FINAL_TYPE (GtkChart, gtk_chart, GTK, CHART, GtkWidget) typedef enum { GTK_CHART_TYPE_UNKNOWN, GTK_CHART_TYPE_LINE, GTK_CHART_TYPE_SCATTER, GTK_CHART_TYPE_GAUGE_ANGULAR, GTK_CHART_TYPE_GAUGE_LINEAR, GTK_CHART_TYPE_NUMBER } GtkChartType; GtkWidget * gtk_chart_new (void); void gtk_chart_set_type(GtkChart *chart, GtkChartType type); void gtk_chart_set_title(GtkChart *chart, const char *title); void gtk_chart_set_label(GtkChart *chart, const char *label); void gtk_chart_set_x_label(GtkChart *chart, const char *x_label); void gtk_chart_set_y_label(GtkChart *chart, const char *y_label); void gtk_chart_set_x_max(GtkChart *chart, double x_max); void gtk_chart_set_y_max(GtkChart *chart, double y_max); void gtk_chart_set_width(GtkChart *chart, int width); void gtk_chart_plot_point(GtkChart *chart, double x, double y); void gtk_chart_set_value(GtkChart *chart, double value); void gtk_chart_set_value_min(GtkChart *chart, double value); void gtk_chart_set_value_max(GtkChart *chart, double value); bool gtk_chart_save_csv(GtkChart *chart, const char *filename); bool gtk_chart_save_png(GtkChart *chart, const char *filename); void gtk_chart_set_user_data(GtkChart *chart, void *user_data); void * gtk_chart_get_user_data(GtkChart *chart); G_END_DECLS lxi-tools-2.7/src/icons/000077500000000000000000000000001447016333500152245ustar00rootroot00000000000000lxi-tools-2.7/src/icons/128x128/000077500000000000000000000000001447016333500161615ustar00rootroot00000000000000lxi-tools-2.7/src/icons/128x128/status/000077500000000000000000000000001447016333500175045ustar00rootroot00000000000000lxi-tools-2.7/src/icons/128x128/status/dialog-information-symbolic.symbolic.png000066400000000000000000000047001447016333500274340ustar00rootroot00000000000000PNG  IHDR>asBIT|d wIDATxkUw  8#(M)ly|R 6VIS>PcڴiEP$5m4&FV҈UU; 8XFak. 3sϽkǹws{ug.QL)$`,0hOK xl^6{D)CZ|`.0K?'Ifp8rfgc@V&X` >\N}=Qcp9 ;} X| &d0WHd ݡȀ4Q%@/;Q[{H\|8chc+ Y.+f# SA߁/Z;wp .wF bAY̱Х Tiqy*])J"gŋx_^D"{#SÁ/G{FX-l |k jGؾ'LhBa ZKjz p=_)gb;mkg v˻]{bko!A3cy_@O26]YK&/^-gc-]0r8ګQ - i[=}v#q u{P$Ak| _7ǾE`z;=]uп:Rӊljl@EZwhknŌyt;Q5G`3Ƭ/98DgK %]uxY~DUhvS-To0Q4P^Ck(y E3",@bYYKZ0IY_k"EY_k{8DY- EMe(@+bjo>!SGVk҃BJ]2H|ڹe[tS;3gdM{2uP#DJ»;mQ!F tiNc+dz1N9HR5֒ }g5d䈣:kZuӦU,@;Wy yd<eԟ]f~ED 4ɨZ t P~E8 4ɐb%:A50[Y_k{הhFQ]CNP[AK:i1WY_;lЊga Hrfu~w5-O +'(VhEL&@v *э|>߷~|BpW?@VdJd:\%K8V"bS?wa8ΟoIeQ/!g'pO|X\|UQ qry&oo~߂>Ov5aeV !#0ғ`/rW|O>,s%S ۑ=+nCтUT߆jV0 4dN@y3f5z<]uXdFk7N&e\ gBkeڥ+U ̀U;nllķZA W{`cDj(nĦ]Cr!vbY ؝Y/`6/C"@5\M3dv,U\mKʷ|ZE#+ߖ=e q>Ŷ"~j! }&)?~Xe\JRwtAv7Ѓ#fp+b@99uE߲IENDB`lxi-tools-2.7/src/icons/16x16/000077500000000000000000000000001447016333500160115ustar00rootroot00000000000000lxi-tools-2.7/src/icons/16x16/actions/000077500000000000000000000000001447016333500174515ustar00rootroot00000000000000lxi-tools-2.7/src/icons/16x16/actions/benchmark.symbolic.png000066400000000000000000000005731447016333500237360ustar00rootroot00000000000000PNG  IHDRasBIT|d2IDAT8?KQDJa-DRD!vY ؋vP,`B!(Tj `;);] {޻!Vq,Y.WW d=rpdCW\>a O*nu|ٴxR> 1:^`.v3O :"Kh6R78@/8nh_L6nS(4'2n0[8P?Hx\ g\/Ɍڧg7}_$HIENDB`lxi-tools-2.7/src/icons/16x16/actions/script.symbolic.png000066400000000000000000000003551447016333500233060ustar00rootroot00000000000000PNG  IHDRasBIT|dIDAT8A @ "!!3:%rqP? O:oG= = 0ET̃_ƀX9FJJ|2VT~j ZIJM?nܽ4:C ⁺Gc{<(nIENDB`lxi-tools-2.7/src/icons/16x16/actions/view-fullscreen-symbolic.symbolic.png000066400000000000000000000003171447016333500267310ustar00rootroot00000000000000PNG  IHDRasBIT|dIDAT8 @@FO/R+R. 8f6R4WnӜ>ćJA{M2?x ``2HYPH9`w,Rk,w?;Pj|i@LbĜ,G1IENDB`lxi-tools-2.7/src/icons/16x16/actions/view-sidebar-start.symbolic.png000066400000000000000000000003071447016333500255130ustar00rootroot00000000000000PNG  IHDRasBIT|d~IDAT8ӱ ` !Q)WXX]KUX`]2epbxGܐʀ-OG hU_1H12&ĜQ>1?Dn[1*U=v@YIENDB`lxi-tools-2.7/src/icons/lxi-instrument-discovered.png000066400000000000000000000235751447016333500230750ustar00rootroot00000000000000PNG  IHDR(2.NzTXtRaw profile type exifxڥiv于sNzTWuD@ @٬mś('X}CWgy=?5ޏϡ{_Kzwܷ'4Q@ÂHD(; ]MK?_7ge֝1)'x p|?oBӁϞw=KpO~XIoQh>ъ9%|qrxqsT?9? _ggͬńӳR'Bo] %P]+T뽦;\ultmp_g>x?,!GmC 3b9Ncsj9w+y:NɜO͟^98X`l+q5AQ/kT]/&'Ё.g\ĭc\ Dq}vG0݇;p"~b!$bSޚK;z6̈2XP QDd)RbRNJ-Mr%J(HI%RjiiJM5Rkm{6fn\8{豋^zm4(6 iYfmV\ʫj;.5?{O5)ƌQE5fFNcf'+ch̦ӈ^3FT#fr| F{~2tBu d4ϝ#ӷ4lj-*R+ MrNvrɅ[J֝u[,ɴcan;M9Dߗoņΐݐ۞;v8-]Zض=-d0q[̿uG"e5X7)5vKM/ƪ2esvsRj1ҸXZR &ZXq=R{-@|]]T%{@t[ W(I\Z}0k̹l ^I U%S!KE%Dl.66ln,xLjƗLMs&;iClJV(JU1 $\wvrb"'^y`6dkՓ\/MR2]H[=rJ.و,5#-+Zkc}{;\eDK*N-ȵCeӔX uWd3P%qXu$=:q(fhavst7g{ rnCKiQ?(.0.T^A^ {&[ݔ]^#e=eI" LXd|#ePa-ɀs$K N,,X*\X$ǁJ4#jN\脲o Gi3.dEݑLqh4m@Ony_gh1:Y@;p1sb I?Cr ~fhhJ"͜?و0 ^0^pH㐼IPq ѫ?.?]o_3heefxo#\D>QA|̍u})BV, *[3e/"|ԪxPJQ'PNx/BJ QD nO~­!#¨WЛ XduCwu3Szh).ji*^M]# J_=t|3_ѯ2*It8W9uүB-D_jҭR`X ܧ|ApL J0o($R~9'1Ə J`~¯(Hf}L!-9Oyp";]MQx,Ӧ5-_JKEØS0k:R JݩDDJg7kfs4'@ 8ssEp-auXx/Y 9\3JVE7 ]_b:FwP}3ʗc+ܤOܸ lڗ'.ڨbXAWwO b¥BK+*ѡ>8U m0|T']"Հ2TWKH.U8h(huke&BY֣ 㮳v_R.#tsBnPֿI71o~m.&:leeڿ̼LN[Wew'0@:IiKȈQ p]SoTh夹ΎA^7VZ=ibsf=R ϼDHWMEk~RK_A0h~;VwnP ^^ mow/'8Je3=#eWIxʤ㪝;7?\)D->x{\WuGS)S|7W)ʱ|.?vIDӴErJB($O1ҍ@VLKRJgGXBe8F%>L{O>ѧjH^"V[-e5IݬbWIk)-AyEh?IQ1ٱ{J5ZT%ّY><@Ӟc tWQA!-}%i;YiFާ÷pv:Ro? oOE^yN8SטǚD;tӴ,[)󬧆ko_*= XyefH*UM##3/V}t+'nz0DǞ+ڏw>&.9T^)VB^umNwԢDS"6 qK4>!X~ǕՖu ۀ%fZ:/N*)]Prt_J 6R&rypD$k%<ݤxhFKK`.Jm !h9c(=, bћ'oY:r]( /9HG3Q/u Յ¸}PqP8F8Mw9( ф䳷MڧbLGj<0YI  f_5SUmIYNvc & -6v[8L ś9@w~!~aY1Y'\; Es犯Bv"/m0F Hцh¶X(1d|t4hLo;ZK;B1䶰qCR?a$r#B{DS}ztbI b~h:&ixB_P !Vbگ>B^JoSsラ٧qPh0j{P`ݔ?{D\]<,'u-;䵂#湈a|I?X8I/QCrXEZH%`3;D ۠kӷ!Lq ]{Dw#FJ%ŬVEАqt/UzNfI _r!b}Tg %p䂆-_?@ 1@~#lT> jݲ$WBk ƪ"'cpBY2Pp@grYnQuoSW` i1 0 ʤ E TDQy? uHNw848}4aOْVV/NGj #8!KC@%\`MgcR(=3EZi\E[z>-\8.vġ>$n."Eݶ4.vL \%Fg( cԇ$ӧ]}K5CphYbffm{ݑ`/@܍Zϊ9.z 3+̭g:w#;Wﳑ^ d>Ml~2Zvcut ՗n>y̱1K/~7KîYJxofcWϦia2Yw*gTByϞw<)~WJ߼ [`[Od~+HJL.hZ_ؙ&H^,CiF-:0WGb#I;]z)}VS^JiiCCPICC profilex}=H@_SRZA!Cu *U(BP+`r& IZpc⬫ ~8:9)HK -b<8ǻ{wЬ2T2ɄͭWF$)u_<ܟ#/ ijL7, MKOee9O|N w☘bKGD pHYs B(xtIME  WIDATXMkV!ɲc"qc;vR"iلJ[hC%d, t]P)dU4.sU 8M(EŽ8e˺=+=?Ȑkdf> 7 PpPZOckB6쐍)~t_Y?9鐿?Ţ맽hEQ8穷 ?0w$Fز,,˹Y2bj_8ķ$cYOaج{l#= T-9V &c}}} !ǐeyfccc㺂4w : xW%{BL)u'Vp~~?VAI`xggUޯ|RS>,v'Nb]9G:j5\\\ NCUՁr !R:,B2{m8}sJ2`l0 EQ`gk?-&azX,۶QTpvveXFH$|>09N4)hL/lvvaZBe@%Lk ĽIZ>4P(ضx<9!nB].bLLtu]ަwpprkkH$U0!ZUTvooeI?~fPU}Y$)}ڝE;8ׄ4M霷ZGGG?VwL12{{w{ ǘMIENDB`lxi-tools-2.7/src/icons/lxi-instrument-manual.png000066400000000000000000000236251447016333500222170ustar00rootroot00000000000000PNG  IHDR(2.jzTXtRaw profile type exifxڭir% >w@k3zK-$$ Ͽ?)EkbkΖXcޟv^sqss(גߎ[S0PωD|(Ej|@e\|\B_?/mr^G{31O~,:%ބ'+gx|1*m55~yѧu>hE\^߿:34reǩ8G`R/kT=_LN&o:Ƹ@ eg{qG0݇;p)>M:5;9l8rbSC#X1&#B)$TS!ǜrΒFd)RPbI%)ҪL5Ws6Fnݸ{'s^zmGy(6 y,ζJ+UV]m̎;e]w{{QsO^(QN$i7qh15r3[=Yw༾ol _^y7Fư<5gk9z3qÜk Wc-{:|71:e@d>2FBv Y Y \z)V> I^Rwf I',ޡNs \ަ[1g筎ჲOm!ǥYinɂVtut(\@/‘Wڀ#o Ipc:0HQgi ZnVhdl$F@zq@hq(>ly"#*0,qK]UXzq~MMԕUSP^ѹ2]rR|b}_@!XNdHwy8|ĶTD_ N$#ʋ&CL@\Kuۜk#/dOH䌯d0cΦ y8]P`<'2N`{_zLO0h }ڜ9Z܇WDpiY^8C؜uNnUj2͔c*39/#sGvv Z3qdWnn4r2Ju"PxkZRx"qBʫVXƨV"DI46$@N,Szj LPV(S6uNH=9?8#&ELfAN^+xkru^߃'24MP*M`0 W=Q)cO͎ۘy戬N{kC06x^eM_Om~>Ss=fnrUyRSitN9%as&;=eAbfZDZ.&FG$1K jTs_2>Zԣ|Y@ZJMlRܢGQqų]ֻy?›_NxNYQiqx؁"7-D.:q@-Čr5nX S퐾T\ܴ+"LդR9 s)')oO UwqtU-Z2Vd>ΝM4/T7jбOu$zJ5To]>/3]QhǛbA˒PGVOImU^s^Cs sK(R.Oxnbj#8ha;P !<`S"FڊNp"{C&S6@"Լ pF_Bbq@\@h}C;<]-0?IV ߍ!xh4Ο[fLWeij.?l.-9T榕ơ"+!-ul?}( TKf'C4{*{߲-rE:BcGV&&*qJ&+欿{zU?9%xGQNp0eTݼXe)|bp9 n& DTpտU4GI]V[NY76_|eħ,&PV_W_9rW'_u־}CocHZt޽2{H1Wg-{ ]zP{shD0C\%ע 8 C6W+X~Y \Cw4`5ݺI(g,\ɅCdM^$!`JޤH(t}EHr"J)buֽ.W}|hdiٓuEJ3+ @ uhiswIxv,.겜^b,(Srb-^J Dzm']+MժO7ڨ2rĮh>at mz={׽z0"nX!u'k}^>8,&Bk&EL-!ƲPh?e}b+@^7-#>ƖSD%1\= @pCf%e=mחqWw#@/[aK<}꽘AMѠ*4,˷xPxH9:|w@K϶ l*:zBס%_y^NA6U̡jӮ |7rȍy4$03wL\i8|+DsIr@i!7ʸ$# ڄ{ñ>ȁY@BÁo)x!$4f)`+ <3#Jb%ꝕ&6{b,mN%b56J$=+Bp4oD-m7:%+c,A~qv y͕i!|rv@"aIK2`@ ͳY u*]CWi}ļa$y—%dⱳm}׌!wn@/c&Yv)ۦ@ JiD5>huلL"ϺCU6iS;:)9[V`o+v[7>w IL I~d&Ⱥ?R`d}sz%Z-@r*G6rhۧhjY:?;+^`+<"`xShTzm2a>Qy.y?K(V'3Mn7FڵXTeK(w,lW=jd nhFso S+A3;8DP|is=v :ArѳTvW6}Ȫψ/2L`]C ygK1NŴO--nدS@%\t6#"Z57}R2|_+(yPUט[Y2"-T[ T4A.IF?lu-(\hTZ:O}{ҐɏKIk%薥DJY`w؈L+LEhZ=8|}iT3Su3GqyPDnEn&2b @HԦ&#Ro̘B2¬n&JI(DU&b>/ E֤굲ngYsso48QصuJ_B]} 'ݲws}T tTˉJ&$`sA)$C2M}>89C>;[lnTiTzCmO6>TAIJ0 AX8$msTфtu0X{2ɆHW@ܙA+ ɂ+yV^˜Rٓ]X;Fl!ϳJ>I~\Scܶ#0`6,V*7w Cg؋_[ABXp캦HZ엢fsVʪӂun4QY[ ;Kòk'"4?ߍ2WF)O`(/E붏tA~*wyvk( /~[rHsZ^&4t"+3ެ~jڣwDG}tD][]^aޑPA|$_激5fiCCPICC profilex}=H@_SRZ ␡v *U(BP+`r& IZpc⬫ ~8:9)HK -b<8ǻ{wЬ2T2ɄͭWF$)u_<ܟ#/ ijL7, MKOae9O|N '/bKGD pHYs B(xtIME .}G?IDATX홿OFǿw>q C! uڥS@Н%ZNH*J ̯ځ[ "c;x TIؾ$iA BwX_˗?د_'K7\.Mzcn04p]ZiEQ>4E*#+w7B0ʹm}dYH2PӴO!#MnØ?1^E^J@A^(Q !0oς`^$)3Ĩ-RB0@xttR42%t\ !$pX]] c8oza cy.9>SJ݁5?UPe92d2v!zQJVU H)u+?tua`!J*2 4Mh+ #N\.ömR9{qBpCt]c b5LӄiPUe ((IR2ݵO"8( lFR`&cî ㅭ^^4M\\\@Q́s% #ޠnpXeYG$A288>P?[RH4^^Kd2bUU1;; 4 2wn]nնm\]]!9yoL?1 $!J\.T*AuȲB/;Bs&j 8fCP(CrAX9??r,B4E"@\FV)'I$fkHX 055+9G.Ct]B_VA}/JP18ILNNq_!2 j0;;Jw&8]mPJ ZXX$xe뺎 ض BOrqi 9s]u]ض{vz)hYV%iU ,ԅBasGG ղ,0_77DӴuY$IsZ:99igg$3lsMEIɲ-^BU9,j4WZo?-Fv |\?I6н \\75e ٔ])HS3,{ tz5q pp({{gr}bKGDC pHYs B(xtIME #"R8IDATXnFƿm 04$"@Ratɲj7}DMgT l*E +eSQuY](# {nj b!W F9?s"+@NNNjGEQ$iW5Bo!i\լQ( 8ZZjUU !Xde+]׿ 5Mzp~QU_Q*R&,ȕ$̲2ƾRJe$(Q4 v`* (,H(/h*HG_8S pQcS[AoBL)fV(˾UPeXblB|||QJ+?)ğgzzoKEn"^b0CP=k۸GPicڂim|~9'r-; !D3]CvaY4M$il8LOld8&noo ۶tJPT`Yc΃3uj㇭ò,Z-(m!}4z98,VVV lQJ!I ylfX,²pbL25ض;$ ' .rS0a$ |inCuȲ4;Ο?" <<< NcccR 148+GD]777HR(#L"4Mz=>"19H[!X]"*`}}=PZrpV]ǢK7iJH18\.\.qu\EP@#":NDMqB z7O괻;qJ9!Ǻcmm m:!?tiN^^^v~~n~d4ߛ3?3-؀P2IENDB`lxi-tools-2.7/src/icons/lxi-tools-icon-128px.png000066400000000000000000000461401447016333500214770ustar00rootroot00000000000000PNG  IHDR>a!zTXtRaw profile type exifxڭi\9sr8foozHRYU)C>K@X˥:j#8ϟ~K"O%=_0B #]tyH~?__JBLxͤ9a}RB)/4y!7=F‚:?ᅤq$:c9ʓOO0+ʪƚy]w'pN?L F*Yb՚u6/vͷzw=j}߿-jEJolߣG[v 8)9Q1=BeQpNPĈ` c7-rN'"D׸IԎf^TZT(3d"f*K@K|m봵\wj7 >nkwvN( ,d}21{ns9So''ܵe9o87[gX--V'G 0}KmrʷAߒnZwYns:X/K\W?+]B}l^/DņI%YM-gZ]Pߝp8`m[!f"V %[P+n,6mխvz$)G~XHϜDZ(gr]hRTYDnJr ]?BuknꬕPcL״=V;gϮ԰ʹPz| z 8_PL$z֡\XɚccQv\p›eFAfrc-djW koݷdofs2qrc.bCFq[CCD^2#h̉aT(l{63!5r*RUI@0:w! Ċ0%f)C;ɴDAD)ɥe`Oh-rl*d`h#y^ FK-\..a' 1IxИVgS8NXFj!kۀBn ]p1Cx14VA`(Z6DqP1$L`h2,T#$?: lU"ؐxI;H"dW@Y(==@.3o[= / [ ˌ8=V9JLJkt2(shĂÀݑ+1AKLǢ18]RveH6^ Q2":pi35r7R2(oYvD@2bpV20R=%p Bߍ2$ aV)kѵ/P'z~{1O=I&@3EqZCK(6 :m-n/}Hd6Pgxj_eU8Y RԒ_JU깯)p0#u$8@P1Ea :"# >*rLǃX%hB:yV$kZEL YIn=Ip@`\j*H#dP .o"R @ 3)@LQ'~V)#D$6|g`нHZ"dOȼ4-fL"nE5Z@7Efj` y@=G. XԽŊY@ Q+y)>0m$v`E4|hXͫvJQi&Qrxx5KP2c6%f(?9C-^ 9Yj^0n`MYfe`@KEs#?i3G5E0@P#\O6M;_jC| ⲱQ/ AlCIbP$J zƅ%ѷ#>1l`r'pl!؏oױw$0n1mF-BVeX(j+esp8V0U >ж$rS?,$\׬R-6H+wwDjn; qPv!h'~^Xg}=¤ {yU&S !šhsLZQu5zˁBm.'Z{H-0 CO!pQ܁!Kס7JߴWPk}Flp7W!î6 `̍r!E6C&az(WOu9/WLQA,EM!p9rPh`^Zd!iT251Ld~֝W_,ZtJn}&؋tK=VKȇjүDtB~(J1hKzFw@{e3f[$,"=N{9BܦvFl!!)ct ]z 'R2e6t2DpXF~  rLA^=͸5{$R@+:CSN2?}how c=~L.% 8?r/jkJ@_#.}6Nl}U߽Rm|8g`+ =A3 NW<GJR鷯\)2VE6b7u^ $HYp?bͯ[Oܷ m% 0 _qr!v Z؂q}~KGsfO-Ep%k҇]kcw݃;@QT~Ȑw4pՅP1a㔕g~BԤ[gs D<σR oנcJ& b5AxՍf`W.xli=SR+Bf!?DJuI/ya1hzK?}1o"GQ ^ xŬ"0ëYS+ xx#Q\vK]u=S@/$.AϷ M"ehP j#Hwh>ͱ1I C)~Z@İۣl;rx } [eudPE7Ԡ{c%=4P&*cȩHb|8 %|kpv=_ uIf9[K9ܛ{;R%emUU<,q/wIT! XG ortpU{*M u:[YAZ記Ԣ]o5O`GkNc{48Ezᛨk;-^l6^"VօÒaLoo+j.m0@m#4;{)K܈Z!;Q[+&Ԡyh@Wxƈ" 6MKUVÞUm&LץvP#An2CwJ7@xĸ06LcbcNLjyr7/ed$qhx:40ט6 "Y> fT34$hKd̄AQQƙM6y߆*wlޭL 8S{I-LаO A\!=.|F:U?ZJZ֒􃠺\uc EG" a&\@ M.c`!x+2[G}M:vqTmE>| fo*(h)Tԫ2E4'l-_0m% I H6 ZqDFqˌ5E.qAoXE>\A CuHA|K:-SL$!K>Erţ3A:&P}:P:g@eNܨ*!t?AM ]-Lˇ ,ڢcҥ=D ݵYUb:Ihz;:<ɋS΅DXFbNj*U*7)}]TkW R5z$&DQT{RԴjejN\DtjE D١06R~m"l1p3u)cZTk@I+$7t!q!kH\=܂ioP;m:?*#r'8=tnqDP/ 0rN1ߗA8N\]f -0@u$K"MUkOKdpӷDMaox7~{gx:cEMsxW*dM*3;N[]uMs>g\z92%<9[pJ- A#_G^Y 12+xҙS1DLgt!+Ed^D8PHkshP*J8+4;i&'鐹}3V123mE dxWRA,i#*f SGOj=АWQ "D ӑNk.;2FVx4P{9N *Ktҷ̐c^aaeʬ[_X~QQM$r{(G' W{21NS즯GF 5N 9e2m-|I[AtѠ ,+cVi bgt0̂Qr"_NiCCPICC profilex}=H@_SED2NDE EjVL.& IZpc⬫ ~9)HK -b<8ǻ{wP/346Sɮ]AD1"3˘$|=|,s^5g1 2ô77m>qex̤ ?r]segtj8L,XicV45)∪/d #bKGDC pHYs  tIME (0fvPIDATx]y\Ue>ܕ +;+⒚iI6Me5L44ee6KNS[Ki. dp ܋$p}~=@N:T*455MIQT$!D R^pPjjj~W_Vg4(aw߭ZpaYsi,YTHH*rIhԖ>>>~]6mwDT͠8`;+`Æ Yf$|0[ 8q׫ŋiz$rƓE%K"x`YvEQT$ (ZI-݁ f@D $H @D $H @D $HpSC΋3,d3(\z&E`Vpl|dz|/c9 O!1,F  h2=U]SR_,4~8 $,}b.sNww*@6E16WmovyzGق.r]xу]~R>]g{:t Q> hLPTǍŗPa >oj5 06 1.?S`(f,׭-(Ê'B?UZ阺ZڅMpox_Bp<2@Y-4f҇S!`('A/Jª(Ɂ^Xtt1i p 9 0*k81$Q15_p\i Dz O+uۑQ 8vafEvb9 EO LJBx /5{`V~z*=߄u? @ o.8GKjĄW5i#.<[Sp{ro; q+?܎YDH/ŭ;iq `m8UXf-~PnOx)A_Pt9tu0,l؏nA$ǦaQL !rK"F$CQoPU^ FC₺]ic1>R8[ӌ: 5େ'ba$-!OYLxJ~5.VFaVԊףKO{&Bam@}b",xc+X<% \{Ym ʊ&B;8[V/JMW8O#İm ! / X=V#VqJj-` .!%RGyX3D%q餹; / gApKRn<0oڈ%G.,82E ,n΅YS!8.S F}@C{JVnl '!A&3 $zȑ^nԱ` >|I wuDے"t)nc}{ /?q(r;U M*)0Bpd Yfw?q`s]YHeHJ' _&رJEuBϗvTrl?}4p6Kjܓ !ؗyWo]h20' OQCqpa_t PSMNKՎYgJ>x,}|6r@RU= "JxU&bEi} H-FUT7ŷ7J8_#8UeP :sͻM":gGh *^Gv  t2h[^}F/}2| yrؐH Sgq L B8j34P}aL<}{j[4z$'#9)^0o0<&I w'^_mf;;O!x-4jL^y[ۇܖtz~F%vr[F_̀!2=&o$@|`4r^+z(@!feWN`^e\a5 ݸ(@/#8\fwE2izVXmv, p 4{,ˡlnךh jjN Q=vLf6oB@h(rԧ`Y?k8X/nh۝`X*D )@vEXXQEbl LHQah`oF.!|%r+q֒5UcR#cƤ$:/ɲݰUm*?poy{'ˑup!|iq}qK|Վ9\i=PШU&/FIs͎' 񛷷*H6-akv / { Af70`lƦ]ڟ%,6:wM< *̳wA3ke'0O_`JS@NgS!ǵ';`:vܻrLɧ[3com;2:.fu`/ѓoذx'S-D/aDLKp.0;.IxUuMȸP3!2Y5AQ¿ӓ4& v{3kH,'1*.9'Po3!{F#&2ԌgXѕk6o|c12~01l(n36! Qi'],$ J`P߈o23pk*] ?s 1I3|2>w"md(ќ"_&?CU)#y Ϝ=XuO|vsѦ7'yk$%T&ooĦm]TX}ƄAF=Cޅʖھhg1ul,06]Ov]rx\8S^nbcf1ct=cyE! mQ]VmQUgvǯS6 ehRjo6]fü_{aaS(e4u 6K+qAճF mܔYMCȨ0L3:O켺 p>"6͋jJ|L _(?}FByW`\,*`bJom]q #GuK=??;;F"6;a[N(rZOg0Kf*+NëĈ، :.ثSq}\įiP2 eUNo2$DPM6`k:OI[ES I^ƠG&"Av|;_ .tbv_ |5;l64TB)НdFi5?饄5htJ"hJeհSwD\>q0~?H#sZ ,{~a6NAT }M-&nwL/(i:/Xv/MWhB% ]+XCZʝgfr5d!OoUd4{gb-x@E_¾Ch=G^UWjal`_wu=q5Y_c0mȁJBjI:v~:0=&fV%bJj=nr~A˽Tny*>5!s&]s<}N='K;9Xv D mЕz# aHLYgt'D́:$u!!O_ a.b8.c;'~$~pXpziaQ/G$B߼8Zw5 ҅^!YspHIBP\!rW>8wur!h4Yp9^q7d'HWo5]&GCq18`` 'pΟ Of 685 󿞀v8)|yLƼ@.p@u+[%wbp?,Y?Xg }i1qG;|7d"*I@8UvLeO=M0ם0WcZ[V/V;c#> λP?xplDNMZjr]J6xrr|)#6PI?rZ[nݺ:?I/ADIENDB`lxi-tools-2.7/src/icons/scalable/000077500000000000000000000000001447016333500167725ustar00rootroot00000000000000lxi-tools-2.7/src/icons/scalable/actions/000077500000000000000000000000001447016333500204325ustar00rootroot00000000000000lxi-tools-2.7/src/icons/scalable/actions/benchmark-symbolic.svg000066400000000000000000000107071447016333500247310ustar00rootroot00000000000000lxi-tools-2.7/src/icons/scalable/actions/lxi-instrument.svg000066400000000000000000000117161447016333500241630ustar00rootroot00000000000000LXILXIlxi-tools-2.7/src/icons/scalable/actions/scpi-symbolic.svg000066400000000000000000000043761447016333500237420ustar00rootroot00000000000000lxi-tools-2.7/src/icons/scalable/actions/screenshot-symbolic.svg000066400000000000000000000007221447016333500251500ustar00rootroot00000000000000lxi-tools-2.7/src/icons/scalable/actions/script-symbolic.svg000066400000000000000000000031761447016333500243050ustar00rootroot00000000000000lxi-tools-2.7/src/icons/scalable/actions/view-fullscreen-symbolic.svg000066400000000000000000000045411447016333500261100ustar00rootroot00000000000000 lxi-tools-2.7/src/icons/scalable/actions/view-sidebar-start-symbolic.svg000066400000000000000000000011371447016333500265100ustar00rootroot00000000000000 lxi-tools-2.7/src/images/000077500000000000000000000000001447016333500153565ustar00rootroot00000000000000lxi-tools-2.7/src/images/photo-camera.png000066400000000000000000000120211447016333500204370ustar00rootroot00000000000000PNG  IHDRI#sBIT|d pHYsetEXtSoftwarewww.inkscape.org<IDATx{t}ǿ][eGBZަ`'MedŊS|ߟ`>3_p՚ u`ŤI̟?TWfϞ=8ahdH$N0n k xrxxx'oqR̬0e0Wnu"ZJ\? = s#lS^΢Eӛh3=` \.׷7 vkk?piC|Z^烝qlټyIf0ăK:::j' 96$b{{y/1&a1!itmڴ鶏CҼ!4:MC`9 d```zV{L r@WDd!wИ]MD/1fm{Ge˖Qhkk`""ID2f8ʾҜh RiFhU(L7F*6|.V3!-#DfRt3ߊxX.fvkګv3И!acYaW\3T*a!|=Nl(A1G0_ x)G Ǩ\.SOM}de%յֲb)#j s EO۶ݽAfGlSϪ@D汾{eu$ +md2U LfcKKE=Ix?cYָ?ǘN ^,+ḵk͛;۶Rmoݺ~fttעu$ oXfGT ;L-"ZȘv]Gry̆N +2P![vUEa>pMeim&UV8A^1crYnmm}jCA I+WVFEY- ?hN\Np99N'#x>u5tAWUVYF  N_JuORVC#{vjedĖ9Acت aJ(yfRF숸uKd,KJ3պBP"Ot\R/fU ,Jf<Ǿ2})7D3qUA/B9̜W!4R 1A~+c 鶤|_t\."ߊ K=`3DǍ{y qSZ`Enj SB!'ETV}rJ 46;P0*NyqEd/BN8JB6]+2J1vqCwq.AYIq]?+2fL9mŊSq̈́6!"'>xͤZ&zA kY*i "4wl3[R8Vd )%A,s-1"&戾lOD+^c"΅21mۢOJc ]l C6n(z.8^z1pR61dAM&/G3BAh3< N6Ä1 N#3 'exqF1HPKDc@̷1H "Y.1^ l>DdvLfk _r~> @UAKz{{d̰͛'C\ߐ;hkJy/~Zm-a9ɇAp9ߓ_5:nV'om ݲ[yYZ]d&d؞4)ՓM6%e5d󼧙>e5F'/;#c[:":Bv;*ѽ}u]C\.eY,m۟rQTfRF{a#lvqX-t!xrd2oDѠwBpN8B몺E\qQR0 lDtU{us>IA^#r{Q7wp:)&e~d>}}}Um$ B6]DDʾma,{v,{>(6X 0 -W  3yE9U&Q"z.CK@(IM0R:&uDM `RR.b>iZ&,*W*ʠR `đTOR._lHA3mT/Ӄ (8I$ jsQ,G(JZ)g֢ɉ-J[<;2 gj-q#$?Z9l ㄈhooZXzoC21{6̼LQ.'ag̼aLDAwi x]!fjժ}F"!F|qяT 2B- {l6;> poww:`-m/^$!l=A2F" aW-Z^!iC]Q28cۿ&jzD`-[,wA<`tYb/J]Ҭy;͋dV {0^;3d{\]$A[6 qw=fVt^B}B1vC z}֞ٞJ2\{)`Pkwvvyo\OmY<z߇l5dd@#aUV Iߴ8pIENDB`lxi-tools-2.7/src/images/runner.png000066400000000000000000000133171447016333500174020ustar00rootroot00000000000000PNG  IHDRg- pHYs%%LtEXtSoftwarewww.inkscape.org<\IDATx{|UnE҂EAPۀ bvnS5"Xn*/\,Y,t̮K \򪴈B69G$;sl<˙syB \Mѡ!`џR,ki===ʬb!&*|PԷ`Uy |]TQ^`4 0SN/NBHdiRnE~DteY?Ǚ0?y[Bs 8|Qm&S:ת8\d>eDD_C2̼²-yq|} 'O#nkYC>R8\. e] ӦlFfuk^Fq&~-+]~VJd2VO---gPq=5e\T*jo|,擎_bc;;;}]urѷ}ubX€|~BX:'NW5UJ `9 !]blq̜?#Rjt:ht+J'|3iYV1I&Ńx"z\2aB3| /u_x>RfL4 %׶.5kPyM\/Xx<,^xD"0.!ıЈ~`UfT*-p8; oCDI&iomm#c3T*5;}Lj^@D"kZh,_|Rв!ѣ00V*gX scw)mhmWs]J+W0xR, ѵ×tuum0-&~IJ_wJ=nʗr{^#XPxH)p3/-8f PJ+;=1y jrW 1b\g#mf{Yu?]th^`+'MtxVlٲɛ7ozXfj*upҥSoywDd2<- ;*NboѻĪCj.݀Ba;u߱'k%3k)kKz{{wbQ7FZ@hف3Dd"8Wf2iT1DR˲܊G4g*~bΜ9U/1ֶ2a>i5 5AD`]Qaj18ޯx5W#D3?jժomkdb'Oލ+,kf>^47#XJ9v ;]׽c͚5+GDOaSyy^g\ng{L6k׮&* !ίf?D=:~.e]v4rm2e,K*yBG tw ? s̏m>|e[~%y5QF)`hh4W3Dt<<? ;)̗ !zBciDt-6 3<2լ%֋R*-7 x!gP/!Ma"'f>)a̜YֱB^f>Mq+T\+~rS{{~ْ hYS~/ѕB| '0sdhe !LRWR*HUΖd2J&\ny#gY}̶>)`h93'XXN/7K)p?0CZjCPuݧl3Oa~˲ηm{Eй=B;J c'G3~3gO:;;lZo)G\U\|b\EJ 4=J#HH `5]5>"H)!c3އn3gMvgGGǰ߹Gyl %m&iokkG+ȄNuiF{>OYȦMР>;ys2u- I>`3UG___|```g;DD:PD"޲g^ch=1U崴@u@x<^{*})/ ;,eϧR)SBEÖHs]"|~+bo$hH:7L 44*\JI&΀R#6CX컦E2`&оR'ׄa!l4NB8O$Fƀlv[ֱ5jM4ƀD7mtia!&+]D8+`u84hYe&r2L f A dY֕]TwEHPJy43lZVlYwL5`___+]jZ(ܔL&_2-" Dր7nֱRa4ŋw"sLD0NbZGT%Ol0jg&I X9}wipF HDW[%]kiiδ)J)32c`#VjRX,ȴ( ̃?|.4|:D€f8a-ɓ4-"D€D˴ADy#E8tf~U Um(osܧ~:FBCM:{zz," m;"iZΜ9+f1 ҶߘҀ˖- uAiB( 844t.iuJGrW<޵!`BL *2D|p$Rۗ.]:մ(0]v加 7*D|̗]vu>i1Q!4\.MDJoEB3LK[[ۓ0g^PJNVBnkk&|>˲I)okGŋH$A8+:&ƌQǿ70D`t\d>X1Nsi!1~}滖n0)D"X8N;x1J);|FGl"zX,g)e̷ |F|738馅#tʍ>gaeٝL": [ԩSO+(F 8| !Rw8 7IC=<vvvjZHn)xY9V,kF2|| /_}Ti#mO ՘f͚Җ̼2eZHP:j>bBse& }y0odl֡@G@fX^P`كBkX>`{ jF@)a4} 춱Xtf>ȣV:Gʯ@FғʡDt1F۶ <al=P˟۶kdܹsJ$3!m dڡe\.)۰my!\fDb9+|8\݀mmm@+^{J_) *3\&к P(4kKKbo)aD#f'r@DDtvP54˲p4sŰ̱6J)pN&0Oc`/IC{9:bRg˗f;n<ĪU̯-R/[Glf%J#6 ]׽ #pLW<+JgPv|3L]wuf̘q CGh0`kkYŲG~9) 78u|A*Ĵ ՀlvʡOM:?V^ T׫NHRBWZ@1D)u_[֙ǕJ+GLXaYdri!AKv1;Y]Y"#P>ߓQϹ"]E#z _F@f&qB0cRm:@gU˲NL&Ϙb _ @׫z $'\pHDgZ|#`&iT5bq\FfN%#~{+Gֳo/Dt0DDC7>B4_i.UT~ B?6 |J) /x\7&"_,noXv9G-~N=91ub۱kdfp]~KqC{xFD'!ko|9'|&W lReɣHvTxX,^5R15fJFCFѠ|fwweCO03>4_}4V]ţR_hpp𹶶#D5!Dmj/i!˲+Xwww+b83;Udf]jb\2g8%J5|uMb]zu/? !kN(KUKqRcLl۾MGdoQZ0c,/ߚθ#ZeiGBn_ϤDtM飚Giޭ!73w !~ kJU޲ SNϘB0u~+nl6˲0Z~jYedtMt .60HpDt$3 הR3.6aё.1^*x ^'JA 9,kM"Ș$"~guvvnI`~O?,BHc60pD4xM1 Z um4֤AӀte"cIQG1ϙ]]] text/x-lua *.lua -- --[[ ]] false Communication Discover timeout [ms] adjustment_timeout_discover 1 Instrument discovery timeout in milliseconds center SCPI timeout [ms] adjustment_timeout_scpi 1 SCPI communications timeout in milliseconds center Screenshot timeout [ms] adjustment_timeout_screenshot 1 Screenshot communications timeout in milliseconds center Use mDNS discovery GTK_ALIGN_START 1 Use mDNS for instrument discovery center Communications protocol 0 Default communications protocol used for discovered instruments center VXI11/TCP RAW/TCP RAW/TCP port adjustment_raw_port 1 RAW/TCP network port center Appearance Show sent SCPI message GTK_ALIGN_START 1 Show sent SCPI message center Show SCPI message timestamp GTK_ALIGN_START 1 Show SCPI message timestamp center Show SCPI message IP GTK_ALIGN_START 1 Show SCPI message IP center Show SCPI message type GTK_ALIGN_START 1 Show SCPI message timestamp center Prefer dark color theme GTK_ALIGN_START 1 Prefer dark theme center 99900 1000 100 1000 99900 1000 100 1000 99900 1000 100 1000 65535 0 1 100 lxi-tools-2.7/src/lxi_gui-window.c000066400000000000000000003071111447016333500172250ustar00rootroot00000000000000/* * Copyright (c) 2021-2022 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include "config.h" #include "lxi_gui-window.h" #include "screenshot.h" #include "benchmark.h" #include "misc.h" #include "lxilua.h" #include #include #include #include #include #include #include #include "gtkchart.h" #include "lxi_gui-resources.h" static lxi_info_t info; struct _LxiGuiWindow { GtkApplicationWindow parent_instance; /* Template widgets */ GSettings *settings; GtkListBox *list_box_instruments; GMenuModel *list_widget_menu_model; GtkWidget *list_widget_popover_menu; GtkViewport *list_viewport; GdkClipboard *clipboard; GtkEntry *entry_scpi; GtkTextView *text_view_scpi; GtkToggleButton *toggle_button_scpi_send; GtkPicture *picture_screenshot; GtkToggleButton *toggle_button_screenshot_grab; GtkButton *button_screenshot_save; GThread *screenshot_worker_thread; GThread *screenshot_grab_worker_thread; GThread *search_worker_thread; GThread *send_worker_thread; GtkProgressBar *progress_bar_benchmark; GThread *benchmark_worker_thread; GtkToggleButton *toggle_button_benchmark_start; GtkToggleButton *toggle_button_search; GtkSpinButton *spin_button_benchmark_requests; GtkLabel *label_benchmark_result; GtkImage *image_benchmark; GdkPixbuf *pixbuf_screenshot; GtkSourceView *source_view_script; GtkTextView *text_view_script_status; GThread *script_run_worker_thread; GtkInfoBar *info_bar; GtkLabel *label_info_bar; AdwViewStack *view_stack; GtkViewport *viewport_screenshot; GtkToggleButton *toggle_button_script_run; AdwFlap *flap; AdwStatusPage *status_page_instruments; unsigned int benchmark_requests_count; const char *id; const char *ip; int protocol; int port; char *image_buffer; int image_size; char image_format[10]; char image_filename[1000]; GFile *script_file; lua_State *L; gboolean screenshot_ready; gboolean screenshot_loaded; int screenshot_size; double progress_bar_fraction; char *benchmark_result_text; gboolean lua_stop_requested; GMutex mutex_gui_chart; GMutex mutex_discover; GMutex mutex_instrument_list; GMutex mutex_save_png; GMutex mutex_save_csv; GList *list_instruments; GtkListBoxRow *list_box_row_pressed; GtkListBoxRow *list_box_row_selected; }; G_DEFINE_TYPE (LxiGuiWindow, lxi_gui_window, GTK_TYPE_APPLICATION_WINDOW) static LxiGuiWindow *self_global; #define CHARTS_MAX 1024 struct chart_t { bool allocated; int handle; GtkChartType type; char *title; char *label; char *x_label; char *y_label; double x; double y; double x_max; double y_max; double value; double value_min; double value_max; int width; bool autoscale; bool no_csv; GtkWidget *widget; GtkWindow *window; char *filename_png; char *filename_csv; }; static struct chart_t gui_chart[CHARTS_MAX]; struct show_data_t { LxiGuiWindow *self; gchar *buffer; }; static gboolean show_error_thread(gpointer user_data) { struct show_data_t *data = user_data; // Show error message gtk_label_set_text (GTK_LABEL(data->self->label_info_bar), data->buffer); gtk_info_bar_set_message_type(data->self->info_bar, GTK_MESSAGE_ERROR); gtk_info_bar_set_show_close_button(data->self->info_bar, true); gtk_widget_show (GTK_WIDGET(data->self->info_bar)); g_free(data->buffer); return G_SOURCE_REMOVE; } static void show_error(LxiGuiWindow *self, const char *buffer) { struct show_data_t *data = g_new0(struct show_data_t, 1); data->self = self; data->buffer = g_strdup(buffer); g_idle_add(show_error_thread, data); } static gboolean show_info_thread(gpointer user_data) { struct show_data_t *data = user_data; // Show info message gtk_label_set_text (GTK_LABEL(data->self->label_info_bar), data->buffer); gtk_info_bar_set_message_type(data->self->info_bar, GTK_MESSAGE_INFO); gtk_info_bar_set_show_close_button(data->self->info_bar, false); gtk_widget_show (GTK_WIDGET(data->self->info_bar)); g_free(data->buffer); return G_SOURCE_REMOVE; } static void show_info(LxiGuiWindow *self, const char *buffer) { struct show_data_t *data = g_new0(struct show_data_t, 1); data->self = self; data->buffer = g_strdup(buffer); g_idle_add(show_info_thread, data); } static void hide_info_bar(LxiGuiWindow *self) { gtk_widget_hide(GTK_WIDGET(self->info_bar)); } static GtkWidget* find_child_by_name(GtkWidget* parent, const gchar* name) { GtkWidget *child; GList *children = NULL; g_assert(GTK_IS_WIDGET(parent) == true); if (g_strcmp0(gtk_widget_get_name(parent), name) == 0) return parent; for (child = gtk_widget_get_first_child(parent); child != NULL; child = gtk_widget_get_next_sibling(child)) { children = g_list_append(children, child); } while (children != NULL) { GtkWidget* widget = find_child_by_name(children->data, name); if (widget != NULL) return widget; children = children->next; } return NULL; } typedef enum { DISCOVERED, MANUAL } instrument_type_t; typedef enum { ADD, REMOVE, EDIT, } action_t; typedef struct { const char *name; const char *uuid; const char *address; int protocol; int port; GtkWidget *widget; instrument_type_t type; } instrument_t; static gboolean gui_update_search_add_instrument_thread(gpointer data) { instrument_t *device = data; g_mutex_lock(&self_global->mutex_instrument_list); if (device->type == DISCOVERED) { // Append list box to list (GtkListBoxRow automatically inserted as parent) gtk_list_box_append(self_global->list_box_instruments, device->widget); } else { // Prepend list box to list (GtkListBoxRow automatically inserted as parent) gtk_list_box_prepend(self_global->list_box_instruments, device->widget); } // Update widget reference to parent (GtkListBoxRow) device->widget = gtk_widget_get_parent(device->widget); g_mutex_unlock(&self_global->mutex_instrument_list); return G_SOURCE_REMOVE; } /* Add instrument to list */ static void list_add_instrument (LxiGuiWindow *self, const char *name, const char *uuid, const char *address, int protocol, int port, instrument_type_t type) { UNUSED(self); GtkWidget *image; GtkWidget *list_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); GtkWidget *list_text_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); GtkWidget *list_title = gtk_label_new(address); GtkWidget *list_subtitle = gtk_label_new (name); // Set properties of list box gtk_widget_set_size_request(list_box, -1, 60); // Set properties of list text box gtk_widget_set_hexpand(list_text_box, true); gtk_widget_set_hexpand_set(list_text_box, true); gtk_widget_set_margin_top(list_text_box, 8); gtk_widget_set_margin_end(list_text_box, 5); gtk_widget_set_halign(list_text_box, GTK_ALIGN_START); // Add image to list box if (type == DISCOVERED) { image = gtk_image_new_from_resource("/io/github/lxi-tools/lxi-gui/icons/lxi-instrument-discovered.png"); } else { image = gtk_image_new_from_resource("/io/github/lxi-tools/lxi-gui/icons/lxi-instrument-manual.png"); } gtk_widget_set_margin_start(image, 2); gtk_widget_set_margin_end(image, 2); gtk_image_set_pixel_size(GTK_IMAGE(image), 50); gtk_box_append(GTK_BOX(list_box), image); // Add title to list text box gtk_widget_set_name(list_title, "list-title"); gtk_widget_set_halign(list_title, GTK_ALIGN_START); gtk_box_append(GTK_BOX(list_text_box), list_title); // Add subtitle to list text box gtk_widget_set_name(list_subtitle, "list-subtitle"); gtk_widget_add_css_class(list_subtitle, "subtitle"); GtkStyleContext *context = gtk_widget_get_style_context (GTK_WIDGET (list_subtitle)); GtkCssProvider *provider = gtk_css_provider_new (); gtk_css_provider_load_from_data (provider, "label.subtitle {opacity: 1; font-size: x-small;}", -1); gtk_style_context_add_provider (context, GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_USER); gtk_widget_set_vexpand(list_subtitle, true); gtk_widget_set_vexpand_set(list_subtitle, true); gtk_widget_set_valign(list_subtitle, GTK_ALIGN_START); gtk_widget_set_halign(list_subtitle, GTK_ALIGN_START); gtk_label_set_wrap(GTK_LABEL(list_subtitle), true); gtk_label_set_natural_wrap_mode(GTK_LABEL(list_subtitle), GTK_NATURAL_WRAP_NONE); gtk_label_set_wrap_mode(GTK_LABEL(list_subtitle), PANGO_WRAP_CHAR); gtk_box_append(GTK_BOX(list_text_box), list_subtitle); // Add text box to list box gtk_box_append(GTK_BOX(list_box), list_text_box); // Add instrument to list to manage instrument data instrument_t *device = g_new0(instrument_t, 1); device->name = g_strdup(name); device->address = g_strdup(address); device->uuid = g_strdup(uuid); device->protocol = protocol; device->port = port; device->widget = list_box; device->type = type; self_global->list_instruments = g_list_append(self_global->list_instruments, device); // Add list box to instrument list (rework, add or insert depending on type) g_idle_add(gui_update_search_add_instrument_thread, device); } static void json_read_instrument(JsonReader *reader, const char **name, const char **id, const char **address, int *protocol, int *port) { json_reader_read_member (reader, "name"); *name = json_reader_get_string_value (reader); json_reader_end_member (reader); json_reader_read_member (reader, "id"); *id = json_reader_get_string_value (reader); json_reader_end_member (reader); json_reader_read_member (reader, "address"); *address = json_reader_get_string_value (reader); json_reader_end_member (reader); json_reader_read_member (reader, "protocol"); *protocol = json_reader_get_int_value (reader); json_reader_end_member (reader); json_reader_read_member (reader, "port"); *port = json_reader_get_int_value (reader); json_reader_end_member (reader); } static void json_add_instrument(JsonBuilder *builder, const char *name, const char *id, const char *address, int protocol, int port) { json_builder_begin_object(builder); json_builder_set_member_name(builder, "name"); json_builder_add_string_value(builder, name); json_builder_set_member_name(builder, "id"); json_builder_add_string_value(builder, id); json_builder_set_member_name(builder, "address"); json_builder_add_string_value(builder, address); json_builder_set_member_name(builder, "protocol"); json_builder_add_int_value(builder, protocol); json_builder_set_member_name(builder, "port"); json_builder_add_int_value(builder, port); json_builder_end_object (builder); } static void json_instrument(action_t action, const char *name, const char *uuid, const char *address, int protocol, int port) { const char *uuid_; const char *name_; const char *address_; int protocol_; int port_; // Read instrument JSON tree from gsettings gchar *added_instruments_string = g_settings_get_string(self_global->settings, "added-instruments"); // If empty if (strlen(added_instruments_string) == 0) { // Install default JSON tree representing parsable empty instrument list g_settings_set_string(self_global->settings, "added-instruments", "{\"instrument\":[]}"); g_settings_sync(); added_instruments_string = g_settings_get_string(self_global->settings, "added-instruments"); } // Setup JSON reader JsonParser *parser = json_parser_new (); json_parser_load_from_data (parser, added_instruments_string, -1, NULL); JsonReader *reader = json_reader_new (json_parser_get_root (parser)); // Setup JSON builder JsonBuilder *builder = json_builder_new(); // Begin new JSON tree json_builder_begin_object(builder); json_builder_set_member_name(builder, "instrument"); json_builder_begin_array(builder); // Traverse through existing list of instruments json_reader_read_member (reader, "instrument"); int array_size = json_reader_count_elements(reader); for (int i=0; isettings, "added-instruments", added_instruments_string_updated); g_settings_sync(); // Cleanup g_free(added_instruments_string_updated); json_node_free(root); g_object_unref(gen); g_object_unref(builder); g_free(added_instruments_string); g_object_unref(reader); g_object_unref(parser); } static void add_instrument(const char *name, const char *address, int protocol, int port, instrument_type_t type) { const char *uuid = g_uuid_string_random(); if (type == MANUAL) { // Add instrument to gsettings JSON tree json_instrument(ADD, name, uuid, address, protocol, port); } if (type == DISCOVERED) { // Make sure we don't add instrument with same IP twice (happens in mDNS // discovery because multiple services can be reported on same IP) for (GList *l = self_global->list_instruments; l != NULL; l = l->next) { instrument_t *device = (instrument_t *) l->data; if (g_str_equal(device->address, address) && (device->type == DISCOVERED)) { return; } } } // Add instrument to list widget list_add_instrument(self_global, name, uuid, address, protocol, port, type); // Manage instruments status page if (g_list_length(self_global->list_instruments) > 0) { gtk_widget_set_visible(GTK_WIDGET(self_global->status_page_instruments), false); } } static instrument_t *find_instrument(GtkWidget *widget) { for (GList *l = self_global->list_instruments; l != NULL; l = l->next) { instrument_t *device = (instrument_t *) l->data; if (device->widget == widget) { return device; } } return NULL; } static void remove_discovered_instruments(void) { g_mutex_lock(&self_global->mutex_instrument_list); // Go through instrument list and remove discovered instruments GList *l = self_global->list_instruments; while (l != NULL) { instrument_t *device = (instrument_t *) l->data; GList *next = l->next; if (device->type == DISCOVERED) { gtk_list_box_remove(self_global->list_box_instruments, device->widget); g_free((gpointer)device->name); g_free((gpointer)device->uuid); g_free((gpointer)device->address); g_free(l->data); self_global->list_instruments = g_list_delete_link (self_global->list_instruments, l); } l = next; } g_mutex_unlock(&self_global->mutex_instrument_list); } static void remove_instrument(GtkWidget *widget) { instrument_t *device; g_mutex_lock(&self_global->mutex_instrument_list); // Find intrument in instrument list by widget pointer (child) device = find_instrument(widget); if (device == NULL) { printf("No widget found!\n"); return; } // If removing currently selected device make sure to invalidate information // for currently selected instrument if (device->widget == (GtkWidget *) self_global->list_box_row_selected) { self_global->ip = NULL; self_global->id = NULL; self_global->protocol = -1; self_global->port = -1; } // If manually added device, remove device from gsettings JSON tree if (device->type == MANUAL) { json_instrument(REMOVE, NULL, device->uuid, NULL, 0, 0); } // Remove device from instrument list g_free((gpointer)device->name); g_free((gpointer)device->uuid); g_free((gpointer)device->address); g_free(device); self_global->list_instruments = g_list_remove(self_global->list_instruments, device); // Destroy instrument widget from list view gtk_list_box_remove(self_global->list_box_instruments, GTK_WIDGET(widget)); // Manage instruments status page if (g_list_length(self_global->list_instruments) <= 0) { gtk_widget_set_visible(GTK_WIDGET(self_global->status_page_instruments), true); } g_mutex_unlock(&self_global->mutex_instrument_list); } static int add_instruments_from_gsettings(void) { gchar *added_instruments_string = g_settings_get_string(self_global->settings, "added-instruments"); const char *name; const char *uuid; const char *address; int protocol; int port; // If empty if (strlen(added_instruments_string) == 0) { // Do nothing return 0; } // Setup JSON reader JsonParser *parser = json_parser_new (); json_parser_load_from_data (parser, added_instruments_string, -1, NULL); JsonReader *reader = json_reader_new (json_parser_get_root (parser)); // Traverse through existing list of instruments json_reader_read_member (reader, "instrument"); int array_size = json_reader_count_elements(reader); for (int i=0; isettings, "com-protocol"); unsigned int raw_port = g_settings_get_uint(self_global->settings, "raw-port"); g_mutex_lock(&self_global->mutex_discover); add_instrument(id, address, com_protocol, raw_port, DISCOVERED); g_mutex_unlock(&self_global->mutex_discover); } static void vxi11_broadcast(const char *address, const char *interface) { UNUSED(address); char *text = g_strdup_printf ("Broadcasting on interface %s", interface); show_info(self_global, text); g_free(text); } static void vxi11_device(const char *address, const char *id) { // Use configured defaults unsigned int com_protocol = g_settings_get_uint(self_global->settings, "com-protocol"); unsigned int raw_port = g_settings_get_uint(self_global->settings, "raw-port"); g_mutex_lock(&self_global->mutex_discover); add_instrument(id, address, com_protocol, raw_port, DISCOVERED); g_mutex_unlock(&self_global->mutex_discover); } static gboolean gui_update_script_run_worker_function_finished_thread(gpointer data) { LxiGuiWindow *self = data; // Restore search button gtk_toggle_button_set_active(self->toggle_button_script_run, false); gtk_widget_set_sensitive(GTK_WIDGET(self->toggle_button_script_run), true); return G_SOURCE_REMOVE; } static gboolean gui_update_search_finished_thread(gpointer data) { LxiGuiWindow *self = data; // Restore search button gtk_toggle_button_set_active(self->toggle_button_search, false); gtk_widget_set_sensitive(GTK_WIDGET(self->toggle_button_search), true); // Hide broadcasting info bar hide_info_bar(self); // Manage instruments status page if (g_list_length(self->list_instruments) > 0) { gtk_widget_set_visible(GTK_WIDGET(self->status_page_instruments), false); } else { gtk_widget_set_visible(GTK_WIDGET(self->status_page_instruments), true); } // Reenable search shortcut gtk_widget_action_set_enabled (GTK_WIDGET (self), "action.search", true); return G_SOURCE_REMOVE; } static gboolean gui_update_send_worker_finished_thread(gpointer data) { LxiGuiWindow *self = data; // Restore search button gtk_widget_set_sensitive(GTK_WIDGET(self->toggle_button_scpi_send), true); gtk_toggle_button_set_active(self->toggle_button_scpi_send, false); return G_SOURCE_REMOVE; } static gpointer search_worker_thread(gpointer data) { LxiGuiWindow *self = data; unsigned int timeout = g_settings_get_uint(self->settings, "timeout-discover"); bool use_mdns_discovery = g_settings_get_boolean(self->settings, "use-mdns-discovery"); // Reset selected IP and ID self->ip = NULL; self->id = NULL; // Search for LXI devices if (use_mdns_discovery) lxi_discover(&info, timeout, DISCOVER_MDNS); else lxi_discover(&info, timeout, DISCOVER_VXI11); g_idle_add(gui_update_search_finished_thread, self); return NULL; } static gboolean gui_update_search_start_thread(gpointer data) { LxiGuiWindow *self = data; // Hide instruments status page gtk_widget_set_visible(GTK_WIDGET(self->status_page_instruments), false); // Reveal flap adw_flap_set_reveal_flap(self->flap, true); // Only allow one search activity at a time gtk_widget_set_sensitive(GTK_WIDGET(self->toggle_button_search), false); // Clear instrument list remove_discovered_instruments(); // Start thread which searches for LXI instruments self->search_worker_thread = g_thread_new("search_worker", search_worker_thread, (gpointer)self); return G_SOURCE_REMOVE; } static void button_clicked_search(LxiGuiWindow *self, GtkToggleButton *button) { UNUSED(button); g_idle_add(gui_update_search_start_thread, self); } struct dispatch_data_t { GtkTextView *text_view; gchar *buffer; }; static gboolean text_view_add_buffer_thread(gpointer user_data) { struct dispatch_data_t *data = user_data; GtkTextBuffer *text_buffer = gtk_text_view_get_buffer(data->text_view); GtkTextIter iter; // Append text gtk_text_buffer_get_end_iter(text_buffer, &iter); gtk_text_buffer_insert (text_buffer, &iter, data->buffer, -1); // Scroll down gtk_text_buffer_get_end_iter(text_buffer, &iter); gtk_text_iter_backward_line(&iter); GtkTextMark *end_mark = gtk_text_buffer_create_mark(text_buffer, NULL, &iter, FALSE); gtk_text_view_scroll_mark_onscreen(data->text_view, end_mark); gtk_text_buffer_delete_mark(text_buffer, end_mark); // Cleanup g_free(data->buffer); g_free(data); return G_SOURCE_REMOVE; } static void text_view_add_buffer(GtkTextView *view, const char *buffer) { struct dispatch_data_t *data = g_new0(struct dispatch_data_t, 1); data->text_view = view; data->buffer = g_strdup(buffer); g_idle_add(text_view_add_buffer_thread, data); } static gboolean text_view_add_markup_buffer_thread(gpointer user_data) { struct dispatch_data_t *data = user_data; GtkTextBuffer *text_buffer = gtk_text_view_get_buffer(data->text_view); GtkTextIter iter; // Append text gtk_text_buffer_get_end_iter(text_buffer, &iter); gtk_text_buffer_insert_markup(text_buffer, &iter, data->buffer, -1); // Scroll down gtk_text_buffer_get_end_iter(text_buffer, &iter); GtkTextMark *end_mark = gtk_text_buffer_create_mark(text_buffer, NULL, &iter, FALSE); gtk_text_view_scroll_mark_onscreen(data->text_view, end_mark); gtk_text_buffer_delete_mark(text_buffer, end_mark); // Cleanup g_free(data->buffer); g_free(data); return G_SOURCE_REMOVE; } static void text_view_add_buffer_in_dimgray(GtkTextView *view, const char *buffer) { struct dispatch_data_t *data = g_new0(struct dispatch_data_t, 1); data->text_view = view; data->buffer = g_strdup_printf("%s", buffer); g_idle_add(text_view_add_markup_buffer_thread, data); } static gboolean text_view_clear_buffer_thread(gpointer data) { GtkTextView *view = data; GtkTextIter start, end; GtkTextBuffer *text_buffer = gtk_text_view_get_buffer(view); gtk_text_buffer_get_bounds(text_buffer, &start, &end); gtk_text_buffer_delete(text_buffer, &start, &end); return G_SOURCE_REMOVE; } static void text_view_clear_buffer(GtkTextView *view) { g_idle_add(text_view_clear_buffer_thread, view); } static void save_text_buffer_to_file(GFile *file, GtkTextBuffer *text_buffer) { GtkTextIter start, end; gboolean status = true; GError *error = NULL; char *buffer; // Get buffer of script text view gtk_text_buffer_get_bounds(text_buffer, &start, &end); buffer = gtk_text_buffer_get_text(text_buffer, &start, &end, true); // Write output stream to file status = g_file_replace_contents (file, buffer, strlen(buffer), NULL, false, 0, NULL, NULL, &error); if (status != true) { g_print("Could not write output stream: %s\n", error->message); g_error_free(error); return; } // TODO: Report errors to GUI } static void on_scpi_save_as_response(GtkDialog *dialog, int response, gpointer user_data) { LxiGuiWindow *self = user_data; if (response == GTK_RESPONSE_ACCEPT) { GtkFileChooser *chooser = GTK_FILE_CHOOSER (dialog); GFile *file = gtk_file_chooser_get_file (chooser); GtkTextBuffer *text_buffer = gtk_text_view_get_buffer(self->text_view_scpi); save_text_buffer_to_file(file, text_buffer); } gtk_window_destroy (GTK_WINDOW (dialog)); } static void scpi_save_as(LxiGuiWindow *self) { GtkWidget *dialog; // Show file save dialog dialog = gtk_file_chooser_dialog_new ("Select file", GTK_WINDOW (self), GTK_FILE_CHOOSER_ACTION_SAVE, "_Cancel", GTK_RESPONSE_CANCEL, "_Save", GTK_RESPONSE_ACCEPT, NULL); GtkFileChooser *chooser = GTK_FILE_CHOOSER(dialog); gtk_file_chooser_set_current_name (chooser, "Untitled.txt"); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); gtk_widget_show (dialog); g_signal_connect (dialog, "response", G_CALLBACK (on_scpi_save_as_response), (gpointer *) self); } static void scpi_action_cb(GtkWidget *widget, const char *action_name, GVariant *parameter) { LxiGuiWindow *self = LXI_GUI_WINDOW (widget); UNUSED(parameter); if (g_str_equal (action_name, "scpi_clear_all")) { text_view_clear_buffer(self->text_view_scpi); } if (g_str_equal (action_name, "scpi_save_as")) { scpi_save_as(self); } } static void scpi_print(LxiGuiWindow *self, const char *text, bool sent, const char *ip, const char *timestamp) { bool show_ip = g_settings_get_boolean(self->settings, "scpi-show-message-ip"); bool show_type = g_settings_get_boolean(self->settings, "scpi-show-message-type"); bool show_timestamp = g_settings_get_boolean(self->settings, "scpi-show-message-timestamp"); GString *string = g_string_new(NULL); // Build text string if ((show_timestamp) || (show_ip) || (show_type)) { g_string_append(string, "["); } if (show_timestamp) { // Add timestamp g_string_append(string, timestamp); } if (show_ip) { // Add IP if (show_timestamp) { g_string_append(string, " "); } g_string_append(string, ip); } if (show_type) { // Add type const char *type; if ((show_timestamp) || (show_ip)) { g_string_append(string, " "); } if (sent) { type = "REQ"; } else { type = "RSP"; } g_string_append(string, type); } if ((show_timestamp) || (show_ip) || (show_type)) { g_string_append(string, "] "); } g_string_append(string, text); if (sent) { text_view_add_buffer_in_dimgray(self->text_view_scpi, string->str); text_view_add_buffer(self->text_view_scpi, "\n"); } else { text_view_add_buffer(self->text_view_scpi, string->str); } // Cleanup g_string_free(string, true); } static gpointer send_worker_thread(gpointer data) { LxiGuiWindow *self = data; int device = 0; const char *input_buffer; GString *tx_buffer; char rx_buffer[65536]; int rx_bytes; unsigned int timeout = g_settings_get_uint(self->settings, "timeout-scpi"); bool show_sent_scpi = g_settings_get_boolean(self->settings, "show-sent-scpi"); if (self->ip == NULL) { show_error(self, "No instrument selected"); goto error_no_instrument; } // Prepare buffer to send GtkEntryBuffer *entry_buffer = gtk_entry_get_buffer(GTK_ENTRY(self->entry_scpi)); input_buffer = gtk_entry_buffer_get_text(entry_buffer); if (strlen(input_buffer) == 0) goto error_no_input; tx_buffer = g_string_new_len(input_buffer, strlen(input_buffer)); strip_trailing_space(tx_buffer->str); if (self->protocol == VXI11) { device = lxi_connect(self->ip, 0, NULL, timeout, VXI11); } if (self->protocol == RAW) { tx_buffer = g_string_append(tx_buffer, "\n"); device = lxi_connect(self->ip, self->port, NULL, timeout, RAW); } if (device == LXI_ERROR) { show_error(self, "Error connecting"); goto error_connect; } if (lxi_send(device, tx_buffer->str, tx_buffer->len, timeout) == LXI_ERROR) { show_error(self, "Error sending"); goto error_send; } if (show_sent_scpi) { GDateTime* date_time = g_date_time_new_now_local(); char *timestamp = g_strdup_printf("%02d:%02d:%02d:%03d", g_date_time_get_hour(date_time), g_date_time_get_minute(date_time), g_date_time_get_second(date_time), g_date_time_get_microsecond(date_time)/1000); g_date_time_unref(date_time); // Print sent command to output view if (self->protocol == RAW) { // Remove newline g_string_erase(tx_buffer, tx_buffer->len - 1, 1); } scpi_print(self, tx_buffer->str, true, self->ip, timestamp); g_free(timestamp); } if (question(tx_buffer->str)) { rx_bytes = lxi_receive(device, rx_buffer, sizeof(rx_buffer), timeout); if (rx_bytes == LXI_ERROR) { show_error(self, "No response received"); goto error_receive; } // Terminate received string/data rx_buffer[rx_bytes] = 0; GDateTime* date_time = g_date_time_new_now_local(); char *timestamp = g_strdup_printf("%02d:%02d:%02d:%03d", g_date_time_get_hour(date_time), g_date_time_get_minute(date_time), g_date_time_get_second(date_time), g_date_time_get_microsecond(date_time)/1000); g_date_time_unref(date_time); // Print received response to text view scpi_print(self, rx_buffer, false, self->ip, timestamp); g_free(timestamp); } // Clear text in text input entry gtk_entry_buffer_delete_text(entry_buffer, 0, -1); error_send: error_receive: lxi_disconnect(device); error_connect: g_string_free(tx_buffer, true); error_no_instrument: error_no_input: // Restore send button state // Defer! g_idle_add(gui_update_send_worker_finished_thread, self); return NULL; } static void button_clicked_scpi_clear(LxiGuiWindow *self, GtkButton *button) { UNUSED(button); // Clear SCPI input entry GtkEntryBuffer *entry_buffer = gtk_entry_get_buffer(self->entry_scpi); gtk_entry_buffer_delete_text(entry_buffer, 0, -1); gtk_entry_set_buffer(self->entry_scpi, entry_buffer); } static void button_clicked_scpi_send(LxiGuiWindow *self, GtkButton *button) { UNUSED(button); // Update send button state gtk_widget_set_sensitive(GTK_WIDGET(self->toggle_button_scpi_send), false); // Start thread which sends the SCPI message self->send_worker_thread = g_thread_new("send_worker", send_worker_thread, (gpointer)self); } static void entry_scpi_enter_pressed(LxiGuiWindow *self, GtkEntry *entry) { UNUSED(entry); // Start thread which sends the SCPI message self->send_worker_thread = g_thread_new("send_worker", send_worker_thread, (gpointer)self); // Update send button state gtk_widget_set_sensitive(GTK_WIDGET(self->toggle_button_scpi_send), false); gtk_toggle_button_set_active(self->toggle_button_scpi_send, true); } static void button_clicked_scpi(LxiGuiWindow *self, GtkButton *button) { // Insert button label at entry cursor position const char *button_label = gtk_button_get_label(button); int cursor_position = gtk_editable_get_position(GTK_EDITABLE(self->entry_scpi)); GtkEntryBuffer *entry_buffer = gtk_entry_get_buffer(self->entry_scpi); gtk_entry_buffer_insert_text(entry_buffer, cursor_position, button_label, strlen(button_label)); gtk_entry_set_buffer(self->entry_scpi, entry_buffer); cursor_position = cursor_position + strlen(button_label); gtk_editable_set_position(GTK_EDITABLE(self->entry_scpi), cursor_position); } static bool grab_screenshot(LxiGuiWindow *self) { char *plugin_name = (char *) ""; char *filename = (char *) ""; unsigned int timeout = g_settings_get_uint(self->settings, "timeout-screenshot"); int status; // Check for instrument if (self->ip == NULL) { show_error(self, "No instrument selected"); return 1; } // Allocate 20 MB for image data self->image_buffer = g_malloc(0x100000*20); if (self->image_buffer == NULL) { show_error(self, "Failure allocating memory for image data"); return 1; } // Capture screenshot status = screenshot((char *)self->ip, plugin_name, filename, timeout, false, self->image_buffer, &(self->image_size), self->image_format, self->image_filename); if (status != 0) { show_error(self, "Failed to grab screenshot"); g_free(self->image_buffer); return 1; } return 0; } static gboolean gui_update_grab_screenshot_finished_thread(gpointer user_data) { LxiGuiWindow *self = user_data; GdkPixbufLoader *loader; if (self->screenshot_ready) { // Show screenshot //loader = gdk_pixbuf_loader_new (); loader = gdk_pixbuf_loader_new_with_type(self->image_format, NULL); gdk_pixbuf_loader_write(loader, (const guchar *) self->image_buffer, (gsize)self->image_size, NULL); self->pixbuf_screenshot = gdk_pixbuf_loader_get_pixbuf (loader); if (self->pixbuf_screenshot == NULL) { show_error(self, "Failure handling image format"); self->screenshot_loaded = false; } else { self->screenshot_size = gdk_pixbuf_get_width(self->pixbuf_screenshot); self->screenshot_loaded = true; gtk_widget_set_valign(GTK_WIDGET(self->picture_screenshot), GTK_ALIGN_FILL); gtk_widget_set_halign(GTK_WIDGET(self->picture_screenshot), GTK_ALIGN_FILL); gtk_picture_set_pixbuf(self->picture_screenshot, self->pixbuf_screenshot); gdk_pixbuf_loader_close(loader, NULL); g_object_unref(loader); // Make screenshot picture zoomable //gtk_widget_set_sensitive(GTK_WIDGET(self->viewport_screenshot), true); } g_free(self->image_buffer); } // Restore screenshot buttons gtk_toggle_button_set_active(self->toggle_button_screenshot_grab, false); gtk_widget_set_sensitive(GTK_WIDGET(self->toggle_button_screenshot_grab), true); // Activate screenshot "Save" button if picture was successfully loaded if (self->screenshot_loaded) gtk_widget_set_sensitive(GTK_WIDGET(self->button_screenshot_save), true); return G_SOURCE_REMOVE; } static gpointer screenshot_grab_worker_thread(gpointer data) { LxiGuiWindow *self = data; if (grab_screenshot(self) == 0) { self->screenshot_ready = true; } else { self->screenshot_ready = false; } g_idle_add(gui_update_grab_screenshot_finished_thread, self); return NULL; } static void button_clicked_screenshot_grab(LxiGuiWindow *self, GtkButton *button) { UNUSED(button); if (self->ip == NULL) { show_error(self, "No instrument selected"); gtk_toggle_button_set_active(self->toggle_button_screenshot_grab, false); return; } // Disable grab button while grabbing the screenshot gtk_widget_set_sensitive(GTK_WIDGET(self->toggle_button_screenshot_grab), false); // Start worker thread that will perform the grab screenshot work self->screenshot_grab_worker_thread = g_thread_new("screenshot_grab_worker", screenshot_grab_worker_thread, (gpointer) self); } static void on_screenshot_file_save_response(GtkDialog *dialog, int response) { GError *error = NULL; gboolean status = true; if (response == GTK_RESPONSE_ACCEPT) { GtkFileChooser *chooser = GTK_FILE_CHOOSER (dialog); g_autoptr(GFile) file = gtk_file_chooser_get_file (chooser); status = gdk_pixbuf_save(self_global->pixbuf_screenshot, g_file_get_path(file), "png", &error, NULL); if (status == false) { g_error ("Error: %s\n", error->message); } } gtk_window_destroy (GTK_WINDOW (dialog)); } static void button_clicked_screenshot_save (LxiGuiWindow *self, GtkButton *button) { UNUSED(button); GtkWidget *dialog; GtkFileChooser *chooser; // Show file save as dialog dialog = gtk_file_chooser_dialog_new ("Select file", GTK_WINDOW (self), GTK_FILE_CHOOSER_ACTION_SAVE, "_Cancel", GTK_RESPONSE_CANCEL, "_Save", GTK_RESPONSE_ACCEPT, NULL); chooser = GTK_FILE_CHOOSER(dialog); gtk_file_chooser_set_current_name (chooser, "Untitled screenshot.png"); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); gtk_widget_show (dialog); g_signal_connect (dialog, "response", G_CALLBACK (on_screenshot_file_save_response), NULL); } static gboolean gui_update_progress_bar_fraction_thread(gpointer user_data) { LxiGuiWindow *self = user_data; static int count; gtk_progress_bar_set_fraction(self->progress_bar_benchmark, self->progress_bar_fraction); // Animate the runner if (count++ % 2) { gtk_image_set_pixel_size(self->image_benchmark, 155); gtk_widget_set_margin_start(GTK_WIDGET(self->image_benchmark), 10); } else { gtk_image_set_pixel_size(self->image_benchmark, 160); gtk_widget_set_margin_start(GTK_WIDGET(self->image_benchmark), 0); } return G_SOURCE_REMOVE; } static void benchmark_progress_cb(unsigned int count) { double fraction_count; double total_count = self_global->benchmark_requests_count; // Update progress for every 5% fraction reached fraction_count = total_count / 20; if ((++count % (unsigned int) fraction_count) == 0) { self_global->progress_bar_fraction = count / fraction_count / 20; g_idle_add(gui_update_progress_bar_fraction_thread, self_global); } } static gboolean gui_update_benchmark_finished_thread(gpointer user_data) { LxiGuiWindow *self = user_data; gtk_label_set_text(self->label_benchmark_result, self->benchmark_result_text); g_free(self->benchmark_result_text); gtk_toggle_button_set_active(self->toggle_button_benchmark_start, false); gtk_widget_set_sensitive(GTK_WIDGET(self->toggle_button_benchmark_start), true); return G_SOURCE_REMOVE; } static gpointer benchmark_worker_function(gpointer data) { double result; LxiGuiWindow *self = data; int status = 0; if (self->protocol == VXI11) { status = benchmark(self->ip, 0, 1000, VXI11, self->benchmark_requests_count, false, &result, benchmark_progress_cb); } if (self->protocol == RAW) { status = benchmark(self->ip, self->port, 1000, RAW, self->benchmark_requests_count, false, &result, benchmark_progress_cb); } if (status != LXI_OK) { show_error(self, "Error benchmarking instrument"); self->benchmark_result_text = NULL; } // Show benchmark result self->benchmark_result_text = g_strdup_printf("%.1f requests/s", result); g_idle_add(gui_update_benchmark_finished_thread, self); return NULL; } static gboolean gui_update_progress_bar_reset_thread(gpointer user_data) { LxiGuiWindow *self = user_data; // Reset gtk_progress_bar_set_fraction(self->progress_bar_benchmark, 0); gtk_label_set_text(self->label_benchmark_result, ""); return G_SOURCE_REMOVE; } static void button_clicked_benchmark_start(LxiGuiWindow *self, GtkToggleButton *button) { UNUSED(button); // Reset g_idle_add(gui_update_progress_bar_reset_thread, self); self->benchmark_requests_count = gtk_spin_button_get_value(self->spin_button_benchmark_requests); if (self->ip == NULL) { show_error(self, "No instrument selected"); gtk_toggle_button_set_active(self->toggle_button_benchmark_start, true); return; } gtk_widget_set_sensitive(GTK_WIDGET(button), false); self->benchmark_worker_thread = g_thread_new("benchmark_worker", benchmark_worker_function, (gpointer) self); } typedef struct { AdwEntryRow *entry_row_name; AdwEntryRow *entry_row_address; GtkComboBoxText *combo_box_text_com_protocol; GtkSpinButton *spin_button_raw_port; GtkButton *button_save; AdwActionRow *action_row_raw_port; action_t action; instrument_t *device; } ResponseData; static void on_dialog_response(GtkDialog *dialog, int response, gpointer user_data) { ResponseData *data = user_data; const char *name; const char *address; const char *protocol_string; int protocol; int port; instrument_t *device = data->device; GtkWidget *child; if (response == GTK_RESPONSE_OK) { // Save pressed name = gtk_editable_get_text(GTK_EDITABLE(data->entry_row_name)); address = gtk_editable_get_text(GTK_EDITABLE(data->entry_row_address)); protocol_string = gtk_combo_box_text_get_active_text(data->combo_box_text_com_protocol); port = gtk_spin_button_get_value_as_int(data->spin_button_raw_port); // Manage protocol value if (g_str_equal(protocol_string, "VXI11/TCP")) { protocol = VXI11; } else { protocol = RAW; } if (data->action == ADD) { add_instrument(name, address, protocol, port, MANUAL); } else { // EDIT // Update instrument in gsettings JSON tree if (device->type == MANUAL) { json_instrument(EDIT, name, data->device->uuid, address, protocol, port); } // Update device runtime settings g_free((gpointer)device->name); g_free((gpointer)device->address); device->name = g_strdup(name); device->address = g_strdup(address); device->protocol = protocol; device->port = port; GtkWidget *row = device->widget; // Update list widget title and subtitle (id/name and ip) if (row != NULL) { child = find_child_by_name(GTK_WIDGET(row), "list-title"); if (child != NULL) { // Update IP gtk_label_set_text(GTK_LABEL(child), address); } child = find_child_by_name(GTK_WIDGET(row), "list-subtitle"); if (child != NULL) { // Update ID gtk_label_set_text(GTK_LABEL(child), name); } } // If editing selected instrument make sure to update currently // selected instrument information if (row == (GtkWidget *) self_global->list_box_row_selected) { self_global->ip = device->address; self_global->id = device->name; self_global->protocol = device->protocol; self_global->port = device->port; } } } gtk_window_destroy (GTK_WINDOW (dialog)); g_free(data); } static void on_entry_row_name_or_address_changed(GtkEditable *self, gpointer user_data) { UNUSED(self); const char *name, *address; ResponseData *data = user_data; bool address_valid = false; name = gtk_editable_get_text(GTK_EDITABLE(data->entry_row_name)); address = gtk_editable_get_text(GTK_EDITABLE(data->entry_row_address)); // Manage address field if (strlen(address) > 0) { if (g_hostname_is_ip_address(address)) { gtk_widget_remove_css_class(GTK_WIDGET(data->entry_row_address), "error"); gtk_widget_set_tooltip_text(GTK_WIDGET(data->entry_row_address), ""); address_valid = true; } else { gtk_widget_add_css_class(GTK_WIDGET(data->entry_row_address), "error"); gtk_widget_set_tooltip_text(GTK_WIDGET(data->entry_row_address), "Invalid address format"); address_valid = false; } } else { gtk_widget_remove_css_class(GTK_WIDGET(data->entry_row_address), "error"); gtk_widget_set_tooltip_text(GTK_WIDGET(data->entry_row_address), ""); address_valid = false; } // Manage port combo box if (strcmp(gtk_combo_box_text_get_active_text(data->combo_box_text_com_protocol), "VXI11/TCP") == 0) { gtk_widget_set_sensitive(GTK_WIDGET(data->action_row_raw_port), false); } else { gtk_widget_set_sensitive(GTK_WIDGET(data->action_row_raw_port), true); } // Manage save button if ((strlen(name) > 0) && (address_valid)) { gtk_widget_set_sensitive(GTK_WIDGET(data->button_save), true); } else { gtk_widget_set_sensitive(GTK_WIDGET(data->button_save), false); } } static void create_instrument_dialog(LxiGuiWindow *self, action_t action) { ResponseData *data; instrument_t *device = NULL; if (action == EDIT) { // Find intrument in instrument list by widget pointer (child) device = find_instrument(GTK_WIDGET(self->list_box_row_pressed)); if (device == NULL) { printf("No widget found!\n"); return; } } /* Construct a GtkBuilder instance from UI description */ GtkWidget *toplevel = GTK_WIDGET(self); GtkBuilder *gtk_builder = gtk_builder_new (); gtk_builder_expose_object (gtk_builder, "toplevel", G_OBJECT (toplevel)); gtk_builder_add_from_resource(gtk_builder, "/io/github/lxi-tools/lxi-gui/lxi_gui-instrument_dialog.ui", NULL); // Get UI objects GtkDialog *dialog = GTK_DIALOG(gtk_builder_get_object(gtk_builder, "add_instrument_dialog")); AdwEntryRow *entry_row_name = ADW_ENTRY_ROW(gtk_builder_get_object(gtk_builder, "entry_row_name")); AdwEntryRow *entry_row_address = ADW_ENTRY_ROW(gtk_builder_get_object(gtk_builder, "entry_row_address")); GtkComboBoxText *combo_box_text_com_protocol = GTK_COMBO_BOX_TEXT(gtk_builder_get_object (gtk_builder, "combo_box_text_com_protocol")); GtkSpinButton *spin_button_raw_port = GTK_SPIN_BUTTON(gtk_builder_get_object(gtk_builder, "spin_button_raw_port")); AdwActionRow *action_row_raw_port = ADW_ACTION_ROW(gtk_builder_get_object(gtk_builder, "action_row_raw_port")); GtkButton *button_save = GTK_BUTTON(gtk_builder_get_object(gtk_builder, "button_save")); // Set defaults if (action == ADD) { gtk_window_set_title(GTK_WINDOW(dialog), "Add Instrument"); gtk_widget_set_sensitive(GTK_WIDGET(button_save), false); gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box_text_com_protocol), 0); gtk_widget_set_sensitive(GTK_WIDGET(action_row_raw_port), false); } else { // EDIT gtk_window_set_title(GTK_WINDOW(dialog), "Edit Instrument"); if (device->protocol == VXI11) { gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box_text_com_protocol), 0); gtk_widget_set_sensitive(GTK_WIDGET(action_row_raw_port), false); } else { gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box_text_com_protocol), 1); gtk_widget_set_sensitive(GTK_WIDGET(action_row_raw_port), true); } // Restore old values gtk_editable_set_text(GTK_EDITABLE(entry_row_name), device->name); gtk_editable_set_text(GTK_EDITABLE(entry_row_address), device->address); gtk_spin_button_set_value(spin_button_raw_port, device->port); } data = g_new (ResponseData, 1); data->entry_row_name = entry_row_name; data->entry_row_address = entry_row_address; data->combo_box_text_com_protocol = combo_box_text_com_protocol; data->spin_button_raw_port = spin_button_raw_port; data->button_save = button_save; data->action_row_raw_port = action_row_raw_port; data->action = action; data->device = device; // Connect signals g_signal_connect(dialog, "response", G_CALLBACK(on_dialog_response), data); g_signal_connect(entry_row_name, "changed", G_CALLBACK(on_entry_row_name_or_address_changed), data); g_signal_connect(entry_row_address, "changed", G_CALLBACK(on_entry_row_name_or_address_changed), data); g_signal_connect(combo_box_text_com_protocol, "changed", G_CALLBACK(on_entry_row_name_or_address_changed), data); // Show window gtk_widget_show(GTK_WIDGET(dialog)); // Cleanup g_object_unref(gtk_builder); } static void button_clicked_add_instrument(LxiGuiWindow *self, GtkButton *button) { UNUSED(button); create_instrument_dialog(self, ADD); } static void edit_instrument(LxiGuiWindow *self) { create_instrument_dialog(self, EDIT); } static void pressed_cb (GtkGestureClick *gesture, guint n_press, double x, double y, LxiGuiWindow *self) { GtkListBoxRow *row; GtkAdjustment* adjustment; double y_adjustment, y_adjusted; UNUSED(gesture); UNUSED(n_press); // Adjust y value to account for scrolling offset so we can pick the right row adjustment = gtk_list_box_get_adjustment(self->list_box_instruments); y_adjustment = gtk_adjustment_get_value(adjustment); y_adjusted = y + y_adjustment; row = gtk_list_box_get_row_at_y(self->list_box_instruments, y_adjusted); self->list_box_row_pressed = row; if (row != NULL) { instrument_t *device; device = find_instrument(GTK_WIDGET(row)); if (device == NULL) { // No instrument found self->id = NULL; self->ip = NULL; self->protocol = -1; self->port = -1; return; } // If left click if (gtk_gesture_single_get_current_button(GTK_GESTURE_SINGLE(gesture)) == GDK_BUTTON_PRIMARY) { self->list_box_row_selected = row; // Update information of currently selected instrument self->ip = device->address; self->id = device->name; self->protocol = device->protocol; self->port = device->port; } // If right click if (gtk_gesture_single_get_current_button(GTK_GESTURE_SINGLE(gesture)) == GDK_BUTTON_SECONDARY) { /* Place our popup menu at the point where * the click happened, before popping it up. */ gtk_popover_set_pointing_to (GTK_POPOVER (self->list_widget_popover_menu), &(const GdkRectangle){ x, y, 1, 1 }); gtk_popover_popup (GTK_POPOVER (self->list_widget_popover_menu)); } } } static void action_cb (GtkWidget *widget, const char *action_name, GVariant *parameter) { LxiGuiWindow *self = LXI_GUI_WINDOW (widget); UNUSED(parameter); instrument_t *device = find_instrument(GTK_WIDGET(self->list_box_row_pressed)); if (g_str_equal (action_name, "action.copy_ip")) { gdk_clipboard_set (self->clipboard, G_TYPE_STRING, device->address); } if (g_str_equal (action_name, "action.copy_id")) { gdk_clipboard_set (self->clipboard, G_TYPE_STRING, device->name); } if (g_str_equal (action_name, "action.remove")) { // Remove action remove_instrument(GTK_WIDGET(self->list_box_row_pressed)); } if (g_str_equal (action_name, "action.edit")) { // Edit action edit_instrument(self); } if (g_str_equal (action_name, "action.open_browser") && self->ip != NULL) { #ifndef __APPLE__ gchar *uri = g_strconcat("http://", self->ip, NULL); gtk_show_uri(GTK_WINDOW(self), uri, GDK_CURRENT_TIME); #else gchar *uri = g_strconcat("open http://", self->ip, NULL); system(uri); #endif g_free(uri); } } static void on_script_file_open_response (GtkDialog *dialog, int response, gpointer user_data) { LxiGuiWindow *self = user_data; if (response == GTK_RESPONSE_ACCEPT) { // Read file contents into script text view GFileInputStream *file_input_stream; GInputStream *input_stream; GtkSourceBuffer *source_buffer_script; gboolean status = true; gsize bytes_read = 0, bytes_written = 0; GError *error = NULL; GFile *file = gtk_file_chooser_get_file(GTK_FILE_CHOOSER(dialog)); file_input_stream = g_file_read(file, NULL, &error); if (file_input_stream == NULL) { g_print ("Could not open file: %s\n", error->message); g_error_free(error); g_object_unref(file_input_stream); return; } GFileInfo *info = g_file_query_info(file, "*", G_FILE_QUERY_INFO_NONE, NULL, NULL); goffset len_buffer = g_file_info_get_size(info); gchar *buffer = g_malloc(len_buffer); if (buffer == NULL) { g_print("Failure allocating memory for reading file"); g_object_unref(file_input_stream); return; } input_stream = g_buffered_input_stream_new (G_INPUT_STREAM (file_input_stream)); status = g_input_stream_read_all(input_stream, buffer, len_buffer, &bytes_read, NULL, &error); if (status != TRUE) { g_print ("Could not read file input stream: %s\n", error->message); g_error_free(error); g_object_unref(file_input_stream); g_free(buffer); g_free(input_stream); return; } // Convert input file buffer to UTF-8 gchar *utf8_buffer = g_convert (buffer, bytes_read, "UTF-8", "ISO-8859-1", NULL, &bytes_written, &error); if (error != NULL) { g_print ("Couldn't convert to UTF-8\n"); g_error_free (error); g_object_unref(file_input_stream); g_free(buffer); g_free(input_stream); return; } // Get source buffer of script source view source_buffer_script = GTK_SOURCE_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(self->source_view_script))); // Clear existing text buffer GtkTextIter start, end; gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(source_buffer_script), &start, &end); gtk_text_buffer_delete(GTK_TEXT_BUFFER(source_buffer_script), &start, &end); // Read data into text buffer GtkTextIter iter; gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(source_buffer_script), &iter); gtk_text_buffer_insert(GTK_TEXT_BUFFER(source_buffer_script), &iter, utf8_buffer, bytes_written); // Free old script file if any if (self->script_file != NULL) g_object_unref(self->script_file); // Update script file reference self->script_file = file; // Print status if (self->script_file != NULL) { char *filename = g_file_get_path(self->script_file); char *basename = g_path_get_basename(filename); g_free(filename); char *text = g_strdup_printf ("Opening %s\n", basename); text_view_add_buffer(self->text_view_script_status, text); g_free(text); } // Cleanup g_free(buffer); g_object_unref(file_input_stream); g_object_unref(input_stream); } // TODO: Report errors to GUI gtk_window_destroy (GTK_WINDOW (dialog)); } static void button_clicked_script_new(LxiGuiWindow *self, GtkButton *button) { UNUSED(button); GtkSourceBuffer *source_buffer_script; // Clear existing script file self->script_file = NULL; // Get source buffer of script source view source_buffer_script = GTK_SOURCE_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(self->source_view_script))); // Clear existing text buffer GtkTextIter start, end; gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(source_buffer_script), &start, &end); gtk_text_buffer_delete(GTK_TEXT_BUFFER(source_buffer_script), &start, &end); // Print status text_view_add_buffer(self->text_view_script_status, "New script\n"); } static void button_clicked_script_open(LxiGuiWindow *self, GtkButton *button) { UNUSED(button); GtkWidget *dialog; gpointer data = self; // Show file open dialog dialog = gtk_file_chooser_dialog_new ("Select file", GTK_WINDOW (self), GTK_FILE_CHOOSER_ACTION_OPEN, "_Cancel", GTK_RESPONSE_CANCEL, "_Open", GTK_RESPONSE_ACCEPT, NULL); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); gtk_widget_show (dialog); g_signal_connect (dialog, "response", G_CALLBACK (on_script_file_open_response), data); } static void on_script_file_save_response(GtkDialog *dialog, int response, gpointer user_data) { LxiGuiWindow *self = user_data; if (response == GTK_RESPONSE_ACCEPT) { GtkFileChooser *chooser = GTK_FILE_CHOOSER (dialog); GFile *file = gtk_file_chooser_get_file (chooser); GtkTextBuffer *text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(self->source_view_script)); save_text_buffer_to_file(file, text_buffer); // Free old script file if any if (self->script_file != NULL) g_object_unref(self->script_file); // Update script file reference self->script_file = file; // Print status if (self->script_file != NULL) { char *filename = g_file_get_path(self->script_file); char *basename = g_path_get_basename(filename); g_free(filename); char *text = g_strdup_printf ("Saving %s\n", basename); text_view_add_buffer(self->text_view_script_status, text); g_free(text); } } gtk_window_destroy (GTK_WINDOW (dialog)); } static void button_clicked_script_save(LxiGuiWindow *self, GtkButton *button) { UNUSED(button); if (self->script_file != NULL) { // Save file GtkTextBuffer *text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(self->source_view_script)); save_text_buffer_to_file(self->script_file, text_buffer); // Print status char *filename = g_file_get_path(self->script_file); char *basename = g_path_get_basename(filename); g_free(filename); char *text = g_strdup_printf ("Saving %s\n", basename); text_view_add_buffer(self->text_view_script_status, text); g_free(text); } else { GtkWidget *dialog; gpointer data = self; // Show file save dialog dialog = gtk_file_chooser_dialog_new ("Select file", GTK_WINDOW (self), GTK_FILE_CHOOSER_ACTION_SAVE, "_Cancel", GTK_RESPONSE_CANCEL, "_Save", GTK_RESPONSE_ACCEPT, NULL); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); gtk_widget_show (dialog); g_signal_connect (dialog, "response", G_CALLBACK (on_script_file_save_response), data); } } static void button_clicked_script_save_as(LxiGuiWindow *self, GtkButton *button) { UNUSED(button); GtkWidget *dialog; gpointer data = self; // Show file save dialog dialog = gtk_file_chooser_dialog_new ("Select file", GTK_WINDOW (self), GTK_FILE_CHOOSER_ACTION_SAVE, "_Cancel", GTK_RESPONSE_CANCEL, "_Save", GTK_RESPONSE_ACCEPT, NULL); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); gtk_widget_show (dialog); g_signal_connect (dialog, "response", G_CALLBACK (on_script_file_save_response), data); } void initialize_script_engine(LxiGuiWindow *self) { // Print lua engine status char *text = g_strdup_printf ("%s engine ready\n", LUA_VERSION); text_view_add_buffer(self->text_view_script_status, text); text_view_add_buffer(self->text_view_script_status, "Loaded lxi-tools extensions\n"); g_free(text); self->lua_stop_requested = false; } static void lua_print_error(LxiGuiWindow *self, const char *string) { text_view_add_buffer(self->text_view_script_status, string); text_view_add_buffer(self->text_view_script_status, "\n"); } static void lua_print_string(const char *string) { text_view_add_buffer(self_global->text_view_script_status, string); text_view_add_buffer(self_global->text_view_script_status, "\n"); } static void chart_destroyed_cb (GtkWidget *widget, gpointer user_data) { UNUSED(user_data); int handle; // Mark widget deallocated for (handle=0; handlewidget), g_file_get_path(file)); if (status == false) { g_error ("Error: %s\n", error->message); } } gtk_window_destroy (GTK_WINDOW (dialog)); } static void chart_save_image(GSimpleAction *action, GVariant *state, gpointer user_data) { UNUSED(action); UNUSED(state); GtkWidget *dialog; GtkFileChooser *chooser; struct chart_t *chart = user_data; // Show file save as dialog dialog = gtk_file_chooser_dialog_new ("Select file", GTK_WINDOW (chart->window), GTK_FILE_CHOOSER_ACTION_SAVE, "_Cancel", GTK_RESPONSE_CANCEL, "_Save", GTK_RESPONSE_ACCEPT, NULL); chooser = GTK_FILE_CHOOSER(dialog); gtk_file_chooser_set_current_name (chooser, "Untitled screenshot.png"); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); gtk_widget_show (dialog); g_signal_connect (dialog, "response", G_CALLBACK (on_chart_save_image_response), chart); } static void on_chart_save_csv_response(GtkDialog *dialog, int response, struct chart_t *chart) { GError *error = NULL; gboolean status = true; if (response == GTK_RESPONSE_ACCEPT) { GtkFileChooser *chooser = GTK_FILE_CHOOSER (dialog); g_autoptr(GFile) file = gtk_file_chooser_get_file (chooser); status = gtk_chart_save_csv(GTK_CHART(chart->widget), g_file_get_path(file)); if (status == false) { g_error ("Error: %s\n", error->message); } } gtk_window_destroy (GTK_WINDOW (dialog)); } static void chart_save_csv(GSimpleAction *action, GVariant *state, gpointer user_data) { UNUSED(action); UNUSED(state); GtkWidget *dialog; GtkFileChooser *chooser; struct chart_t *chart = user_data; // Show file save as dialog dialog = gtk_file_chooser_dialog_new ("Select file", GTK_WINDOW (chart->window), GTK_FILE_CHOOSER_ACTION_SAVE, "_Cancel", GTK_RESPONSE_CANCEL, "_Save", GTK_RESPONSE_ACCEPT, NULL); chooser = GTK_FILE_CHOOSER(dialog); gtk_file_chooser_set_current_name (chooser, "Untitled.csv"); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); gtk_widget_show (dialog); g_signal_connect (dialog, "response", G_CALLBACK (on_chart_save_csv_response), chart); } static GActionEntry win_actions[] = { { "save-image", chart_save_image, NULL, NULL, NULL, {} }, { "save-csv", chart_save_csv, NULL, NULL, NULL, {} } }; static void chart_button_clicked_fullscreen(GtkButton *button, gpointer data) { UNUSED(button); GtkWindow *window = GTK_WINDOW(data); gtk_window_fullscreen(window); } static bool chart_key_pressed_cb(GtkEventControllerKey* self, guint keyval, guint keycode, GdkModifierType state, gpointer user_data) { UNUSED(self); UNUSED(state); GtkWindow *window = GTK_WINDOW(user_data); // If key pressed if ((keyval == 0xff1b) && (keycode == 0x9)) { // Exit fullscreen if (gtk_window_is_fullscreen(window)) { gtk_window_unfullscreen(window); } } return true; } static gboolean gui_chart_save_csv_thread(gpointer user_data) { struct chart_t *chart = user_data; gtk_chart_save_csv(GTK_CHART(chart->widget), chart->filename_csv); g_free(chart->filename_csv); // Signal we are finished saving csv file g_mutex_unlock(&self_global->mutex_save_csv); return G_SOURCE_REMOVE; } // lua: chart_save_csv(handle) static int lua_gui_chart_save_csv(lua_State* L) { int handle = lua_tointeger(L, 1); const char *filename = lua_tostring(L, 2); if (gui_chart[handle].allocated == true) { gui_chart[handle].filename_csv = g_strdup(filename); char *text = g_strdup_printf ("Saving %s\n", filename); text_view_add_buffer(self_global->text_view_script_status, text); g_free(text); g_idle_add(gui_chart_save_csv_thread, &gui_chart[handle]); // Wait for save csv operation finished g_mutex_lock(&self_global->mutex_save_csv); } return 0; } static gboolean gui_chart_save_png_thread(gpointer user_data) { struct chart_t *chart = user_data; gtk_chart_save_png(GTK_CHART(chart->widget), chart->filename_png); g_free(chart->filename_png); // Signal we are finished saving png file g_mutex_unlock(&self_global->mutex_save_png); return G_SOURCE_REMOVE; } // lua: chart_save_png(handle) static int lua_gui_chart_save_png(lua_State* L) { int handle = lua_tointeger(L, 1); const char *filename = lua_tostring(L, 2); if (gui_chart[handle].allocated == true) { gui_chart[handle].filename_png = g_strdup(filename); char *text = g_strdup_printf ("Saving %s\n", filename); text_view_add_buffer(self_global->text_view_script_status, text); g_free(text); g_idle_add(gui_chart_save_png_thread, &gui_chart[handle]); // Wait for save png operation finished g_mutex_lock(&self_global->mutex_save_png); } return 0; } static gboolean gui_chart_close_thread(gpointer user_data) { GtkWindow *window = user_data; gtk_window_close(window); return G_SOURCE_REMOVE; } // lua: chart_close(handle) static int lua_gui_chart_close(lua_State* L) { int handle = lua_tointeger(L, 1); if (gui_chart[handle].allocated == true) { g_idle_add(gui_chart_close_thread, gui_chart[handle].window); } return 0; } static gboolean gui_chart_plot_thread(gpointer user_data) { struct chart_t *chart = user_data; gtk_chart_plot_point(GTK_CHART(chart->widget), chart->x, chart->y); return G_SOURCE_REMOVE; } // lua: chart_plot(handle, x_value, y_value) static int lua_gui_chart_plot(lua_State* L) { int handle = lua_tointeger(L, 1); double x = lua_tonumber(L, 2); double y = lua_tonumber(L, 3); gui_chart[handle].x = x; gui_chart[handle].y = y; if (gui_chart[handle].allocated == true) { g_idle_add(gui_chart_plot_thread, &gui_chart[handle]); } return 0; } static gboolean gui_chart_set_value_thread(gpointer user_data) { struct chart_t *chart = user_data; gtk_chart_set_value(GTK_CHART(chart->widget), chart->value); return G_SOURCE_REMOVE; } // lua: chart_set_value(handle, value) static int lua_gui_chart_set_value(lua_State* L) { int handle = lua_tointeger(L, 1); double value = lua_tonumber(L, 2); gui_chart[handle].value = value; if (gui_chart[handle].allocated == true) { g_idle_add(gui_chart_set_value_thread, &gui_chart[handle]); } return 0; } static gboolean gui_chart_new_thread(gpointer data) { struct chart_t *chart = data; GAction *action; GActionGroup *actions; /* Construct a GtkBuilder instance from UI description */ GtkBuilder *builder = gtk_builder_new_from_resource("/io/github/lxi-tools/lxi-gui/lxi_gui-chart.ui"); // Get UI objects GtkWindow *window = GTK_WINDOW(gtk_builder_get_object (builder, "window")); GObject *button_fullscreen = gtk_builder_get_object (builder, "button_fullscreen"); GtkWidget *widget = GTK_WIDGET(gtk_builder_get_object (builder, "chart")); // Map window actions actions = G_ACTION_GROUP (g_simple_action_group_new ()); g_action_map_add_action_entries (G_ACTION_MAP(actions), win_actions, G_N_ELEMENTS(win_actions), chart); gtk_widget_insert_action_group (GTK_WIDGET (window), "chart", G_ACTION_GROUP (actions)); // Disable "Save CSV" if chart features no CSV data action = g_action_map_lookup_action (G_ACTION_MAP (actions), "save-csv"); if (chart->no_csv) { g_simple_action_set_enabled (G_SIMPLE_ACTION (action), false); } // Prepare window chart->window = window; gtk_window_set_decorated(window, true); gtk_window_set_modal(window, false); gtk_window_set_transient_for(window, GTK_WINDOW(self_global)); gtk_window_set_resizable(window, true); switch (chart->type) { case GTK_CHART_TYPE_LINE: gtk_window_set_title(window, "Line Chart"); gtk_window_set_default_size(window, chart->width, chart->width/2); break; case GTK_CHART_TYPE_SCATTER: gtk_window_set_title(window, "Scatter Chart"); gtk_window_set_default_size(window, chart->width, chart->width/2); break; case GTK_CHART_TYPE_NUMBER: gtk_window_set_title(window, "Number Chart"); gtk_window_set_default_size(window, chart->width, chart->width/2); break; case GTK_CHART_TYPE_GAUGE_LINEAR: gtk_window_set_title(window, "Linear Gauge"); gtk_window_set_default_size(window, chart->width, chart->width*2); break; case GTK_CHART_TYPE_GAUGE_ANGULAR: gtk_window_set_title(window, "Angular Gauge"); gtk_window_set_default_size(window, chart->width, chart->width); break; default: // Do nothing break; } // Prepare chart widget chart->widget = widget; gtk_chart_set_type(GTK_CHART(widget), chart->type); gtk_chart_set_title(GTK_CHART(widget), chart->title); g_free(chart->title); gtk_chart_set_width(GTK_CHART(widget), chart->width); switch (chart->type) { case GTK_CHART_TYPE_LINE: case GTK_CHART_TYPE_SCATTER: gtk_chart_set_x_label(GTK_CHART(widget), chart->x_label); g_free(chart->x_label); gtk_chart_set_y_label(GTK_CHART(widget), chart->y_label); g_free(chart->y_label); gtk_chart_set_x_max(GTK_CHART(widget), chart->x_max); gtk_chart_set_y_max(GTK_CHART(widget), chart->y_max); break; case GTK_CHART_TYPE_NUMBER: gtk_chart_set_label(GTK_CHART(widget), chart->label); g_free(chart->label); break; case GTK_CHART_TYPE_GAUGE_LINEAR: case GTK_CHART_TYPE_GAUGE_ANGULAR: gtk_chart_set_label(GTK_CHART(widget), chart->label); g_free(chart->label); gtk_chart_set_value_min(GTK_CHART(widget), chart->value_min); gtk_chart_set_value_max(GTK_CHART(widget), chart->value_max); break; default: // Do nothing break; } // Install event controller to listen for key presses GtkEventController *controller = gtk_event_controller_key_new(); gtk_widget_add_controller(GTK_WIDGET(window), controller); // Associate window with application for signals etc. to propagate GtkApplication *app = gtk_window_get_application(GTK_WINDOW(self_global)); gtk_application_add_window(app, window); // Connect signals g_signal_connect (button_fullscreen, "clicked", G_CALLBACK (chart_button_clicked_fullscreen), window); g_signal_connect (controller, "key-pressed", G_CALLBACK (chart_key_pressed_cb), window); g_signal_connect (widget, "destroy", G_CALLBACK (chart_destroyed_cb), NULL); // Show window gtk_window_present(window); // Cleanup g_object_unref(builder); // Signal we are finished creating chart g_mutex_unlock(&self_global->mutex_gui_chart); return G_SOURCE_REMOVE; } // lua: handle = chart_new(...) static int lua_gui_chart_new(lua_State* L) { int handle; // Find free chart handle for (handle=0; handletype = GTK_CHART_TYPE_LINE; } else if (strcmp(type, "scatter") == 0) { chart->type = GTK_CHART_TYPE_SCATTER; } else if (strcmp(type, "number") == 0) { chart->type = GTK_CHART_TYPE_NUMBER; } else if (strcmp(type, "linear-gauge") == 0) { chart->type = GTK_CHART_TYPE_GAUGE_LINEAR; } else if (strcmp(type, "angular-gauge") == 0) { chart->type = GTK_CHART_TYPE_GAUGE_ANGULAR; } else { chart->type = GTK_CHART_TYPE_UNKNOWN; } chart->handle = handle; // Parse arguments depending on chart type switch (chart->type) { case GTK_CHART_TYPE_LINE: case GTK_CHART_TYPE_SCATTER: chart->title = g_strdup(lua_tostring(L, 2)); chart->x_label = g_strdup(lua_tostring(L, 3)); chart->y_label = g_strdup(lua_tostring(L, 4)); chart->x_max = lua_tonumber(L, 5); chart->y_max = lua_tonumber(L, 6); chart->width = lua_tointeger(L, 7); chart->autoscale = lua_toboolean(L, 8); chart->no_csv = false; break; case GTK_CHART_TYPE_NUMBER: chart->title = g_strdup(lua_tostring(L, 2)); chart->label = g_strdup(lua_tostring(L, 3)); chart->width = lua_tointeger(L, 4); chart->no_csv = true; break; case GTK_CHART_TYPE_GAUGE_LINEAR: case GTK_CHART_TYPE_GAUGE_ANGULAR: chart->title = g_strdup(lua_tostring(L, 2)); chart->label = g_strdup(lua_tostring(L, 3)); chart->value_min = lua_tonumber(L, 4); chart->value_max = lua_tonumber(L, 5); chart->width = lua_tointeger(L, 6); chart->no_csv = true; break; default: break; } // Create new chart window g_idle_add(gui_chart_new_thread, chart); // Wait for chart ready (sleeps here until unlocked) g_mutex_lock(&self_global->mutex_gui_chart); // Return chart handle lua_pushinteger(L, handle); return 1; } // lua: print(string) // Note: Overrides lua builtin print() static int lua_print(lua_State* L) { int nargs = lua_gettop(L); for (int i=1; i <= nargs; i++) { if (lua_isstring(L, i)) { lua_print_string(lua_tostring(L,i)); } else { /* non-strings */ } } return 0; } // lua: ip = selected_ip() static int lua_gui_ip(lua_State* L) { // Return currently GUI selected IP lua_pushstring(L, self_global->ip); return 1; } // lua: id = selected_id() static int lua_gui_id(lua_State* L) { // Return currently GUI selected ID lua_pushstring(L, self_global->id); return 1; } // lua: version = version() static int lua_gui_version(lua_State* L) { // Return GUI version lua_pushstring(L, PACKAGE_VERSION); return 1; } static const struct luaL_Reg gui_lib [] = { {"lxi_chart_new", lua_gui_chart_new}, {"lxi_chart_plot", lua_gui_chart_plot}, {"lxi_chart_set_value", lua_gui_chart_set_value}, {"lxi_chart_close", lua_gui_chart_close}, {"lxi_chart_save_csv", lua_gui_chart_save_csv}, {"lxi_chart_save_png", lua_gui_chart_save_png}, {"lxi_selected_ip", lua_gui_ip}, {"lxi_selected_id", lua_gui_id}, {"lxi_version", lua_gui_version}, {"print", lua_print}, {NULL, NULL} }; static void lua_line_hook(lua_State *L, lua_Debug *ar) { if (ar->event == LUA_HOOKLINE) { if (self_global->lua_stop_requested == true) { luaL_error(L, "Stopped by user"); } } } #if !defined LUA_VERSION_NUM || LUA_VERSION_NUM==501 /* ** Adapted from Lua 5.2.0 (for backwards compatibility) */ static void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { luaL_checkstack(L, nup+1, "too many upvalues"); for (; l->name != NULL; l++) { /* fill the table with given functions */ int i; lua_pushstring(L, l->name); for (i = 0; i < nup; i++) /* copy upvalues to the top */ lua_pushvalue(L, -(nup+1)); lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */ lua_settable(L, -(nup + 3)); } lua_pop(L, nup); /* remove upvalues */ } #endif extern int lua_register_gui(lua_State *L) { // Register gui functions lua_getglobal(L, "_G"); luaL_setfuncs(L, gui_lib, 0); lua_pop(L, 1); // Install line hook to manage run/stop execution lua_sethook(L, &lua_line_hook, LUA_MASKLINE, 0); return 0; } static void load_log_script(lua_State *L) { gsize size; int error; GResource *resource = lxi_gui_get_resource(); GBytes *script = g_resource_lookup_data (resource, "/io/github/lxi-tools/lxi-gui/log.lua", G_RESOURCE_LOOKUP_FLAGS_NONE, NULL); gconstpointer script_buffer = g_bytes_get_data (script, &size); error = luaL_loadbuffer(L, script_buffer, strlen(script_buffer), "lxi-gui") || lua_pcall(L, 0, 0, 0); if (error) { lua_print_error(self_global, lua_tostring(L, -1)); lua_pop(L, 1); /* pop error message from the stack */ } } static gpointer script_run_worker_function(gpointer data) { LxiGuiWindow *self = data; GtkTextBuffer *buffer_script = gtk_text_view_get_buffer(GTK_TEXT_VIEW(self->source_view_script)); GtkTextIter start, end; gchar *code_buffer; int error; char *chunkname = NULL; char *filename; // Reset lua control state self->lua_stop_requested = false; // Initialize new Lua session lua_State *L = luaL_newstate(); // Open all standard Lua libraries luaL_openlibs(L); // Bind GUI functions lua_register_gui(L); // Bind lxi functions lua_register_lxi(L); // Load data logger script load_log_script(L); // Hardcode locale so script handles number conversion correct etc. setlocale(LC_ALL, "C.UTF-8"); // Get buffer of script text view gtk_text_buffer_get_bounds(buffer_script, &start, &end); code_buffer = gtk_text_buffer_get_text(buffer_script, &start, &end, true); // Use filename as chunk name if working with a file if (self->script_file != NULL) { filename = g_file_get_path(self->script_file); chunkname = g_path_get_basename(filename); g_free(filename); } else { chunkname = strdup("buffer"); } // Let lua load buffer and do error checking before running error = luaL_loadbuffer(L, code_buffer, strlen(code_buffer), chunkname) || lua_pcall(L, 0, 0, 0); if (error) { lua_print_error(self, lua_tostring(L, -1)); lua_pop(L, 1); /* pop error message from the stack */ } // Cleanup g_free(chunkname); lua_close(L); // Restore script run button g_idle_add(gui_update_script_run_worker_function_finished_thread, self); return NULL; } static void toggle_button_clicked_script_run(LxiGuiWindow *self, GtkButton *button) { UNUSED(button); // Only allow to run once until execution is done gtk_widget_set_sensitive(GTK_WIDGET(self->toggle_button_script_run), false); text_view_clear_buffer(self->text_view_script_status); // Start thread which starts interpreting the Lua script self->script_run_worker_thread = g_thread_new("script_worker", script_run_worker_function, (gpointer) self); } static void button_clicked_script_stop(LxiGuiWindow *self, GtkButton *button) { UNUSED(self); UNUSED(button); // Signal lua script engine to stop execution self->lua_stop_requested = true; } static void info_bar_clicked(LxiGuiWindow *self, GtkInfoBar *infobar) { UNUSED(self); UNUSED(infobar); // TODO: Fix and use callback parameters gtk_widget_hide(GTK_WIDGET(self_global->info_bar)); } static void lxi_gui_window_dispose(GObject *object) { LxiGuiWindow *window = (LxiGuiWindow *)object; g_object_unref (window->settings); // Remove list view port as parent to list popover menu gtk_widget_unparent(GTK_WIDGET(window->list_widget_popover_menu)); G_OBJECT_CLASS (lxi_gui_window_parent_class)->dispose (object); } static void lxi_gui_window_action_copy_screenshot_cb(GtkWidget *widget, const char *action_name, GVariant *param) { UNUSED(action_name); UNUSED(param); LxiGuiWindow *self = LXI_GUI_WINDOW (widget); GtkSelectionModel *selection_model = adw_view_stack_get_pages(self->view_stack); // If screenshot page is selected if (gtk_selection_model_is_selected(selection_model, 1)) { // If screenshot image is available if (self->pixbuf_screenshot != NULL) { // Copy image to clipboard gdk_clipboard_set_texture(self->clipboard, gdk_texture_new_for_pixbuf(self->pixbuf_screenshot)); } } else { // Perform normal copy action GtkWidget *widget = gtk_window_get_focus(GTK_WINDOW(self)); if (widget != NULL) { g_signal_emit_by_name(widget, "copy-clipboard"); } } } static void lxi_gui_window_action_search_cb(GtkWidget *widget, const char *action_name, GVariant *param) { UNUSED(action_name); UNUSED(param); LxiGuiWindow *self = LXI_GUI_WINDOW (widget); g_assert (LXI_GUI_IS_WINDOW (self)); // Disable shortcut action temporarily gtk_widget_action_set_enabled (GTK_WIDGET (self), "action.search", false); button_clicked_search(self, NULL); } static void lxi_gui_window_action_toggle_flap_cb(GtkWidget *widget, const char *action_name, GVariant *param) { UNUSED(action_name); UNUSED(param); LxiGuiWindow *self = LXI_GUI_WINDOW (widget); g_assert (LXI_GUI_IS_WINDOW (self)); bool flap_state = adw_flap_get_reveal_flap(self->flap); // Toggle flap adw_flap_set_reveal_flap(self->flap, !flap_state); } static void lxi_gui_window_class_init(LxiGuiWindowClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class); object_class->dispose = lxi_gui_window_dispose; // Bind widgets gtk_widget_class_set_template_from_resource (widget_class, "/io/github/lxi-tools/lxi-gui/lxi_gui-window.ui"); gtk_widget_class_bind_template_child (widget_class, LxiGuiWindow, list_box_instruments); gtk_widget_class_bind_template_child (widget_class, LxiGuiWindow, list_viewport); gtk_widget_class_bind_template_child (widget_class, LxiGuiWindow, entry_scpi); gtk_widget_class_bind_template_child (widget_class, LxiGuiWindow, text_view_scpi); gtk_widget_class_bind_template_child (widget_class, LxiGuiWindow, toggle_button_scpi_send); gtk_widget_class_bind_template_child (widget_class, LxiGuiWindow, picture_screenshot); gtk_widget_class_bind_template_child (widget_class, LxiGuiWindow, toggle_button_screenshot_grab); gtk_widget_class_bind_template_child (widget_class, LxiGuiWindow, button_screenshot_save); gtk_widget_class_bind_template_child (widget_class, LxiGuiWindow, progress_bar_benchmark); gtk_widget_class_bind_template_child (widget_class, LxiGuiWindow, toggle_button_benchmark_start); gtk_widget_class_bind_template_child (widget_class, LxiGuiWindow, spin_button_benchmark_requests); gtk_widget_class_bind_template_child (widget_class, LxiGuiWindow, label_benchmark_result); gtk_widget_class_bind_template_child (widget_class, LxiGuiWindow, image_benchmark); gtk_widget_class_bind_template_child (widget_class, LxiGuiWindow, toggle_button_search); gtk_widget_class_bind_template_child (widget_class, LxiGuiWindow, source_view_script); gtk_widget_class_bind_template_child (widget_class, LxiGuiWindow, text_view_script_status); gtk_widget_class_bind_template_child (widget_class, LxiGuiWindow, info_bar); gtk_widget_class_bind_template_child (widget_class, LxiGuiWindow, label_info_bar); gtk_widget_class_bind_template_child (widget_class, LxiGuiWindow, view_stack); gtk_widget_class_bind_template_child (widget_class, LxiGuiWindow, viewport_screenshot); gtk_widget_class_bind_template_child (widget_class, LxiGuiWindow, toggle_button_script_run); gtk_widget_class_bind_template_child (widget_class, LxiGuiWindow, flap); gtk_widget_class_bind_template_child (widget_class, LxiGuiWindow, status_page_instruments); // Bind signal callbacks gtk_widget_class_bind_template_callback (widget_class, button_clicked_search); gtk_widget_class_bind_template_callback (widget_class, button_clicked_add_instrument); gtk_widget_class_bind_template_callback (widget_class, entry_scpi_enter_pressed); gtk_widget_class_bind_template_callback (widget_class, button_clicked_scpi); gtk_widget_class_bind_template_callback (widget_class, button_clicked_scpi_clear); gtk_widget_class_bind_template_callback (widget_class, button_clicked_scpi_send); gtk_widget_class_bind_template_callback (widget_class, button_clicked_screenshot_grab); gtk_widget_class_bind_template_callback (widget_class, button_clicked_screenshot_save); gtk_widget_class_bind_template_callback (widget_class, button_clicked_benchmark_start); gtk_widget_class_bind_template_callback (widget_class, button_clicked_script_new); gtk_widget_class_bind_template_callback (widget_class, button_clicked_script_open); gtk_widget_class_bind_template_callback (widget_class, button_clicked_script_save); gtk_widget_class_bind_template_callback (widget_class, button_clicked_script_save_as); gtk_widget_class_bind_template_callback (widget_class, toggle_button_clicked_script_run); gtk_widget_class_bind_template_callback (widget_class, button_clicked_script_stop); gtk_widget_class_bind_template_callback (widget_class, info_bar_clicked); /* These are the actions that we are using in the menu */ gtk_widget_class_install_action (widget_class, "action.copy_ip", NULL, action_cb); gtk_widget_class_install_action (widget_class, "action.copy_id", NULL, action_cb); gtk_widget_class_install_action (widget_class, "action.remove", NULL, action_cb); gtk_widget_class_install_action (widget_class, "action.edit", NULL, action_cb); gtk_widget_class_install_action (widget_class, "action.open_browser", NULL, action_cb); gtk_widget_class_install_action (widget_class, "action.search", NULL, lxi_gui_window_action_search_cb); gtk_widget_class_install_action (widget_class, "action.toggle_flap", NULL, lxi_gui_window_action_toggle_flap_cb); gtk_widget_class_install_action (widget_class, "scpi_clear_all", NULL, scpi_action_cb); gtk_widget_class_install_action (widget_class, "scpi_save_as", NULL, scpi_action_cb); gtk_widget_class_install_action (widget_class, "action.copy_screenshot", NULL, lxi_gui_window_action_copy_screenshot_cb); /* Create shortcuts */ gtk_widget_class_add_binding_action (widget_class, GDK_KEY_s, GDK_CONTROL_MASK, "action.search", NULL); gtk_widget_class_add_binding_action (widget_class, GDK_KEY_h, GDK_CONTROL_MASK, "action.toggle_flap", NULL); gtk_widget_class_add_binding_action (widget_class, GDK_KEY_c, GDK_CONTROL_MASK, "action.copy_screenshot", NULL); // Initialize LXI library lxi_init(); // Set up search information callbacks info.broadcast = &vxi11_broadcast; info.device = &vxi11_device; info.service = &mdns_service; // For mDNS } static gboolean scroll_screenshot( GtkEventControllerScroll* controller, gdouble dx, gdouble dy, gpointer data ) { UNUSED(controller); UNUSED(dx); LxiGuiWindow *self = data; int width; width = gtk_widget_get_width(GTK_WIDGET(self->picture_screenshot)); if (self->screenshot_loaded) { gtk_widget_set_size_request(GTK_WIDGET(self->picture_screenshot), width, -1); gtk_widget_set_valign(GTK_WIDGET(self->picture_screenshot), GTK_ALIGN_CENTER); gtk_widget_set_halign(GTK_WIDGET(self->picture_screenshot), GTK_ALIGN_CENTER); self->screenshot_loaded = false; } if (dy > 0) { // Scroll down -> zoom in width = width * 0.9; } else { // Scroll up -> zoom out width = width * 1.1; } gtk_widget_set_size_request(GTK_WIDGET(self->picture_screenshot), width, -1); return TRUE; } static void lxi_gui_window_init(LxiGuiWindow *self) { GtkGesture *list_widget_gesture = gtk_gesture_click_new(); gtk_widget_init_template (GTK_WIDGET (self)); self_global = self; // Required for GtkSourceView to be recognized by builder gtk_source_view_get_type(); // Required for GtkChart to be recognized by builder gtk_chart_get_type(); // Load settings self->settings = g_settings_new ("io.github.lxi-tools.lxi-gui"); // Set up clipboard GdkDisplay* gdk_display = gdk_display_get_default(); self->clipboard = gdk_display_get_clipboard(gdk_display); // Manage dark theme setting bool prefer_dark_theme = g_settings_get_boolean(self->settings, "prefer-dark-theme"); if (prefer_dark_theme) { AdwStyleManager *adw_style_manager = adw_style_manager_get_default(); adw_style_manager_set_color_scheme(adw_style_manager, ADW_COLOR_SCHEME_PREFER_DARK); } // Load and apply CSS GtkCssProvider *provider = gtk_css_provider_new (); gtk_css_provider_load_from_resource (provider, "/io/github/lxi-tools/lxi-gui/lxi_gui.css"); gtk_style_context_add_provider_for_display (gdk_display_get_default (), GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); // Load instrument popover menu from model GtkBuilder *builder = gtk_builder_new_from_resource ("/io/github/lxi-tools/lxi-gui/lxi_gui-window_list_widget_menu_model.ui"); self->list_widget_menu_model = G_MENU_MODEL (gtk_builder_get_object (builder, "list-widget-menu-model")); // Load popover menu from menu model self->list_widget_popover_menu = gtk_popover_menu_new_from_model(self->list_widget_menu_model); gtk_popover_set_has_arrow(GTK_POPOVER(self->list_widget_popover_menu), false); // Add list view port as parent to list popover menu gtk_widget_set_parent (GTK_WIDGET(self->list_widget_popover_menu), GTK_WIDGET(self->list_viewport)); // Add event controller to handle any click gesture on list viewport widget gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (list_widget_gesture), 0); g_signal_connect (list_widget_gesture, "pressed", G_CALLBACK (pressed_cb), self); gtk_widget_add_controller (GTK_WIDGET(self->list_viewport), GTK_EVENT_CONTROLLER (list_widget_gesture)); // Add event controller to capture scroll events on the surface of screenshot viewport GtkEventController *event_controller_screenshot; event_controller_screenshot = gtk_event_controller_scroll_new (GTK_EVENT_CONTROLLER_SCROLL_VERTICAL); gtk_widget_add_controller(GTK_WIDGET(self->viewport_screenshot), event_controller_screenshot); g_signal_connect(event_controller_screenshot, "scroll", G_CALLBACK (scroll_screenshot), self); // Set up SCPI command entry gtk_editable_set_enable_undo (GTK_EDITABLE (self->entry_scpi), TRUE); g_object_unref (builder); g_object_unref (provider); self->ip = NULL; self->id = NULL; self->protocol = -1; self->port = -1; // Register LXI screenshot plugins screenshot_register_plugins(); // Set greeting image on screenshot page and make it not zoomable gtk_widget_set_size_request(GTK_WIDGET(self->picture_screenshot), 200, 200); gtk_picture_set_resource(self->picture_screenshot, "/io/github/lxi-tools/lxi-gui/images/photo-camera.png"); gtk_widget_set_sensitive(GTK_WIDGET(self->viewport_screenshot), false); // Set greeting image on benchmark page gtk_image_set_pixel_size(self->image_benchmark, 160); gtk_image_set_from_resource(self->image_benchmark, "/io/github/lxi-tools/lxi-gui/images/runner.png"); // Grab focus to SCPI input entry gtk_widget_grab_focus(GTK_WIDGET(self->entry_scpi)); // Disable screenshot "Save" button until image is present gtk_widget_set_sensitive(GTK_WIDGET(self->button_screenshot_save), false); self->pixbuf_screenshot = NULL; // Initialize script file self->script_file = NULL; // Set language of source buffer to "lua-lxi-gui" GtkSourceBuffer *source_buffer_script = GTK_SOURCE_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(self->source_view_script))); GtkSourceLanguageManager *language_manager = gtk_source_language_manager_get_default(); gtk_source_language_manager_append_search_path(language_manager, "resource:///io/github/lxi-tools/lxi-gui/language-specs"); GtkSourceLanguage *language = gtk_source_language_manager_get_language(language_manager, "lua-lxi-gui"); gtk_source_buffer_set_language(source_buffer_script, language); // Enable line numbers gtk_source_view_set_show_line_numbers(self->source_view_script, true); // Enable syntax highlighting according to language gtk_source_buffer_set_highlight_syntax(source_buffer_script, true); // Highlight current line gtk_source_view_set_highlight_current_line(self->source_view_script, true); // Set script view theme to "classic" GtkSourceStyleSchemeManager* style_manager = gtk_source_style_scheme_manager_new(); GtkSourceStyleScheme *style = gtk_source_style_scheme_manager_get_scheme(style_manager, "classic-dark"); gtk_source_buffer_set_style_scheme(source_buffer_script, style); // Initialize mutexes g_mutex_lock(&self->mutex_gui_chart); g_mutex_lock(&self->mutex_save_png); g_mutex_lock(&self->mutex_save_csv); // Initialize lua script engine initialize_script_engine(self); // Add extra menu model for SCPI text view (right click menu) GMenu *menu = g_menu_new (); g_menu_append (menu, "Clear all", "scpi_clear_all"); g_menu_append (menu, "Save as..", "scpi_save_as"); gtk_text_view_set_extra_menu (self->text_view_scpi, G_MENU_MODEL(menu)); #if DEVEL_MODE gtk_widget_add_css_class(GTK_WIDGET(self), "devel"); #endif // Add manually added instruments to list widget int added_instruments = add_instruments_from_gsettings(); if (added_instruments > 0) { gtk_widget_set_visible(GTK_WIDGET(self->status_page_instruments), false); } self->list_box_row_pressed = NULL; self->list_box_row_selected = NULL; } lxi-tools-2.7/src/lxi_gui-window.h000066400000000000000000000033701447016333500172320ustar00rootroot00000000000000/* * Copyright (c) 2021-2022 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #pragma once #include G_BEGIN_DECLS #define LXI_GUI_TYPE_WINDOW (lxi_gui_window_get_type()) G_DECLARE_FINAL_TYPE (LxiGuiWindow, lxi_gui_window, LXI_GUI, WINDOW, GtkApplicationWindow) G_END_DECLS lxi-tools-2.7/src/lxi_gui-window.ui000066400000000000000000003170011447016333500174170ustar00rootroot00000000000000

_Preferences app.preferences _Keyboard Shortcuts win.show-help-overlay _About lxi-gui app.about
99900 100 1000 100 1000 lxi-tools-2.7/src/lxi_gui-window_list_widget_menu_model.ui000066400000000000000000000014031447016333500242150ustar00rootroot00000000000000 Copy IP action.copy_ip Copy ID action.copy_id Open in browser action.open_browser Edit action.edit Remove action.remove lxi-tools-2.7/src/lxi_gui.css000066400000000000000000000030011447016333500162550ustar00rootroot00000000000000/* Application Window */ #button-add-instrument { margin-left: 2px; } /* SCPI page */ .text-view-scpi { background-color: shade(@theme_base_color, .90); border-color: alpha(black, 0.8); border-top-left-radius: 5px; border-top-right-radius: 5px; padding: 5px; } .text-view-scpi text { background-color: rgba(0,0,0,0); } .entry-scpi { background-color: shade(@theme_base_color, .80); border: solid @borders 0px; border-top-width: 1px; border-color: @theme_bg_color; border-top-color: alpha(black, 0.2); border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; outline-width: 0px; } .scpi-label { font-weight: bolder; font-size: 0.7em; color: alpha(@theme_text_color, 0.3); } #button-scpi-clear { background-color: @warning_bg_color; } /* Screenshot page */ /* Benchmark page */ .page-benchmark trough { min-height: 60px; } .page-benchmark progress { min-height: 60px; } .label-benchmark-result { font-weight: bold; font-size: 1.8em; } /* Script page */ .box-script-toolbar { margin-top: 10px; } .source-view-script { border-top-left-radius: 5px; border-top-right-radius: 5px; padding: 10px; } .text-view-script-status { background-color: shade(@theme_base_color, .80); border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; padding: 10px; border-top-width: 1px; border-top-color: alpha(black, 0.2); } .text-view-script-status text { background-color: rgba(0,0,0,0); } lxi-tools-2.7/src/lxi_gui.gresource.xml000066400000000000000000000025251447016333500202740ustar00rootroot00000000000000 lxi_gui-window.ui lxi_gui-instrument_dialog.ui lxi_gui-chart.ui lxi_gui-prefs.ui lxi_gui-window_list_widget_menu_model.ui gtk/help-overlay.ui language-specs/lua-lxi-gui.lang icons/128x128/status/dialog-information-symbolic.symbolic.png icons/16x16/actions/view-sidebar-start.symbolic.png icons/16x16/actions/view-fullscreen-symbolic.symbolic.png icons/16x16/actions/scpi.symbolic.png icons/16x16/actions/screenshot.symbolic.png icons/16x16/actions/benchmark.symbolic.png icons/16x16/actions/script.symbolic.png icons/lxi-tools-icon-128px.png icons/lxi-instrument-discovered.png icons/lxi-instrument-manual.png images/photo-camera.png images/runner.png lxi_gui.css log.lua lxi-tools-2.7/src/lxilua.c000066400000000000000000000251201447016333500155530ustar00rootroot00000000000000/* * Copyright (c) 2018-2022, Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include "error.h" #include "misc.h" #include #define RESPONSE_LENGTH_MAX 0x400000 #define SESSIONS_MAX 1024 #define CLOCKS_MAX 1024 struct session_t { int timeout; int protocol; }; static struct session_t session[SESSIONS_MAX]; struct lua_clock_t { double time_start; bool allocated; }; static struct lua_clock_t lua_clock[CLOCKS_MAX]; static char log_script[] = "__lxi_log_data = {}\n" "\n" "function lxi_log_new()\n" "\n" " local data = __lxi_log_data\n" "\n" " handle = #data + 1\n" " data[handle] = {}\n" "\n" " return handle\n" "end\n" "\n" "function lxi_log_free(handle)\n" "-- table.remove(data, handle)\n" "end\n" "\n" "function lxi_log_add(handle, ...)\n" "\n" " local data = __lxi_log_data\n" "\n" " i = #data[handle] + 1\n" "\n" " data[handle][i] = {}\n" " for j,v in ipairs{...} do\n" " data[handle][i][j] = v\n" " end\n" "end\n" "\n" "function lxi_log_save_csv(handle, filename)\n" "\n" " local data = __lxi_log_data\n" "\n" " file = io.open(filename, \"w\")\n" " io.output(file)\n" "\n" " for i=1, #data[handle], 1\n" " do \n" " for j=1, #data[handle][i], 1\n" " do\n" " if (j == #data[handle][i])\n" " then\n" " io.write(data[handle][i][j])\n" " else\n" " io.write(data[handle][i][j] .. \",\")\n" " end\n" " end\n" " io.write(\"\\n\")\n" " end\n" "\n" " io.close(file)\n" "end\n"; // lua: device = lxi_connect(address, port, name, timeout, protocol) static int connect(lua_State *L) { int device; const char *address = lua_tostring(L, 1); int port = lua_tointeger(L, 2); const char *name = lua_tostring(L, 3); int timeout = lua_tointeger(L, 4); const char *protocol = lua_tostring(L, 5); // Default connect arguments int arg_port = 5025; const char *arg_name = "inst0"; int arg_timeout = 2000; int arg_protocol = VXI11; // Handle port if (port != 0) arg_port = port; // Handle name if (name != NULL) arg_name = name; // Handle timeout if (timeout != 0) arg_timeout = timeout; // Handle protocol if (strcmp(protocol, "VXI11") == 0) arg_protocol = VXI11; if (strcmp(protocol, "RAW") == 0) arg_protocol = RAW; // Connect to LXI instrument using VXI11 device = lxi_connect(address, arg_port, arg_name, arg_timeout, arg_protocol); if (device == LXI_ERROR) error_printf("Failed to connect\n"); // Save session data for later reuse session[device].timeout = arg_timeout; session[device].protocol = arg_protocol; // Return status lua_pushinteger(L, device); return 1; } // lua: lxi_disconnect(device) static int disconnect(lua_State *L) { int status = 0; int device = lua_tointeger(L, 1); // Disconnect status = lxi_disconnect(device); // Return status lua_pushnumber(L, status); return 1; } // lua: scpi(device, command, timeout) static int scpi(lua_State *L) { char* response = malloc(RESPONSE_LENGTH_MAX); int status = 0, length; int device = lua_tointeger(L, 1); const char *command = lua_tostring(L, 2); int timeout = lua_tointeger(L, 3); char command_buffer[1000]; // Use session timeout if no timeout provided if (timeout == 0) timeout = session[device].timeout; strip_trailing_space((char *) command); if (session[device].protocol == RAW) { // Add newline to command string strcpy(command_buffer, command); command_buffer[strlen(command)] = '\n'; command_buffer[strlen(command)+1] = 0; command = command_buffer; } // Send SCPI command length = lxi_send(device, command, strlen(command), timeout); if (length < 0) { error_printf("Failed to send message\n"); status = length; goto error; } // Only expect response in case we are firing a question command if (question(command)) { length = lxi_receive(device, response, RESPONSE_LENGTH_MAX, timeout); if (length < 0) { error_printf("Failed to receive message\n"); status = length; goto error; } } if (length > 0) { // Strip newline if (response[length-1] == '\n') response[--length] = 0; // Strip carriage return if (response[length-1] == '\r') response[--length] = 0; } lua_pushlstring(L, response, length); free(response); return 1; error: // Return status lua_pushnumber(L, status); free(response); return 1; } // lua: scpi_raw(device, command, timeout) static int scpi_raw(lua_State *L) { char* response = malloc(RESPONSE_LENGTH_MAX); int status = 0, length; int device = lua_tointeger(L, 1); const char *command = lua_tostring(L, 2); int timeout = lua_tointeger(L, 3); // Use session timeout if no timeout provided if (timeout == 0) timeout = session[device].timeout; // Send SCPI command length = lxi_send(device, command, strlen(command), timeout); if (length < 0) { error_printf("Failed to send message\n"); status = length; goto error; } // Only expect response in case we are firing a question command if (question(command)) { length = lxi_receive(device, response, RESPONSE_LENGTH_MAX, timeout); if (length < 0) { error_printf("Failed to receive message\n"); status = length; goto error; } } lua_pushlstring(L, response, length); free(response); return 1; error: // Return status lua_pushnumber(L, status); free(response); return 1; } // lua: sleep(seconds) static int sleep_(lua_State *L) { long seconds = lua_tointeger(L, 1); sleep(seconds); return 0; } // lua: msleep(miliseconds) static int msleep(lua_State *L) { long mseconds = lua_tointeger(L, 1); long useconds = mseconds * 1000; usleep(useconds); return 0; } // lua: handle = clock_new() static int clock_new(lua_State *L) { int handle; // Find free clock for (handle=0; handlename != NULL; l++) { /* fill the table with given functions */ int i; lua_pushstring(L, l->name); for (i = 0; i < nup; i++) /* copy upvalues to the top */ lua_pushvalue(L, -(nup+1)); lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */ lua_settable(L, -(nup + 3)); } lua_pop(L, nup); /* remove upvalues */ } #endif int lua_register_lxi(lua_State *L) { // Register lxi functions lua_getglobal(L, "_G"); luaL_setfuncs(L, lxi_lib, 0); lua_pop(L, 1); load_log_script(L); return 0; } lxi-tools-2.7/src/lxilua.h000066400000000000000000000032211447016333500155560ustar00rootroot00000000000000/* * Copyright (c) 2016-2022 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #pragma once #include #include #include int lua_register_lxi(lua_State *L); lxi-tools-2.7/src/main.c000066400000000000000000000063751447016333500152140ustar00rootroot00000000000000/* * Copyright (c) 2016-2022 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include "options.h" #include "error.h" #include "discover.h" #include "scpi.h" #include "screenshot.h" #include "benchmark.h" #include "run.h" #include int main(int argc, char* argv[]) { int status = EXIT_SUCCESS; double result; // Parse options parse_options(argc, argv); // Initialize LXI library lxi_init(); switch (option.command) { case DISCOVER: if (option.mdns) status = discover(true, option.timeout); else status = discover(false, option.timeout); break; case SCPI: if (option.interactive) status = enter_interactive_mode(option.ip, option.port, option.timeout, option.protocol); else status = scpi(option.ip, option.port, option.timeout, option.protocol, option.scpi_command); break; case SCREENSHOT: screenshot_register_plugins(); if (option.list) { screenshot_list_plugins(); return EXIT_SUCCESS; } status = screenshot(option.ip, option.plugin_name, option.screenshot_filename, option.timeout, true, NULL, NULL, NULL, NULL); break; case BENCHMARK: status = benchmark(option.ip, option.port, option.timeout, option.protocol, option.count, true, &result, NULL); break; case RUN: status = run(option.lua_script_filename, option.timeout); break; } return status; } lxi-tools-2.7/src/meson.build000066400000000000000000000076771447016333500162740ustar00rootroot00000000000000config_h = configuration_data() config_h.set_quoted('PACKAGE_VERSION', meson.project_version()) config_h.set_quoted('GETTEXT_PACKAGE', 'lxi-gui') config_h.set_quoted('LOCALEDIR', join_paths(get_option('prefix'), get_option('localedir'))) config_h.set10('DEVEL_MODE', devel_mode) configure_file(output: 'config.h', configuration: config_h) common_sources = [ 'benchmark.c', 'lxilua.c', 'misc.c', 'screenshot.c', 'plugins/screenshot_keysight-dmm.c', 'plugins/screenshot_rigol-dl3000.c', 'plugins/screenshot_siglent-sdg.c', 'plugins/screenshot_keysight-ivx.c', 'plugins/screenshot_lecroy.c', 'plugins/screenshot_rigol-dm3068.c', 'plugins/screenshot_siglent-sdm3000.c', 'plugins/screenshot_rigol-1000z.c', 'plugins/screenshot_rigol-dp800.c', 'plugins/screenshot_siglent-sds.c', 'plugins/screenshot_rigol-2000.c', 'plugins/screenshot_rigol-dsa.c', 'plugins/screenshot_siglent-ssa3000x.c', 'plugins/screenshot_rigol-dg.c', 'plugins/screenshot_rohde-schwarz-hmo-rtb.c', 'plugins/screenshot_rohde-schwarz-ng.c', 'plugins/screenshot_tektronix.c', 'plugins/screenshot_tektronix-3000.c', 'plugins/screenshot_rohde-schwarz-rth.c', 'plugins/screenshot_tektronix-mso-5.c', ] lxi_sources = [ 'benchmark.c', 'discover.c', 'lxilua.c', 'main.c', 'options.c', 'run.c', 'scpi.c', common_sources, ] foreach name: ['lua-5.4', 'lua-5.3', 'lua-5.2', 'lua-5.1', 'lua'] lua_dep = dependency(name, version: '>=5.1', required: false) if lua_dep.found() break endif endforeach if not lua_dep.found() error('Lua could not be found!') endif compiler = meson.get_compiler('c') lxi_deps = [ compiler.find_library('readline', required: true), dependency('liblxi', version: '>=1.13', required: true), lua_dep, ] executable('lxi', lxi_sources, dependencies: lxi_deps, install: true, ) subdir('bash-completion') enable_gui = get_option('gui') if enable_gui libglib_dep = dependency('glib-2.0', version: '>= 2.70', required: true, fallback : ['glib', 'libglib_dep'], default_options: ['tests=false']) libgtk_dep = dependency('gtk4', version: '>= 4.6.0', required: true, fallback : ['gtk', 'libgtk_dep'], default_options: ['introspection=disabled', 'demos=false', 'build-examples=false', 'build-tests=false']) libgtksourceview_dep = dependency('gtksourceview-5', version: '>= 5.4.0', required: true, fallback : ['gtksourceview', 'gtksource_dep'], default_options: ['introspection=disabled']) libadwaita_dep = dependency('libadwaita-1', version: '>= 1.2', required: true, fallback : ['libadwaita', 'libadwaita_dep'], default_options: ['introspection=disabled', 'examples=false', 'tests=false']) libjson_glib_dep = dependency('json-glib-1.0', version: '>= 1.4', required: true, fallback : ['json-glib', 'json_glib_dep'], default_options: ['introspection=disabled']) lxi_gui_sources = [ 'lxi_gui-main.c', 'lxi_gui-window.c', 'lxi_gui-application.c', 'lxi_gui-prefs.c', 'gtkchart.c', common_sources, ] lxi_gui_deps = [ lxi_deps, libglib_dep, libgtk_dep, libgtksourceview_dep, libadwaita_dep, libjson_glib_dep, ] gnome = import('gnome') lxi_gui_sources += gnome.compile_resources( 'lxi_gui-resources', 'lxi_gui.gresource.xml', c_name: 'lxi_gui', ) executable('lxi-gui', lxi_gui_sources, dependencies: lxi_gui_deps, install: true, ) endif lxi-tools-2.7/src/misc.c000066400000000000000000000046701447016333500152170ustar00rootroot00000000000000/* * Copyright (c) 2016-2022 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include void hex_print(void *data, int length) { char *bufferp; int i; bufferp = data; (void)bufferp; for (i=0; i= 0) { if ( isspace(line[i]) ) line[i] = '\0'; else break; i--; } } int question(const char *string) { int i; for (i = 0; string[i] != '\0'; i++) { if (string[i] == '?') return true; } return false; } lxi-tools-2.7/src/misc.h000066400000000000000000000033301447016333500152140ustar00rootroot00000000000000/* * Copyright (c) 2021-2022 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #pragma once #define UNUSED(expr) do { (void)(expr); } while (0) void hex_print(void *data, int length); void strip_trailing_space(char *line); int question(const char *string); lxi-tools-2.7/src/options.c000066400000000000000000000332331447016333500157540ustar00rootroot00000000000000/* * Copyright (c) 2016-2022 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include "config.h" #include "options.h" #include "error.h" #include // Default timeouts in seconds #define TIMEOUT 3 #define TIMEOUT_SCREENSHOT 10 #define TIMEOUT_DISCOVER 1 #define TIMEOUT_DISCOVER_MDNS 5 #define PORT_VXI11 111 #define PORT_RAW 5025 struct option_t option = { .command = NO_COMMAND, // Default command .timeout = TIMEOUT, // Default timeout in seconds .ip = "", // Default IP address .scpi_command = "", // Default SCPI command .hex = false, // Default no hexadecimal print .interactive = false, // Default no interactive mode .lua_script_filename = "", // Default lua script filename .plugin_name = "", // Default screenshot plugin name .list = false, // Default no list .screenshot_filename = "", // Default screenshot filename .protocol = VXI11, // Default protocol .port = 0, // Default port (set later) .mdns = false, // Default no mDNS discover .count = 100, // Default number of requests in benchmark }; void print_help(char *argv[]) { printf("Usage: %s [--version] [--help] []\n", argv[0]); printf("\n"); printf(" -v, --version Display version\n"); printf(" -h, --help Display help\n"); printf("\n"); printf("Commands:\n"); printf(" discover [] Search for devices\n"); printf(" scpi [] Send SCPI command\n"); printf(" screenshot [] [] Capture screenshot\n"); printf(" benchmark [] Benchmark\n"); printf(" run Run Lua script\n"); printf("\n"); printf("Discover options:\n"); printf(" -t, --timeout Timeout (default: Normal: %d, mDNS: %d)\n", TIMEOUT_DISCOVER, TIMEOUT_DISCOVER_MDNS); printf(" -m, --mdns Search via mDNS/DNS-SD\n"); printf("\n"); printf("Scpi options:\n"); printf(" -a, --address Device IP address\n"); printf(" -p, --port Use port (default: VXI11: %d, RAW: %d)\n", PORT_VXI11, PORT_RAW); printf(" -t, --timeout Timeout (default: %d)\n", option.timeout); printf(" -x, --hex Print response in hexadecimal\n"); printf(" -i, --interactive Enter interactive mode\n"); printf(" -r, --raw Use raw/TCP\n"); printf("\n"); printf("Screenshot options:\n"); printf(" -a, --address Device IP address\n"); printf(" -t, --timeout Timeout (default: %d)\n", TIMEOUT_SCREENSHOT); printf(" -p, --plugin Use screenshot plugin by name\n"); printf(" -l, --list List available screenshot plugins\n"); printf("\n"); printf("Benchmark options:\n"); printf(" -a, --address Device IP address\n"); printf(" -p, --port Use port (default: VXI11: %d, RAW: %d)\n", PORT_VXI11, PORT_RAW); printf(" -t, --timeout Timeout (default: %d)\n", option.timeout); printf(" -c, --count Number of requests (default: %d)\n", option.count); printf(" -r, --raw Use raw/TCP\n"); printf("\n"); } void print_version(void) { printf("lxi v%s\n", PACKAGE_VERSION); } void parse_options(int argc, char *argv[]) { int c; // Print help if no arguments provided if (argc == 1) { print_help(argv); exit(EXIT_SUCCESS); } // getopt_long stores the option index here int option_index = 0; // Skip ahead past command optind = 2; if (strcmp(argv[1], "discover") == 0) { option.command = DISCOVER; static struct option long_options[] = { {"timeout", required_argument, 0, 't'}, {"mdns", no_argument, 0, 'm'}, {0, 0, 0, 0 } }; static bool no_timeout_provided = true; /* Parse discover options */ c = getopt_long(argc, argv, "t:m", long_options, &option_index); while (c != -1) { switch (c) { case 't': option.timeout = atoi(optarg); no_timeout_provided = false; break; case 'm': option.mdns = true; break; case '?': exit(EXIT_FAILURE); } c = getopt_long(argc, argv, "t:m", long_options, &option_index); } // Set discover timeout if none provided if (no_timeout_provided) { if (option.mdns) option.timeout = TIMEOUT_DISCOVER_MDNS; else option.timeout = TIMEOUT_DISCOVER; } } else if (strcmp(argv[1], "scpi") == 0) { option.command = SCPI; static struct option long_options[] = { {"address", required_argument, 0, 'a'}, {"port", required_argument, 0, 'p'}, {"timeout", required_argument, 0, 't'}, {"hex", no_argument, 0, 'x'}, {"interactive", no_argument, 0, 'i'}, {"raw", no_argument, 0, 'r'}, {0, 0, 0, 0 } }; do { /* Parse scpi options */ c = getopt_long(argc, argv, "a:p:t:xir", long_options, &option_index); switch (c) { case 'a': strncpy(option.ip, optarg, 499); break; case 'p': option.port = atoi(optarg); break; case 't': option.timeout = atoi(optarg); break; case 'x': option.hex = true; break; case 'i': option.interactive = true; break; case 'r': option.protocol = RAW; break; case '?': exit(EXIT_FAILURE); } } while (c != -1); } else if (strcmp(argv[1], "screenshot") == 0) { option.command = SCREENSHOT; // Set default timeout for screenshots option.timeout = TIMEOUT_SCREENSHOT; static struct option long_options[] = { {"address", required_argument, 0, 'a'}, {"timeout", required_argument, 0, 't'}, {"plugin", required_argument, 0, 'p'}, {"list", no_argument, 0, 'l'}, {0, 0, 0, 0 } }; do { /* Parse screenshot options */ c = getopt_long(argc, argv, "a:t:p:l", long_options, &option_index); switch (c) { case 'a': strncpy(option.ip, optarg, 499); break; case 't': option.timeout = atoi(optarg); break; case 'p': option.plugin_name = optarg; break; case 'l': option.list = true; break; case '?': exit(EXIT_FAILURE); } } while (c != -1); } else if (strcmp(argv[1], "benchmark") == 0) { option.command = BENCHMARK; static struct option long_options[] = { {"address", required_argument, 0, 'a'}, {"port", required_argument, 0, 'p'}, {"timeout", required_argument, 0, 't'}, {"count", required_argument, 0, 'c'}, {"raw", no_argument, 0, 'r'}, {0, 0, 0, 0 } }; do { /* Parse benchmark options */ c = getopt_long(argc, argv, "a:p:t:rc:", long_options, &option_index); switch (c) { case 'a': strncpy(option.ip, optarg, 499); break; case 'p': option.port = atoi(optarg); break; case 't': option.timeout = atoi(optarg); break; case 'c': option.count = atoi(optarg); break; case 'r': option.protocol = RAW; break; case '?': exit(EXIT_FAILURE); } } while (c != -1); } else if (strcmp(argv[1], "run") == 0) { option.command = RUN; static struct option long_options[] = { {"timeout", required_argument, 0, 't'}, {0, 0, 0, 0 } }; do { /* Parse run options */ c = getopt_long(argc, argv, "t:", long_options, &option_index); switch (c) { case 't': option.timeout = atoi(optarg); break; case '?': exit(EXIT_FAILURE); } } while (c != -1); } else { // No command provided so we restore index optind = 1; static struct option long_options[] = { {"version", no_argument, 0, 'v'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0 } }; do { /* Parse options */ c = getopt_long(argc, argv, "vh", long_options, &option_index); switch (c) { case 'v': print_version(); exit(EXIT_SUCCESS); case 'h': print_help(argv); exit(EXIT_SUCCESS); case '?': exit(EXIT_FAILURE); } } while (c != -1); } if ((option.command == NO_COMMAND) && (optind != argc)) { error_printf("Unknown command\n"); exit(EXIT_FAILURE); } if (option.command == SCPI) { if (optind != argc) strncpy(option.scpi_command, argv[optind++], 499); if (strlen(option.ip) == 0) { error_printf("No IP address specified\n"); exit(EXIT_FAILURE); } if ((strlen(option.scpi_command) == 0) && (option.interactive == false)) { error_printf("No SCPI command specified\n"); exit(EXIT_FAILURE); } } if ((option.command == SCREENSHOT) && (optind != argc)) { strncpy(option.screenshot_filename, argv[optind++], 999); } if ((option.command == RUN) && (optind != argc)) { strncpy(option.lua_script_filename, argv[optind++], 999); } /* Print any unknown arguments */ if (optind < argc) { error_printf("Unknown arguments: "); while (optind < argc) fprintf(stderr, "%s ", argv[optind++]); fprintf(stderr, "\n"); exit(EXIT_FAILURE); } /* Configure port */ if (option.port == 0) { // See http://www.lxistandard.org/About/LXI-Protocols.aspx if (option.protocol == RAW) option.port = PORT_RAW; // Default TCP/RAW port else option.port = PORT_VXI11; // Default TCP/VXI11 port } // Convert timeout from seconds to milliseconds option.timeout = option.timeout * 1000; } lxi-tools-2.7/src/options.h000066400000000000000000000041571447016333500157640ustar00rootroot00000000000000/* * Copyright (c) 2016-2022 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #pragma once #include #include #include /* Options */ struct option_t { int command; int timeout; char ip[500]; char scpi_command[500]; bool hex; bool interactive; char lua_script_filename[1000]; char *plugin_name; bool list; char screenshot_filename[1000]; lxi_protocol_t protocol; int port; bool mdns; int count; }; enum command_t { DISCOVER, SCPI, SCREENSHOT, BENCHMARK, RUN, NO_COMMAND }; extern struct option_t option; void parse_options(int argc, char *argv[]); lxi-tools-2.7/src/plugins/000077500000000000000000000000001447016333500155725ustar00rootroot00000000000000lxi-tools-2.7/src/plugins/screenshot_keysight-dmm.c000066400000000000000000000064761447016333500226120ustar00rootroot00000000000000/* * Copyright (c) 2017-2018 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "error.h" #include "screenshot.h" #define IMAGE_SIZE_MAX 0x400000 // 4 MB int keysight_dmm_screenshot(char *address, char *id, int timeout) { char* response = malloc(IMAGE_SIZE_MAX); char *command, *image; int device, length, n; char c; UNUSED(id); // Connect to LXI instrument device = lxi_connect(address, 0, NULL, timeout, VXI11); if (device == LXI_ERROR) { error_printf("Failed to connect\n"); goto error_connect; } // Send SCPI commands to grab image command = "HCOP:SDUM:DATA:FORM BMP"; lxi_send(device, command, strlen(command), timeout); command = "HCOP:SDUM:DATA?"; lxi_send(device, command, strlen(command), timeout); length = lxi_receive(device, response, IMAGE_SIZE_MAX, timeout); if (length < 0) { error_printf("Failed to receive message\n"); goto error_receive; } // Strip IEEE 488.2 Data Block header c = response[1]; n = atoi(&c); image = &response[0]; image += n+2; length -= n+2; // Strip ending newline length--; // Dump remaining image data to file screenshot_file_dump(image, length, "bmp"); // Free allocated memory for screenshot free(response); // Disconnect lxi_disconnect(device); return 0; error_connect: error_receive: // Free allocated memory for screenshot free(response); return 1; } // Screenshot plugin configuration struct screenshot_plugin keysight_dmm = { .name = "keysight-dmm", .description = "Keysight Truevolt Digital Multimeter", .regex = "Agilent Keysight Technologies 34...A", .screenshot = keysight_dmm_screenshot }; lxi-tools-2.7/src/plugins/screenshot_keysight-ivx.c000066400000000000000000000065461447016333500226410ustar00rootroot00000000000000/* * Copyright (c) 2017 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "error.h" #include "screenshot.h" #define IMAGE_SIZE_MAX 0x400000 // 4 MB int keysight_ivx_screenshot(char *address, char *id, int timeout) { char* response = malloc(IMAGE_SIZE_MAX); char *command, *image; int device, length, n; char c; UNUSED(id); // Connect to LXI instrument device = lxi_connect(address, 0, NULL, timeout, VXI11); if (device == LXI_ERROR) { error_printf("Failed to connect\n"); goto error_connect; } // Send SCPI commands to grab image command = ":hardcopy:inksaver off"; lxi_send(device, command, strlen(command), timeout); command = ":display:data? BMP, color"; lxi_send(device, command, strlen(command), timeout); length = lxi_receive(device, response, IMAGE_SIZE_MAX, timeout); if (length < 0) { error_printf("Failed to receive message\n"); goto error_receive; } // Strip IEEE 488.2 Data Block header c = response[1]; n = atoi(&c); image = &response[0]; image += n+2; length -= n+2; // Strip ending newline length--; // Dump remaining image data to file screenshot_file_dump(image, length, "bmp"); // Free allocated memory for screenshot free(response); // Disconnect lxi_disconnect(device); return 0; error_connect: error_receive: // Free allocated memory for screenshot free(response); return 1; } // Screenshot plugin configuration struct screenshot_plugin keysight_ivx = { .name = "keysight-ivx", .description = "Keysight InfiniiVision 2000X/3000X series oscilloscope", .regex = "AGILENT KEYSIGHT TECHNOLOGIES [MD]SO-X.[23]...", .screenshot = keysight_ivx_screenshot }; lxi-tools-2.7/src/plugins/screenshot_lecroy.c000066400000000000000000000123311447016333500214700ustar00rootroot00000000000000/* * Copyright (c) 2022 Perry Hung * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "error.h" #include "screenshot.h" #define IMAGE_SIZE_MAX 0x400000 // 4 MB #define MIN_TRANSFER_SIZE 32 // Poll until the SCDP bit is clear static int scdp_status_wait(int device, int timeout) { char *command; char response[6]; for (unsigned retry = 0; retry < 5; retry++) { command = "INR?"; lxi_send(device, command, strlen(command), timeout); int rc = lxi_receive(device, response, MIN_TRANSFER_SIZE, timeout); if (rc < (int)sizeof(response)) { printf("INR? receive failed\n"); return 1; } // Parse the mask, screendump is bit 2 unsigned long state = strtoul(&response[4], NULL, 10); if (state & 2) { return 0; } } return 1; } int lecroy_screenshot(char *address, char *id, int timeout) { UNUSED(id); char* response; response = malloc(IMAGE_SIZE_MAX); if (!response) { error_printf("Memory allocation failed\n"); return 1; } int device = lxi_connect(address, 0, NULL, timeout, VXI11); if (device == LXI_ERROR) { error_printf("Failed to connect\n"); goto error_connect; } // Clear status registers and enable screen dump mask bit, then do a read to // clear any pending bits char * command = "*CLS"; lxi_send(device, command, strlen(command), timeout); command = "INE 2"; lxi_send(device, command, strlen(command), timeout); scdp_status_wait(device, timeout); // Delete any existing file, if any. This ensures that the autoincrementing // suffix counter is reset to zero. command = "DELF DISK,HDD,FILE,'D:\\HardCopy\\lxi-screenshot--00000.png'"; lxi_send(device, command, strlen(command), timeout); // Set hardcopy to dump PNGs to a file command = "HCSU DEV,png,DEST,FILE,DIR,'D:\\HardCopy\',AREA,FULLSCREEN,FILE,'lxi-screenshot'"; lxi_send(device, command, strlen(command), timeout); // Trigger screendump command = "SCDP"; lxi_send(device, command, strlen(command), timeout); if (scdp_status_wait(device, timeout)) { printf("screendump bit not set?\n"); } // Read it back command = "TRFL? DISK,HDD,FILE,'D:\\HardCopy\\lxi-screenshot--00000.png'"; lxi_send(device, command, strlen(command), timeout); int length = lxi_receive(device, response, IMAGE_SIZE_MAX, timeout); if (length < MIN_TRANSFER_SIZE) { error_printf("receive error: %d\n", length); goto error_receive; } // Skip 'TRFL? #' length -= 6; // Parse the digit and skip IEEE header char digit = response[6]; char *image = &response[7]; switch (digit) { case '0' ... '9': { size_t n = digit - '0'; image += n; length -= n; break; } default: break; } // Strip 8 byte CRC footer and 2 byte terminator length -= 10; if (length < 0 || length >= IMAGE_SIZE_MAX) { error_printf("Invalid message\n"); goto error_receive; } screenshot_file_dump(image, length, "png"); free(response); lxi_disconnect(device); return 0; error_receive: lxi_disconnect(device); error_connect: free(response); return 1; } // Screenshot plugin configuration struct screenshot_plugin lecroy = { .name = "lecroy-wp", .description = "LeCroy WavePro Oscilloscope", .regex = "LECROY WP LCRY", .screenshot = lecroy_screenshot }; lxi-tools-2.7/src/plugins/screenshot_rigol-1000z.c000066400000000000000000000063051447016333500220630ustar00rootroot00000000000000/* * Copyright (c) 2017 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "error.h" #include "screenshot.h" #define IMAGE_SIZE_MAX 0x400000 // 4 MB int rigol_1000z_screenshot(char *address, char *id, int timeout) { char* response = malloc(IMAGE_SIZE_MAX); char *command, *image; int device, length, n; char c; UNUSED(id); // Connect to LXI instrument device = lxi_connect(address, 0, NULL, timeout, VXI11); if (device == LXI_ERROR) { error_printf("Failed to connect\n"); goto error_connect; } // Send SCPI command to grab PNG image command = "display:data? on,0,png"; lxi_send(device, command, strlen(command), timeout); length = lxi_receive(device, response, IMAGE_SIZE_MAX, timeout); if (length < 0) { error_printf("Failed to receive message\n"); goto error_receive; } // Strip TMC block header c = response[1]; n = atoi(&c); image = &response[0]; image += n+2; length -= n+2; // Dump remaining PNG image data to file screenshot_file_dump(image, length, "png"); // Free allocated memory for screenshot free(response); // Disconnect lxi_disconnect(device); return 0; error_connect: error_receive: // Free allocated memory for screenshot free(response); return 1; } // Screenshot plugin configuration struct screenshot_plugin rigol_1000z = { .name = "rigol-1000z", .description = "Rigol DS/MSO 1000Z series oscilloscope", .regex = "RIGOL TECHNOLOGIES Rigol Technologies DS1...Z MSO1...Z", .screenshot = rigol_1000z_screenshot }; lxi-tools-2.7/src/plugins/screenshot_rigol-2000.c000066400000000000000000000063721447016333500216760ustar00rootroot00000000000000/* * Copyright (c) 2017 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "error.h" #include "screenshot.h" #define IMAGE_SIZE_MAX 0x400000 // 4 MB int rigol_2000_screenshot(char *address, char *id, int timeout) { char* response = malloc(IMAGE_SIZE_MAX); char *command, *image; int device, length, n; char c; UNUSED(id); // Connect to LXI instrument device = lxi_connect(address, 0, NULL, timeout, VXI11); if (device == LXI_ERROR) { error_printf("Failed to connect\n"); goto error_connect; } // Send SCPI command to grab BMP image command = ":display:data?"; lxi_send(device, command, strlen(command), timeout); length = lxi_receive(device, response, IMAGE_SIZE_MAX, timeout); if (length < 0) { error_printf("Failed to receive message\n"); goto error_receive; } // Strip TMC block header c = response[1]; n = atoi(&c); image = &response[0]; image += n+2; length -= n+2; // Strip ending newline length--; // Dump remaining BMP image data to file screenshot_file_dump(image, length, "bmp"); // Free allocated memory for screenshot free(response); // Disconnect lxi_disconnect(device); return 0; error_connect: error_receive: // Free allocated memory for screenshot free(response); return 1; } // Screenshot plugin configuration struct screenshot_plugin rigol_2000 = { .name = "rigol-2000", .description = "Rigol DS/MSO 2000/4000/5000 series oscilloscope", .regex = "RIGOL TECHNOLOGIES Rigol Technologies DS2... MSO2... DS4... MSO4... MSO5...", .screenshot = rigol_2000_screenshot }; lxi-tools-2.7/src/plugins/screenshot_rigol-dg.c000066400000000000000000000064431447016333500217060ustar00rootroot00000000000000/* * Copyright (c) 2017 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "error.h" #include "screenshot.h" #define IMAGE_SIZE_MAX 0x400000 // 4 MB int rigol_dg_screenshot(char *address, char *id, int timeout) { char* response = malloc(IMAGE_SIZE_MAX); char *command, *image; int device, length, n; char c; UNUSED(id); // Connect to LXI instrument device = lxi_connect(address, 0, NULL, timeout, VXI11); if (device == LXI_ERROR) { error_printf("Failed to connect\n"); goto error_connect; } // Send SCPI command to grab BMP image command = ":HCOPy:SDUMp:DATA:FORMat BMP"; lxi_send(device, command, strlen(command), timeout); command = ":HCOPy:SDUMp:DATA?"; lxi_send(device, command, strlen(command), timeout); length = lxi_receive(device, response, IMAGE_SIZE_MAX, timeout); if (length < 0) { error_printf("Failed to receive message\n"); goto error_receive; } // Strip TMC block header c = response[1]; n = atoi(&c); image = &response[0]; image += n+2; length -= n+2; // Dump remaining BMP image data to file screenshot_file_dump(image, length, "bmp"); // Free allocated memory for screenshot free(response); // Disconnect lxi_disconnect(device); return 0; error_connect: error_receive: // Free allocated memory for screenshot free(response); return 1; } // Screenshot plugin configuration struct screenshot_plugin rigol_dg = { .name = "rigol-dg", .description = "Rigol DG 4000 & 1000Z series function generator", .regex = "RIGOL TECHNOLOGIES Rigol Technologies DG4... DG1...Z", .screenshot = rigol_dg_screenshot }; lxi-tools-2.7/src/plugins/screenshot_rigol-dl3000.c000066400000000000000000000063271447016333500222170ustar00rootroot00000000000000/* * Copyright (c) 2017 Martin Lund, 2020 Heiko Jakob * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "error.h" #include "screenshot.h" #define IMAGE_SIZE_MAX 0x400000 // 4 MB int rigol_dl3000_screenshot(char *address, char *id, int timeout) { char* response = malloc(IMAGE_SIZE_MAX); char *command, *image; int device, length, n; char c; UNUSED(id); // Connect to LXI instrument device = lxi_connect(address, 0, NULL, timeout, VXI11); if (device == LXI_ERROR) { error_printf("Failed to connect\n"); goto error_connect; } // Send SCPI command to grab BMP image command = ":PROJ:WND:DATA?"; lxi_send(device, command, strlen(command), timeout); length = lxi_receive(device, response, IMAGE_SIZE_MAX, timeout); if (length < 0) { error_printf("Failed to receive message\n"); goto error_receive; } // Strip TMC block header c = response[1]; n = atoi(&c); image = &response[0]; image += n+2; length -= n+2; // Dump remaining BMP image data to file screenshot_file_dump(image, length, "bmp"); // Free allocated memory for screenshot free(response); // Disconnect lxi_disconnect(device); return 0; error_connect: error_receive: // Free allocated memory for screenshot free(response); return 1; } // Screenshot plugin configuration struct screenshot_plugin rigol_dl3000 = { .name = "rigol-dl3000", .description = "Rigol DL3000 Series Programmable DC Electronic Load", .regex = "RIGOL TECHNOLOGIES Rigol Technologies DL30..", .screenshot = rigol_dl3000_screenshot }; lxi-tools-2.7/src/plugins/screenshot_rigol-dm3068.c000066400000000000000000000062521447016333500222330ustar00rootroot00000000000000/* * Copyright (c) 2017 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "error.h" #include "screenshot.h" #define IMAGE_SIZE_MAX 0x400000 // 4 MB int rigol_dm3068_screenshot(char *address, char *id, int timeout) { char* response = malloc(IMAGE_SIZE_MAX); char *command, *image; int device, length, n; char c; UNUSED(id); // Connect to LXI instrument device = lxi_connect(address, 0, NULL, timeout, VXI11); if (device == LXI_ERROR) { error_printf("Failed to connect\n"); goto error_connect; } // Send SCPI command to grab BMP image command = ":DISP:DATA?"; lxi_send(device, command, strlen(command), timeout); length = lxi_receive(device, response, IMAGE_SIZE_MAX, timeout); if (length < 0) { error_printf("Failed to receive message\n"); goto error_receive; } // Strip TMC block header c = response[1]; n = atoi(&c); image = &response[0]; image += n+2; length -= n+2; // Dump remaining BMP image data to file screenshot_file_dump(image, length, "bmp"); // Free allocated memory for screenshot free(response); // Disconnect lxi_disconnect(device); return 0; error_connect: error_receive: // Free allocated memory for screenshot free(response); return 1; } // Screenshot plugin configuration struct screenshot_plugin rigol_dm3068 = { .name = "rigol-dm3068", .description = "Rigol DM 3068 digital multimeter", .regex = "RIGOL TECHNOLOGIES Rigol Technologies DM3068", .screenshot = rigol_dm3068_screenshot }; lxi-tools-2.7/src/plugins/screenshot_rigol-dp800.c000066400000000000000000000062541447016333500221470ustar00rootroot00000000000000/* * Copyright (c) 2017 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "error.h" #include "screenshot.h" #define IMAGE_SIZE_MAX 0x400000 // 4 MB int rigol_dp800_screenshot(char *address, char *id, int timeout) { char* response = malloc(IMAGE_SIZE_MAX); char *command, *image; int device, length, n; char c; UNUSED(id); // Connect to LXI instrument device = lxi_connect(address, 0, NULL, timeout, VXI11); if (device == LXI_ERROR) { error_printf("Failed to connect\n"); goto error_connect; } // Send SCPI command to grab BMP image command = ":SYSTem:PRINT? BMP"; lxi_send(device, command, strlen(command), timeout); length = lxi_receive(device, response, IMAGE_SIZE_MAX, timeout); if (length < 0) { error_printf("Failed to receive message\n"); goto error_receive; } // Strip TMC block header c = response[1]; n = atoi(&c); image = &response[0]; image += n+2; length -= n+2; // Dump remaining BMP image data to file screenshot_file_dump(image, length, "bmp"); // Free allocated memory for screenshot free(response); // Disconnect lxi_disconnect(device); return 0; error_connect: error_receive: // Free allocated memory for screenshot free(response); return 1; } // Screenshot plugin configuration struct screenshot_plugin rigol_dp800 = { .name = "rigol-dp800", .description = "Rigol DP 800 series power supply", .regex = "RIGOL TECHNOLOGIES Rigol Technologies DP8..", .screenshot = rigol_dp800_screenshot }; lxi-tools-2.7/src/plugins/screenshot_rigol-dsa.c000066400000000000000000000062531447016333500220620ustar00rootroot00000000000000/* * Copyright (c) 2017 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "error.h" #include "screenshot.h" #define IMAGE_SIZE_MAX 0x400000 // 4 MB int rigol_dsa_screenshot(char *address, char *id, int timeout) { char* response = malloc(IMAGE_SIZE_MAX); char *command, *image; int device, length, n; char c; UNUSED(id); // Connect to LXI instrument device = lxi_connect(address, 0, NULL, timeout, VXI11); if (device == LXI_ERROR) { error_printf("Failed to connect\n"); goto error_connect; } // Send SCPI command to grab BMP image command = ":PRIV:SNAP? BMP"; lxi_send(device, command, strlen(command), timeout); length = lxi_receive(device, response, IMAGE_SIZE_MAX, timeout); if (length < 0) { error_printf("Failed to receive message\n"); goto error_receive; } // Strip TMC block header c = response[1]; n = atoi(&c); image = &response[0]; image += n+2; length -= n+2; // Dump remaining BMP image data to file screenshot_file_dump(image, length, "bmp"); // Free allocated memory for screenshot free(response); // Disconnect lxi_disconnect(device); return 0; error_connect: error_receive: // Free allocated memory for screenshot free(response); return 1; } // Screenshot plugin configuration struct screenshot_plugin rigol_dsa = { .name = "rigol-dsa", .description = "Rigol DSA 700/800 series spectrum analyzer", .regex = "RIGOL TECHNOLOGIES Rigol Technologies DSA[78]..", .screenshot = rigol_dsa_screenshot }; lxi-tools-2.7/src/plugins/screenshot_rohde-schwarz-hmo-rtb.c000066400000000000000000000066451447016333500243340ustar00rootroot00000000000000/* * Copyright (c) 2017 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "error.h" #include "screenshot.h" #define IMAGE_SIZE_MAX 0x100000 * 20 // 20 MB int rs_hmo_rtb_screenshot(char *address, char *id, int timeout) { char *command, *image; int device, length, n; char c; UNUSED(id); // Prepare response buffer char* response = malloc(IMAGE_SIZE_MAX); if (response == NULL) { error_printf("Failed to allocate response buffer\n"); return 1; } // Connect to LXI instrument device = lxi_connect(address, 0, NULL, timeout, VXI11); if (device == LXI_ERROR) { error_printf("Failed to connect\n"); goto error_connect; } // Send SCPI commands to grab image command = "HCOPy:FORMat PNG"; lxi_send(device, command, strlen(command), timeout); command = "HCOPy:DATA?"; lxi_send(device, command, strlen(command), timeout); length = lxi_receive(device, response, IMAGE_SIZE_MAX, timeout); if (length < 0) { error_printf("Failed to receive message\n"); goto error_receive; } // Strip header c = response[1]; n = atoi(&c); image = &response[0]; image += n+2; length -= n+2; // Dump remaining image data to file screenshot_file_dump(image, length, "png"); // Free allocated memory for screenshot free(response); // Disconnect lxi_disconnect(device); return 0; error_connect: error_receive: // Free allocated memory for screenshot free(response); return 1; } // Screenshot plugin configuration struct screenshot_plugin rs_hmo_rtb = { .name = "rs-hmo-rtb", .description = "Rohde & Schwarz HMO 1000/2000/3000 / RTB 2000 series oscilloscope", .regex = "Rohde&Schwarz HAMEG HMO[123]... RTB2...", .screenshot = rs_hmo_rtb_screenshot }; lxi-tools-2.7/src/plugins/screenshot_rohde-schwarz-ng.c000066400000000000000000000064671447016333500233720ustar00rootroot00000000000000/* * Copyright (c) 2017 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "error.h" #include "screenshot.h" #define IMAGE_SIZE_MAX 0x100000 * 20 // 20 MB int rs_ng_screenshot(char *address, char *id, int timeout) { char *command, *image; int device, length, n; char c; UNUSED(id); // Prepare response buffer char* response = malloc(IMAGE_SIZE_MAX); if (response == NULL) { error_printf("Failed to allocate response buffer\n"); return 1; } // Connect to LXI instrument device = lxi_connect(address, 0, NULL, timeout, VXI11); if (device == LXI_ERROR) { error_printf("Failed to connect\n"); goto error_connect; } // Send SCPI commands to grab image (device only supports PNG) command = "HCOPy:DATA?"; lxi_send(device, command, strlen(command), timeout); length = lxi_receive(device, response, IMAGE_SIZE_MAX, timeout); if (length < 0) { error_printf("Failed to receive message\n"); goto error_receive; } // Strip header c = response[1]; n = atoi(&c); image = &response[0]; image += n+2; length -= n+2; // Dump remaining image data to file screenshot_file_dump(image, length, "png"); // Free allocated memory for screenshot free(response); // Disconnect lxi_disconnect(device); return 0; error_connect: error_receive: // Free allocated memory for screenshot free(response); return 1; } // Screenshot plugin configuration struct screenshot_plugin rs_ng = { .name = "rs-ng", .description = "Rohde & Schwarz NGL200/NGM200 series power supplies", .regex = "Rohde&Schwarz NGM2.. NGL2..", .screenshot = rs_ng_screenshot }; lxi-tools-2.7/src/plugins/screenshot_rohde-schwarz-rth.c000066400000000000000000000074021447016333500235510ustar00rootroot00000000000000/* * Copyright (c) 2023 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "error.h" #include "screenshot.h" #define IMAGE_SIZE_MAX 0x100000 * 20 // 20 MB int rs_rth_screenshot(char *address, char *id, int timeout) { char *command, *image; int device, length, n; char c; UNUSED(id); // Prepare response buffer char* response = malloc(IMAGE_SIZE_MAX); if (response == NULL) { error_printf("Failed to allocate response buffer\n"); return 1; } // Connect to LXI instrument device = lxi_connect(address, 0, NULL, timeout, VXI11); if (device == LXI_ERROR) { error_printf("Failed to connect\n"); goto error_connect; } // Send SCPI commands to grab image command = ":HCOPy:LANGuage PNG"; lxi_send(device, command, strlen(command), timeout); command = ":MMEMory:NAME '/media/SD/lxi-tools-screenshot.png'"; lxi_send(device, command, strlen(command), timeout); command = ":HCOPy:IMMediate;*OPC"; lxi_send(device, command, strlen(command), timeout); command = ":MMEMory:DATA? '/media/SD/lxi-tools-screenshot.png'"; lxi_send(device, command, strlen(command), timeout); length = lxi_receive(device, response, IMAGE_SIZE_MAX, timeout); if (length < 0) { error_printf("Failed to receive message\n"); goto error_receive; } // Cleanup command = ":MMEMory:DELete '/media/SD/lxi-tools-screenshot.png';*OPC"; lxi_send(device, command, strlen(command), timeout); // Strip header c = response[1]; n = atoi(&c); image = &response[0]; image += n+2; length -= n+2; // Dump remaining image data to file screenshot_file_dump(image, length, "png"); // Free allocated memory for screenshot free(response); // Disconnect lxi_disconnect(device); return 0; error_connect: error_receive: // Free allocated memory for screenshot free(response); return 1; } // Screenshot plugin configuration struct screenshot_plugin rs_rth = { .name = "rs-rth", .description = "Rohde & Schwarz RTH 1000 series oscilloscope", .regex = "Rohde&Schwarz RTH", .screenshot = rs_rth_screenshot }; lxi-tools-2.7/src/plugins/screenshot_siglent-sdg.c000066400000000000000000000060451447016333500224200ustar00rootroot00000000000000/* * Copyright (c) 2017 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "error.h" #include "screenshot.h" #define IMAGE_SIZE_MAX 0x400000 // 4 MB int siglent_sdg_screenshot(char *address, char *id, int timeout) { char* response = malloc(IMAGE_SIZE_MAX); char *command; int device, length; UNUSED(id); // Connect to LXI instrument device = lxi_connect(address, 0, NULL, timeout, VXI11); if (device == LXI_ERROR) { error_printf("Failed to connect\n"); goto error_connect; } // Send SCPI command to grab BMP image command = "scdp"; lxi_send(device, command, strlen(command), timeout); length = lxi_receive(device, response, IMAGE_SIZE_MAX, timeout); if (length < 0) { error_printf("Failed to receive message\n"); goto error_receive; } // Dump received BMP image data to file screenshot_file_dump(response, length, "bmp"); // Free allocated memory for screenshot free(response); // Disconnect lxi_disconnect(device); return 0; error_connect: error_receive: // Free allocated memory for screenshot free(response); return 1; } // Screenshot plugin configuration struct screenshot_plugin siglent_sdg = { .name = "siglent-sdg", .description = "Siglent SDG 1000X/2000X/6000X series waveform generator", .regex = "SIGLENT TECHNOLOGIES Siglent Technologies SDG[126]...", .screenshot = siglent_sdg_screenshot }; lxi-tools-2.7/src/plugins/screenshot_siglent-sdm3000.c000066400000000000000000000060521447016333500227270ustar00rootroot00000000000000/* * Copyright (c) 2017 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "error.h" #include "screenshot.h" #define IMAGE_SIZE_MAX 0x400000 // 4 MB int siglent_sdm3000_screenshot(char *address, char *id, int timeout) { char* response = malloc(IMAGE_SIZE_MAX); char *command; int device, length; UNUSED(id); // Connect to LXI instrument device = lxi_connect(address, 0, NULL, timeout, VXI11); if (device == LXI_ERROR) { error_printf("Failed to connect\n"); goto error_connect; } // Send SCPI command to grab BMP image command = "scdp"; lxi_send(device, command, strlen(command), timeout); length = lxi_receive(device, response, IMAGE_SIZE_MAX, timeout); if (length < 0) { error_printf("Failed to receive message\n"); goto error_receive; } // Dump received BMP image data to file screenshot_file_dump(response, length, "bmp"); // Free allocated memory for screenshot free(response); // Disconnect lxi_disconnect(device); return 0; error_connect: error_receive: // Free allocated memory for screenshot free(response); return 1; } // Screenshot plugin configuration struct screenshot_plugin siglent_sdm3000 = { .name = "siglent-sdm3000", .description = "Siglent SDM 3000/3000X series digital multimeter", .regex = "SIGLENT TECHNOLOGIES Siglent Technologies SDM3...", .screenshot = siglent_sdm3000_screenshot }; lxi-tools-2.7/src/plugins/screenshot_siglent-sds.c000066400000000000000000000060341447016333500224320ustar00rootroot00000000000000/* * Copyright (c) 2017 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "error.h" #include "screenshot.h" #define IMAGE_SIZE_MAX 0x400000 // 4 MB int siglent_sds_screenshot(char *address, char *id, int timeout) { char* response = malloc(IMAGE_SIZE_MAX); char *command; int device, length; UNUSED(id); // Connect to LXI instrument device = lxi_connect(address, 0, NULL, timeout, VXI11); if (device == LXI_ERROR) { error_printf("Failed to connect\n"); goto error_connect; } // Send SCPI command to grab BMP image command = "scdp"; lxi_send(device, command, strlen(command), timeout); length = lxi_receive(device, response, IMAGE_SIZE_MAX, timeout); if (length < 0) { error_printf("Failed to receive message\n"); goto error_receive; } // Dump received BMP image data to file screenshot_file_dump(response, length, "bmp"); // Free allocated memory for screenshot free(response); // Disconnect lxi_disconnect(device); return 0; error_connect: error_receive: // Free allocated memory for screenshot free(response); return 1; } // Screenshot plugin configuration struct screenshot_plugin siglent_sds = { .name = "siglent-sds", .description = "Siglent SDS 1000X/2000X series oscilloscope", .regex = "SIGLENT TECHNOLOGIES Siglent Technologies SDS[12]...", .screenshot = siglent_sds_screenshot }; lxi-tools-2.7/src/plugins/screenshot_siglent-ssa3000x.c000066400000000000000000000060511447016333500231210ustar00rootroot00000000000000/* * Copyright (c) 2017 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "error.h" #include "screenshot.h" #define IMAGE_SIZE_MAX 0x400000 // 4 MB int siglent_ssa3000x_screenshot(char *address, char *id, int timeout) { char* response = malloc(IMAGE_SIZE_MAX); char *command; int device, length; UNUSED(id); // Connect to LXI instrument device = lxi_connect(address, 0, NULL, timeout, VXI11); if (device == LXI_ERROR) { error_printf("Failed to connect\n"); goto error_connect; } // Send SCPI command to grab BMP image command = "scdp"; lxi_send(device, command, strlen(command), timeout); length = lxi_receive(device, response, IMAGE_SIZE_MAX, timeout); if (length < 0) { error_printf("Failed to receive message\n"); goto error_receive; } // Dump received BMP image data to file screenshot_file_dump(response, length, "bmp"); // Free allocated memory for screenshot free(response); // Disconnect lxi_disconnect(device); return 0; error_connect: error_receive: // Free allocated memory for screenshot free(response); return 1; } // Screenshot plugin configuration struct screenshot_plugin siglent_ssa3000x = { .name = "siglent-ssa3000x", .description = "Siglent SSA 3000X series spectrum analyzer", .regex = "SIGLENT TECHNOLOGIES Siglent Technologies SSA3...X", .screenshot = siglent_ssa3000x_screenshot }; lxi-tools-2.7/src/plugins/screenshot_tektronix-3000.c000066400000000000000000000126311447016333500226050ustar00rootroot00000000000000/* * Copyright (c) 2019 Sam harry Tzavaras * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "error.h" #include "screenshot.h" #define IMAGE_SIZE_MAX 308278 // 302KB #define PARAM_STR_SIZE 10 typedef struct{ char Header[PARAM_STR_SIZE]; char Format[PARAM_STR_SIZE]; char Compression[PARAM_STR_SIZE]; char Layout[PARAM_STR_SIZE]; char Port[PARAM_STR_SIZE]; }restore; void length_check(int length); int tektronix_screenshot_3000(char *address, char *id, int timeout) { restore param; char* response = malloc(IMAGE_SIZE_MAX); int length, device; char *command, command_str[100]; UNUSED(id); // Connect to LXI instrument device = lxi_connect(address, 0, NULL, timeout, VXI11); if (device == LXI_ERROR) { error_printf("Failed to connect\n"); goto error_connect; } // Check the device command = "*IDN?"; lxi_send(device, command, strlen(command), timeout); length_check(lxi_receive(device, response, IMAGE_SIZE_MAX, timeout)); if (strstr(response,"TDS 3") != NULL) { // Send SCPI commands to grab current image parameters and config for grab image command = "hardcopy:Format?"; lxi_send(device, command, strlen(command), timeout); length_check(lxi_receive(device, param.Format, IMAGE_SIZE_MAX, timeout)); command = "hardcopy:Format bmpc"; lxi_send(device, command, strlen(command), timeout); command = "hardcopy:compression?"; lxi_send(device, command, strlen(command), timeout); length_check(lxi_receive(device, param.Compression, IMAGE_SIZE_MAX, timeout)); command = "hardcopy:compression off"; lxi_send(device, command, strlen(command), timeout); command = "hardcopy:layout?"; lxi_send(device, command, strlen(command), timeout); length_check(lxi_receive(device, param.Layout, IMAGE_SIZE_MAX, timeout)); command = "hardcopy:layout Portrait"; lxi_send(device, command, strlen(command), timeout); command = "hardcopy:Port?"; lxi_send(device, command, strlen(command), timeout); length_check(lxi_receive(device, param.Port, IMAGE_SIZE_MAX, timeout)); command = "hardcopy:Port gpib"; lxi_send(device, command, strlen(command), timeout); // Send SCPI commands to grab image command = "hardcopy start"; lxi_send(device, command, strlen(command), timeout); length = lxi_receive(device, response, IMAGE_SIZE_MAX, timeout); length_check(length); // Dump PNG image data to file screenshot_file_dump(response, length, "bmp"); // Restore old configuration sprintf(command_str,"hardcopy:Format %s", param.Format); lxi_send(device, command_str, strlen(command_str), timeout); sprintf(command_str,"hardcopy:compression %s", param.Compression); lxi_send(device, command_str, strlen(command_str), timeout); sprintf(command_str,"hardcopy:layout %s", param.Layout); lxi_send(device, command_str, strlen(command_str), timeout); sprintf(command_str,"hardcopy:Port %s", param.Port); lxi_send(device, command_str, strlen(command_str), timeout); } else printf("Device doesn't match\n"); // Free allocated memory for screenshot free(response); // Disconnect lxi_disconnect(device); return 0; error_connect: // Free allocated memory for screenshot free(response); return 1; } void length_check(int length) { if (length <= 0) error_printf("Failed to receive message\n"); } // Screenshot plugin configuration struct screenshot_plugin tektronix_3000 = { .name = "tektronix-3000", .description = "Tektronix TDS 3000 series e*Scope oscilloscope (experimental)", .regex = "TEKTRONIX TDS3... ", .screenshot = tektronix_screenshot_3000 }; lxi-tools-2.7/src/plugins/screenshot_tektronix-mso-5.c000066400000000000000000000066721447016333500231730ustar00rootroot00000000000000/* * Copyright (c) 2023 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "error.h" #include "screenshot.h" #define IMAGE_SIZE_MAX 0x800000 // 8 MB int tektronix_screenshot_mso_5(char *address, char *id, int timeout) { char* response = malloc(IMAGE_SIZE_MAX); char *command; int device, length; UNUSED(id); // Connect to LXI instrument device = lxi_connect(address, 0, NULL, timeout, VXI11); if (device == LXI_ERROR) { error_printf("Failed to connect\n"); goto error_connect; } // Send SCPI commands to grab PNG image command = "SAVE:IMAGE 'c:/lxi-tools-screenshot.png'"; lxi_send(device, command, strlen(command), timeout); command = "*WAI"; lxi_send(device, command, strlen(command), timeout); command = "FILESYSTEM:READFILE 'c:/lxi-tools-screenshot.png'"; lxi_send(device, command, strlen(command), timeout); length = lxi_receive(device, response, IMAGE_SIZE_MAX, timeout); if (length < 0) { error_printf("Failed to receive message\n"); goto error_receive; } // Cleanup command = "FILESystem:DELEte 'c:/lxi-tools-screenshot.png'"; lxi_send(device, command, strlen(command), timeout); command = "*WAI"; lxi_send(device, command, strlen(command), timeout); // Dump PNG image data to file screenshot_file_dump(response, length, "png"); // Free allocated memory for screenshot free(response); // Disconnect lxi_disconnect(device); return 0; error_connect: error_receive: // Free allocated memory for screenshot free(response); return 1; } // Screenshot plugin configuration struct screenshot_plugin tektronix_mso_5 = { .name = "tektronix-mso-5", .description = "Tektronix MSO 5 series oscilloscope", .regex = "TEKTRONIX MSO5...", .screenshot = tektronix_screenshot_mso_5 }; lxi-tools-2.7/src/plugins/screenshot_tektronix.c000066400000000000000000000063301447016333500222240ustar00rootroot00000000000000/* * Copyright (c) 2017 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "error.h" #include "screenshot.h" #define IMAGE_SIZE_MAX 0x400000 // 4 MB int tektronix_screenshot(char *address, char *id, int timeout) { char* response = malloc(IMAGE_SIZE_MAX); char *command; int device, length; UNUSED(id); // Connect to LXI instrument device = lxi_connect(address, 0, NULL, timeout, VXI11); if (device == LXI_ERROR) { error_printf("Failed to connect\n"); goto error_connect; } // Send SCPI commands to grab PNG image command = "save:image:fileformat PNG"; lxi_send(device, command, strlen(command), timeout); command = "hardcopy:inksaver off"; lxi_send(device, command, strlen(command), timeout); command = "hardcopy start"; lxi_send(device, command, strlen(command), timeout); length = lxi_receive(device, response, IMAGE_SIZE_MAX, timeout); if (length < 0) { error_printf("Failed to receive message\n"); goto error_receive; } // Dump PNG image data to file screenshot_file_dump(response, length, "png"); // Free allocated memory for screenshot free(response); // Disconnect lxi_disconnect(device); return 0; error_connect: error_receive: // Free allocated memory for screenshot free(response); return 1; } // Screenshot plugin configuration struct screenshot_plugin tektronix_2000 = { .name = "tektronix-2000", .description = "Tektronix DPO/MSO 2000 series oscilloscope (experimental)", .regex = "TEKTRONIX DPO2... MSO2...", .screenshot = tektronix_screenshot }; lxi-tools-2.7/src/run.c000066400000000000000000000043761447016333500150730ustar00rootroot00000000000000/* * Copyright (c) 2016-2022 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include "options.h" #include "error.h" #include "lxilua.h" #include "misc.h" #include #include #include #include int run(char *filename, int timeout) { lua_State *L; UNUSED(timeout); if (strlen(filename) == 0) { error_printf("Missing filename\n"); return 1; } L = luaL_newstate(); luaL_openlibs(L); // Add lxi functions lua_register_lxi(L); if (luaL_dofile(L, filename)) { error_printf("%s\n", lua_tostring(L, -1)); lua_close(L); return 0; } lua_close(L); return 0; } lxi-tools-2.7/src/run.h000066400000000000000000000035151447016333500150720ustar00rootroot00000000000000/* * Copyright (c) 2016-2022 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #pragma once #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #include #include "options.h" #include "error.h" #include int run(char *filename, int timeout); #ifdef __cplusplus } #endif lxi-tools-2.7/src/scpi.c000066400000000000000000000124271447016333500152210ustar00rootroot00000000000000/* * Copyright (c) 2016-2022 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include "options.h" #include "error.h" #include "misc.h" #include #define RESPONSE_LENGTH_MAX 0x500000 #define ID_LENGTH_MAX 65536 int scpi(char *ip, int port, int timeout, lxi_protocol_t protocol, char *command) { char* response = malloc(RESPONSE_LENGTH_MAX); char command_buffer[1000]; int device, length;; strip_trailing_space(command); if (protocol == RAW) { // Add newline to command string strcpy(command_buffer, command); command_buffer[strlen(command)] = '\n'; command_buffer[strlen(command)+1] = 0; command = command_buffer; } // Connect device = lxi_connect(ip, port, NULL, timeout, protocol); if (device != LXI_OK) { error_printf("Unable to connect to LXI device\n"); goto error_connect; } // Send SCPI command length = lxi_send(device, command, strlen(command), timeout); if (length < 0) { error_printf("Failed to send message\n"); goto error_send; } // Only expect response in case we are firing a question command if (question(command)) { length = lxi_receive(device, response, RESPONSE_LENGTH_MAX, timeout); if (length < 0) { error_printf("Failed to receive message\n"); goto error_receive; } // Print response if (option.hex) hex_print(response, length); else { int i; for (i=0; i "); if (input == NULL) break; add_history(input); strip_trailing_space(input); // Skip empty lines if (strlen(input) == 0) continue; // Send entered input as SCPI command length = lxi_send(device, input, strlen(input), timeout); if (length < 0) error_printf("Failed to send message\n"); // Only expect response in case we are firing a question command if (question(input)) { length = lxi_receive(device, response, RESPONSE_LENGTH_MAX, timeout); if (length < 0) { error_printf("Failed to receive message\n"); } else { // Make sure we terminate response string response[length] = 0; // Print response printf("%s", response); } } } printf("\n"); // Disconnect lxi_disconnect(device); free(response); return 0; error_connect: free(response); return 1; } lxi-tools-2.7/src/scpi.h000066400000000000000000000041101447016333500152140ustar00rootroot00000000000000/* * Copyright (c) 2016-2022 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #pragma once #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #include #include #include #include #include "options.h" #include "error.h" #include int scpi(char *ip, int port, int timeout, lxi_protocol_t protocol, char *command); int enter_interactive_mode(char *ip, int port, int timeout, lxi_protocol_t protocol); void strip_trailing_space(char *line); #ifdef __cplusplus } #endif lxi-tools-2.7/src/screenshot.c000066400000000000000000000271421447016333500164400ustar00rootroot00000000000000/* * Copyright (c) 2017-2022 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include #include #include "screenshot.h" #include "error.h" #include #define PLUGIN_LIST_SIZE_MAX 50 #define ID_LENGTH_MAX 65536 extern struct screenshot_plugin keysight_dmm; extern struct screenshot_plugin keysight_ivx; extern struct screenshot_plugin lecroy; extern struct screenshot_plugin rigol_1000z; extern struct screenshot_plugin rigol_2000; extern struct screenshot_plugin rigol_dg; extern struct screenshot_plugin rigol_dl3000; extern struct screenshot_plugin rigol_dm3068; extern struct screenshot_plugin rigol_dp800; extern struct screenshot_plugin rigol_dsa; extern struct screenshot_plugin rs_hmo_rtb; extern struct screenshot_plugin rs_ng; extern struct screenshot_plugin rs_rth; extern struct screenshot_plugin siglent_sdm3000; extern struct screenshot_plugin siglent_sdg; extern struct screenshot_plugin siglent_sds; extern struct screenshot_plugin siglent_ssa3000x; extern struct screenshot_plugin tektronix_2000; extern struct screenshot_plugin tektronix_3000; extern struct screenshot_plugin tektronix_mso_5; static struct screenshot_plugin *plugin_list[PLUGIN_LIST_SIZE_MAX] = { }; static char *screenshot_filename = NULL; static char *screenshot_address = NULL; static bool screenshot_no_gui; static void *screenshot_image_buffer; static int *screenshot_image_size; static char *screenshot_image_format; static char *screenshot_image_filename; static int get_device_id(char *address, char *id, int timeout) { int device, bytes_sent, bytes_received; char *command; // Connect to LXI instrument device = lxi_connect(address, 0, NULL, timeout, VXI11); if (device == LXI_ERROR) { error_printf("Failed to connect\n"); goto error_connect; } // Get instrument ID command = "*IDN?"; bytes_sent = lxi_send(device, command, strlen(command), timeout); if (bytes_sent < 0) goto error_send; bytes_received = lxi_receive(device, id, ID_LENGTH_MAX, timeout); if (bytes_received < 0) { error_printf("Failed to receive message\n"); goto error_receive; } // Disconnect lxi_disconnect(device); // Remove trailing newline if (id[bytes_received-1] == '\n') id[bytes_received-1] = 0; return 0; error_receive: error_send: lxi_disconnect(device); error_connect: return 1; } static bool regex_match(const char *string, const char *pattern) { regex_t regex; int status; if (regcomp(®ex, pattern, REG_EXTENDED | REG_NOSUB) != 0) return false; // No match status = regexec(®ex, string, (size_t) 0, NULL, 0); regfree(®ex); if (status != 0) return false; // No match return true; // Match } static char *date_time(void) { static char date_time_string[50]; struct tm *tm; struct timeval tv; gettimeofday(&tv, NULL); tm = localtime(&tv.tv_sec); strftime(date_time_string, sizeof(date_time_string), "%Y-%m-%dT%H:%M:%S", tm); return date_time_string; } void screenshot_file_dump(void *data, int length, char *format) { char automatic_filename[1000]; char *filename; char *image_data = data; int i = 0; FILE *fd; // Resolve screenshot output filename if (strlen(screenshot_filename) == 0) { // Automatically resolve screenshot filename if no filename is provided sprintf(automatic_filename, "screenshot_%s_%s.%s", screenshot_address, date_time(), format); filename = automatic_filename; } else { // Write image data to specified filename filename = screenshot_filename; } if (screenshot_no_gui) { if (strcmp(screenshot_filename, "-") == 0) { // Write image data to stdout in case filename is '-' for (i=0; i= PLUGIN_LIST_SIZE_MAX) { error_printf("Screenshot plugin list full\n"); exit(EXIT_FAILURE); } // Add plugin plugin_list[i] = plugin; } void screenshot_list_plugins(void) { int length, length_max = 0; int i = 0, j = 0; // Find length of longest plugin name while ((i < PLUGIN_LIST_SIZE_MAX) && (plugin_list[i] != NULL)) { length = strlen(plugin_list[i]->name); if (length_max < length) length_max = length; i++; } // Pretty print list of available plugins i=0; for (j=0; j<(length_max-4); j++) putchar(' '); printf("Name Description\n"); while ((i < PLUGIN_LIST_SIZE_MAX) && (plugin_list[i] != NULL)) { for (j=0; j<(length_max-(int)strlen(plugin_list[i]->name)); j++) putchar(' '); printf("%s", plugin_list[i]->name); printf(" %s\n", plugin_list[i]->description); i++; } } void screenshot_register_plugins(void) { // Register screenshot plugins screenshot_plugin_register(&keysight_dmm); screenshot_plugin_register(&keysight_ivx); screenshot_plugin_register(&lecroy); screenshot_plugin_register(&rigol_1000z); screenshot_plugin_register(&rigol_2000); screenshot_plugin_register(&rigol_dg); screenshot_plugin_register(&rigol_dl3000); screenshot_plugin_register(&rigol_dm3068); screenshot_plugin_register(&rigol_dp800); screenshot_plugin_register(&rigol_dsa); screenshot_plugin_register(&rs_hmo_rtb); screenshot_plugin_register(&rs_ng); screenshot_plugin_register(&rs_rth); screenshot_plugin_register(&siglent_sdm3000); screenshot_plugin_register(&siglent_sdg); screenshot_plugin_register(&siglent_sds); screenshot_plugin_register(&siglent_ssa3000x); screenshot_plugin_register(&tektronix_2000); screenshot_plugin_register(&tektronix_3000); screenshot_plugin_register(&tektronix_mso_5); } int screenshot(char *address, char *plugin_name, char *filename, int timeout, bool no_gui, void *image_buffer, int *image_size, char *image_format, char *image_filename) { static char id[ID_LENGTH_MAX]; bool no_match = true; bool token_found = true; char *token = NULL; int plugin_winner = -1; int match_count = 0; int match_count_max = 0; char *regex_buffer; int i = 0; // Check parameters if (strlen(address) == 0) { error_printf("Missing address\n"); return 1; } // Save variables screenshot_address = address; screenshot_filename = filename; screenshot_no_gui = no_gui; screenshot_image_buffer = image_buffer; screenshot_image_size = image_size; screenshot_image_format = image_format; screenshot_image_filename = image_filename; if (strlen(plugin_name) == 0) { // Get instrument ID if (get_device_id(address, id, timeout) != 0) { error_printf("Unable to retrieve instrument ID\n"); return 1; } // Find relevant screenshot plugin (match instrument ID to plugin) while ((i < PLUGIN_LIST_SIZE_MAX) && (plugin_list[i] != NULL)) { // Skip plugin if it has no .regex entry if (plugin_list[i]->regex == NULL) { i++; continue; } // Walk through space separated regular expressions in regex string regex_buffer = strdup(plugin_list[i]->regex); while (token_found == true) { if (token == NULL) token = strtok(regex_buffer, " "); else token = strtok(NULL, " "); if (token != NULL) { // Match regular expression against ID if (regex_match(id, token)) match_count++; // Successful match } else token_found = false; } free(regex_buffer); // Plugin with most matches wins if (match_count > match_count_max) { plugin_winner = i; match_count_max = match_count; } // Reset match_count = 0; token_found = true; i++; } if (plugin_winner == -1) { error_printf("Could not autodetect which screenshot plugin to use\n"); return 1; } if (isatty(fileno(stdout)) && screenshot_no_gui) printf("Loaded %s screenshot plugin\n", plugin_list[plugin_winner]->name); no_match = false; i = plugin_winner; } else { // Find relevant screenshot plugin (match specified plugin name to plugin) while ((i < PLUGIN_LIST_SIZE_MAX) && (plugin_list[i] != NULL)) { if (strcmp(plugin_list[i]->name, plugin_name) == 0) { no_match = false; break; } i++; } } if (no_match) { error_printf("Unknown plugin name\n"); return 1; } // Call capture screenshot function return plugin_list[i]->screenshot(address, id, timeout); } lxi-tools-2.7/src/screenshot.h000066400000000000000000000043311447016333500164400ustar00rootroot00000000000000/* * Copyright (c) 2017-2022 Martin Lund * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #pragma once #ifdef __cplusplus extern "C" { #endif #include #include "misc.h" void screenshot_register_plugins(void); void screenshot_list_plugins(void); int screenshot(char *address, char *plugin_name, char *filename, int timeout, bool no_gui, void *image_buffer, int *image_size, char *image_format, char *image_filename); // Screenshot helper function used by plugins to dump image file void screenshot_file_dump(void *data, int length, char *format); struct screenshot_plugin { const char *name; const char *description; const char *regex; int (*screenshot)(char *address, char *id, int timeout); }; #ifdef __cplusplus } #endif lxi-tools-2.7/subprojects/000077500000000000000000000000001447016333500156655ustar00rootroot00000000000000lxi-tools-2.7/subprojects/glib.wrap000066400000000000000000000010021447016333500174660ustar00rootroot00000000000000[wrap-file] directory = glib-2.70.2 source_url = https://download.gnome.org/sources/glib/2.70/glib-2.70.2.tar.xz source_filename = glib-2.70.2.tar.xz source_hash = 0551459c85cd3da3d58ddc9016fd28be5af503f5e1615a71ba5b512ac945806f [provide] dependency_names = gthread-2.0, gobject-2.0, gmodule-no-export-2.0, gmodule-export-2.0, gmodule-2.0, glib-2.0, gio-2.0, gio-win32-2.0, gio-unix-2.0 program_names = glib-genmarshal, glib-mkenums, glib-compile-schemas, glib-compile-resources, gio-querymodules, gdbus-codegen lxi-tools-2.7/subprojects/gtk.wrap000066400000000000000000000003461447016333500173500ustar00rootroot00000000000000[wrap-file] directory = gtk-4.6.0 source_url = https://download-fallback.gnome.org/sources/gtk/4.6/gtk-4.6.0.tar.xz source_filename = gtk-4.6.0.tar.xz source_hash = 782d5951fbfd585fc9ec76c09d07e28e6014c72db001fb567fff217fb96e4d8c lxi-tools-2.7/subprojects/gtksourceview.wrap000066400000000000000000000001471447016333500214630ustar00rootroot00000000000000[wrap-git] directory=gtksourceview url=https://gitlab.gnome.org/GNOME/gtksourceview.git revision=5.4.2 lxi-tools-2.7/subprojects/json-glib.wrap000066400000000000000000000004371447016333500204500ustar00rootroot00000000000000[wrap-file] directory = json-glib-1.6.6 source_url = https://download.gnome.org/sources/json-glib/1.6/json-glib-1.6.6.tar.xz source_filename = json-glib-1.6.6.tar.xz source_hash = 96ec98be7a91f6dde33636720e3da2ff6ecbb90e76ccaa49497f31a6855a490e [provide] json-glib-1.0 = json_glib_dep lxi-tools-2.7/subprojects/libadwaita.wrap000066400000000000000000000001411447016333500206550ustar00rootroot00000000000000[wrap-git] directory=libadwaita url=https://gitlab.gnome.org/GNOME/libadwaita.git revision=1.2.0