pax_global_header00006660000000000000000000000064145204414710014514gustar00rootroot0000000000000052 comment=a77819f7449327053a778a762650d43f66f7acc1 signal-estimator-0.0.9/000077500000000000000000000000001452044147100150045ustar00rootroot00000000000000signal-estimator-0.0.9/.clang-format000066400000000000000000000004311452044147100173550ustar00rootroot00000000000000BasedOnStyle: WebKit UseTab: Never IndentWidth: 4 ColumnLimit: 90 MaxEmptyLinesToKeep: 1 PenaltyBreakComment: 0 NamespaceIndentation: None AllowShortLoopsOnASingleLine: false AllowShortFunctionsOnASingleLine: None AllowShortBlocksOnASingleLine: Never BreakBeforeBraces: Attach signal-estimator-0.0.9/.fmtignore000066400000000000000000000000311452044147100167710ustar00rootroot00000000000000src/base/io/PcmFuncs.hpp signal-estimator-0.0.9/.github/000077500000000000000000000000001452044147100163445ustar00rootroot00000000000000signal-estimator-0.0.9/.github/FUNDING.yml000066400000000000000000000001011452044147100201510ustar00rootroot00000000000000liberapay: gavv custom: - "https://www.paypal.me/victorgaydov" signal-estimator-0.0.9/.github/workflows/000077500000000000000000000000001452044147100204015ustar00rootroot00000000000000signal-estimator-0.0.9/.github/workflows/build.yaml000066400000000000000000000033061452044147100223660ustar00rootroot00000000000000name: build on: push: branches: - main tags: - v* pull_request: branches: - main workflow_dispatch: schedule: - cron: '0 0 * * 1' jobs: linux-x86_64: runs-on: ubuntu-latest strategy: fail-fast: false matrix: target: [all, no_gui] compiler: [g++, clang++] name: linux-x86_64-${{ matrix.target }}-${{ matrix.compiler }} steps: - name: Checkout uses: actions/checkout@v3 with: submodules: true - name: Install base dependencies run: | sudo apt-get install -y libasound2-dev - name: Install ui dependencies if: ${{ matrix.target == 'all' }} run: | sudo apt-get install -y qtbase5-dev libqwt-qt5-dev - name: Build env: CXX: ${{ matrix.compiler }} LD: ${{ matrix.compiler }} CXXFLAGS: -Werror run: make ${{ matrix.target }} - name: Check cli run: ./bin/x86_64-linux-gnu/signal-estimator -h - name: Check ui if: ${{ matrix.target == 'all' }} run: test -e ./bin/x86_64-linux-gnu/signal-estimator-gui linux-arm32: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 with: submodules: true - name: Build run: make arm32 - name: Check run: test -e ./bin/arm-linux-gnueabihf/signal-estimator linux-arm64: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 with: submodules: true - name: Build run: make arm64 - name: Check run: test -e ./bin/aarch64-linux-gnu/signal-estimator signal-estimator-0.0.9/.gitignore000066400000000000000000000001341452044147100167720ustar00rootroot00000000000000.$* .cache .dir-locals.el .gdb_history GNUmakefile TODO.org bin build compile_commands.json signal-estimator-0.0.9/.gitmodules000066400000000000000000000011071452044147100171600ustar00rootroot00000000000000[submodule "3rdparty/kissfft"] path = 3rdparty/kissfft url = https://github.com/mborgerding/kissfft.git [submodule "3rdparty/concurrentqueue"] path = 3rdparty/concurrentqueue url = https://github.com/cameron314/concurrentqueue.git [submodule "3rdparty/spdlog"] path = 3rdparty/spdlog url = https://github.com/gabime/spdlog branch = v1.x [submodule "3rdparty/intrusive_shared_ptr"] path = 3rdparty/intrusive_shared_ptr url = https://github.com/gershnik/intrusive_shared_ptr.git [submodule "3rdparty/cli11"] path = 3rdparty/cli11 url = https://github.com/CLIUtils/CLI11.git signal-estimator-0.0.9/.ignore000066400000000000000000000000541452044147100162670ustar00rootroot00000000000000/bin /build /3rdparty compile_commands.json signal-estimator-0.0.9/.spelling000066400000000000000000000003731452044147100166250ustar00rootroot00000000000000airpods behavior bluetooth cmake concurrentqueue devel DUTs intrusive_shared_ptr libasound libpng loopback matplotlib pipewire pkg-config prebuilt pulseaudio qt5 qwt spdlog stdout submodules timestamp toolchain toolchains underruns vendored wallclock signal-estimator-0.0.9/3rdparty/000077500000000000000000000000001452044147100165545ustar00rootroot00000000000000signal-estimator-0.0.9/3rdparty/cli11/000077500000000000000000000000001452044147100174655ustar00rootroot00000000000000signal-estimator-0.0.9/3rdparty/concurrentqueue/000077500000000000000000000000001452044147100220035ustar00rootroot00000000000000signal-estimator-0.0.9/3rdparty/intrusive_shared_ptr/000077500000000000000000000000001452044147100230175ustar00rootroot00000000000000signal-estimator-0.0.9/3rdparty/kissfft/000077500000000000000000000000001452044147100202255ustar00rootroot00000000000000signal-estimator-0.0.9/3rdparty/spdlog/000077500000000000000000000000001452044147100200445ustar00rootroot00000000000000signal-estimator-0.0.9/AUTHORS.md000066400000000000000000000010551452044147100164540ustar00rootroot00000000000000# Authors Signal Estimator authors, ordered by first contribution: * Victor Gaydov (victor@enise.org) * BitsonFire (neerajkarthik30@gmail.com) * Vien Huynh (https://github.com/Vhuynh25) * robotboyfriend (https://github.com/robotboyfriend) * Théo Lebrun (theo.lebrun@bootlin.com) * Marco Langer (langer.m86@gmail.com) * Boring Technologies (sam@boring.tech) * Mikhail Baranov (baranov.mv@gmail.com) * Chinry (nlembo99@gmail.com) * Aadithyaa Eeswaran (eaadithyaa@gmail.com) * Jānis Ancāns (janis.ancans@runbox.eu) * Chloe Stejskal (stejskcl@miamioh.edu) signal-estimator-0.0.9/CHANGES.md000066400000000000000000000133201452044147100163750ustar00rootroot00000000000000# Changelog ## [v0.0.9][v0.0.9] - 01 Nov 2023 * Improve impulse detection stability in latency_corr mode * Implement new `io_delay` measurement mode ([gh-74][gh-74]) * Support arbitrary sample formats for output and input devices ([gh-78](gh-78)) * Replace two options `--dump-out` and `--dump-in` with one option `--dump-file` ([gh-76][gh-76]) * Add more info to JSON reports ([gh-65][gh-65]) * GUI: Show plots with measurement results ([gh-47][gh-47]) * GUI: Group options by category and add tooltips ([gh-15][gh-15]) * GUI: Add missing options: impulse settings ([gh-27][gh-27]), input/output format and ring buffer settings, I/O jitter and delay settings, warmup setting, SCHED_RR option * GUI: Refine option names, tooltips, and units (suffixes) * GUI: Change plot window to 15 seconds * GUI: Cleanup sizes and paddings * GUI: Fix SIGSEGV when exiting during measurement [v0.0.9]: https://github.com/gavv/signal-estimator/releases/tag/v0.0.9 [gh-15]: https://github.com/gavv/signal-estimator/issues/15 [gh-27]: https://github.com/gavv/signal-estimator/issues/27 [gh-47]: https://github.com/gavv/signal-estimator/issues/47 [gh-65]: https://github.com/gavv/signal-estimator/issues/65 [gh-74]: https://github.com/gavv/signal-estimator/issues/74 [gh-76]: https://github.com/gavv/signal-estimator/issues/76 [gh-78]: https://github.com/gavv/signal-estimator/issues/78 ## [v0.0.8][v0.0.8] - 30 Oct 2023 * Overhaul hardware latency calculation and improve its precision * Implement new `io_jitter` measurement mode ([gh-53][gh-53]) * Support multiple input devices ([gh-51][gh-51]) * Support different channel counts for output and input devices ([gh-50][gh-50]) * Support different period size and count for output and input devices ([gh-52][gh-52]) * Rename `-v` (`--volume`) to `-g` (`--gain`) * Add `-v` (`--verbose`) option, reduce verbosity by default * Add `--no-rt` option * Rename `--step-period` / `--impulse-period` to `--step-interval` / `--impulse-interval` to avoid confusion with ALSA periods * Take `--gain` into account in `latency_corr` mode (earlier it was ignored) * Saturate instead of overflowing when `--gain`-ed signal is high * Enable `--warmup` by default * Disable `--dump-compression` by default * Use wallclock (absolute system time) time in csv dumps ([gh-60][gh-60]) * GUI: Display measurement results ([gh-13][gh-13]) * GUI: Fix mode names * GUI: Reduce default dump compression * Optimization: avoid frame allocations in real-time path * Optimization: avoid using double-precision floats when they're not needed * Optimization: move computations to separate thread in `latency_step` mode * Optimization: make computation threads non-realtime * Switch to spdlog and enable colored logging ([gh-38][gh-38]) * Switch from cxxopts to CLI11 ([gh-26][gh-26]) * Switch vendored dependencies to latest stable tags * Add new dependency: intrusive_shared_ptr * Enable and fix more warnings * Refactoring * Improve documentation [v0.0.8]: https://github.com/gavv/signal-estimator/releases/tag/v0.0.8 [gh-13]: https://github.com/gavv/signal-estimator/issues/13 [gh-26]: https://github.com/gavv/signal-estimator/issues/26 [gh-38]: https://github.com/gavv/signal-estimator/issues/38 [gh-50]: https://github.com/gavv/signal-estimator/issues/50 [gh-51]: https://github.com/gavv/signal-estimator/issues/51 [gh-52]: https://github.com/gavv/signal-estimator/issues/52 [gh-53]: https://github.com/gavv/signal-estimator/issues/53 [gh-60]: https://github.com/gavv/signal-estimator/issues/60 ## [v0.0.7][v0.0.7] - 19 Sep 2023 * Support cross-compilation (see README) * Bump minimal cmake version to 3.5 * Improve documentation * Improve CI [v0.0.7]: https://github.com/gavv/signal-estimator/releases/tag/v0.0.7 ## [v0.0.6][v0.0.6] - 15 May 2023 * Add debug checks, sanitizers, and assertions * Fix buffer overflow in ImpulseGenerator ([gh-25][gh-25]) * Fix use after free ([gh-25][gh-25]) * Fix memory leak in FFTConvolution ([gh-25][gh-25]) * Fix crash in plotting code ([gh-25][gh-25]) * Fix hang in alsa_close ([gh-5][gh-5]) [v0.0.6]: https://github.com/gavv/signal-estimator/releases/tag/v0.0.6 [gh-25]: https://github.com/gavv/signal-estimator/issues/25 [gh-5]: https://github.com/gavv/signal-estimator/issues/5 ## [v0.0.5][v0.0.5] - 11 Feb 2023 * Fix broken build for Qt 5.15.5 ([gh-23][gh-23]) * Implement convolution-based latency estimation ([gh-3][gh-3]) * Major refactoring * Refinements in command-line options * Add `--warmup` option [v0.0.5]: https://github.com/gavv/signal-estimator/releases/tag/v0.0.5 [gh-23]: https://github.com/gavv/signal-estimator/issues/23 [gh-3]: https://github.com/gavv/signal-estimator/issues/3 ## [v0.0.4][v0.0.4] - 05 Jun 2022 * Fix timestamps on 32-bits platforms ([gh-21][gh-21]) * Improve Qwt plot GUI ([gh-19][gh-19]) * Fix leaks in GUI * Fix compiler warnings * Improve documentation [v0.0.4]: https://github.com/gavv/signal-estimator/releases/tag/v0.0.4 [gh-19]: https://github.com/gavv/signal-estimator/issues/19 [gh-21]: https://github.com/gavv/signal-estimator/issues/21 ## [v0.0.3][v0.0.3] - 24 Aug 2021 * Fix build on Arch ([gh-18][gh-18]) * Fixes in dumper * Fix compiler warnings * Improve documentation * Improve CI [v0.0.3]: https://github.com/gavv/signal-estimator/releases/tag/v0.0.3 [gh-18]: https://github.com/gavv/signal-estimator/issues/18 ## [v0.0.2][v0.0.2] - 22 Aug 2021 * Add JSON output support ([gh-2][gh-2]) * Add GUI ([gh-6][gh-6]) * Add makefile * Fix error messages * Fix compiler warnings * Improve documentation [v0.0.2]: https://github.com/gavv/signal-estimator/releases/tag/v0.0.2 [gh-2]: https://github.com/gavv/signal-estimator/issues/2 [gh-6]: https://github.com/gavv/signal-estimator/issues/6 ## [v0.0.1][v0.0.1] - 03 Mar 2020 * Initial release [v0.0.1]: https://github.com/gavv/signal-estimator/releases/tag/v0.0.1 signal-estimator-0.0.9/CMakeLists.txt000066400000000000000000000157151452044147100175550ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.5) if(${CMAKE_VERSION} VERSION_GREATER_EQUAL 3.24) cmake_policy(SET CMP0135 OLD) endif() project(SignalEstimator) option(BUILD_GUI "build Qt GUI" ON) option(ENABLE_SANITIZERS "enable sanitizers" OFF) option(ENABLE_WERROR "enable -Werror" OFF) set(TOOLCHAIN_PREFIX "" CACHE STRING "target host triplet, e.g. aarch64-linux-gnu") include("cmake/SetupToolchain.cmake") include("cmake/ThirdParty.cmake") set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH}) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release") endif() list(APPEND COMPILER_FLAGS -pthread ) list(APPEND LINKER_FLAGS -pthread ) if(CMAKE_BUILD_TYPE STREQUAL "Debug") add_compile_options( -fno-omit-frame-pointer -funwind-tables -ggdb ) endif() if(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") list(APPEND COMPILER_FLAGS -Wall -Wextra # enable -Wcast-qual -Wctor-dtor-privacy -Wdouble-promotion -Wfloat-conversion -Wformat-security -Wformat=2 -Wlogical-op -Wmissing-declarations -Woverlength-strings -Wpointer-arith -Wsign-conversion -Wstrict-null-sentinel -Wuninitialized # disable -Wno-old-style-cast -Wno-psabi -Wno-system-headers ) if(CMAKE_BUILD_TYPE STREQUAL "Debug") list(APPEND COMPILER_FLAGS -D_GLIBCXX_ASSERTIONS -D_GLIBCXX_DEBUG -D_GLIBCXX_SANITIZE_VECTOR ) endif() endif() if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") list(APPEND COMPILER_FLAGS -Wall -Wextra # enable -Wcast-qual -Wdouble-promotion -Wfloat-conversion -Wformat-security -Wformat=2 -Wnull-dereference -Woverlength-strings -Woverloaded-virtual -Wpointer-arith -Wsign-conversion -Wuninitialized -Wunused # disable -Wno-cast-align -Wno-system-headers -Wno-unused-private-field ) endif() if(ENABLE_WERROR) list(APPEND COMPILER_FLAGS -Werror ) endif() if(ENABLE_SANITIZERS) list(APPEND COMPILER_FLAGS -fsanitize=address -fsanitize=undefined ) list(APPEND LINKER_FLAGS -fsanitize=address -fsanitize=undefined ) endif() add_library(base_objects OBJECT src/base/core/Frame.cpp src/base/core/FramePool.cpp src/base/core/FrameQueue.cpp src/base/core/Log.cpp src/base/core/RateLimiter.cpp src/base/core/Realtime.cpp src/base/core/Sample.cpp src/base/core/Time.cpp src/base/dumps/AsyncDumper.cpp src/base/dumps/CsvDumper.cpp src/base/io/AlsaDeviceManager.cpp src/base/io/AlsaReader.cpp src/base/io/AlsaUtils.cpp src/base/io/AlsaWriter.cpp src/base/io/PcmFormat.cpp src/base/io/PcmMapper.cpp src/base/processing/ContinuousGenerator.cpp src/base/processing/CorrelationLatencyEstimator.cpp src/base/processing/IODelayEstimator.cpp src/base/processing/IOJitterEstimator.cpp src/base/processing/Impulse.cpp src/base/processing/ImpulseGenerator.cpp src/base/processing/LossEstimator.cpp src/base/processing/StepsGenerator.cpp src/base/processing/StepsLatencyEstimator.cpp src/base/reports/JsonPrinter.cpp src/base/reports/JsonReporter.cpp src/base/reports/TextReporter.cpp src/base/run/Runner.cpp ) add_dependencies(base_objects ${ALL_DEPENDENCIES} ) target_compile_options(base_objects PRIVATE ${COMPILER_FLAGS} ) target_link_options(base_objects PRIVATE ${LINKER_FLAGS} ) target_include_directories(base_objects PRIVATE src/base ) add_executable(signal-estimator src/cli/Format.cpp src/cli/Main.cpp src/cli/Print.cpp ) add_dependencies(signal-estimator ${ALL_DEPENDENCIES} ) set(ALL_EXECUTABLES) list(APPEND ALL_EXECUTABLES signal-estimator ) target_compile_options(signal-estimator PRIVATE ${COMPILER_FLAGS} ) target_link_options(signal-estimator PRIVATE ${LINKER_FLAGS} ) target_include_directories(signal-estimator PRIVATE src/base ) target_link_libraries(signal-estimator base_objects m ) install( TARGETS signal-estimator RUNTIME DESTINATION bin ) if(BUILD_GUI) find_package(Qt5Core REQUIRED) find_package(Qt5Widgets REQUIRED) find_package(Qwt REQUIRED) qt5_wrap_cpp(GENERATED_SOURCES src/gui/ListValidator.hpp src/gui/MainWindow.hpp src/gui/NotFoundDialog.hpp src/gui/SignalEstimator.hpp ) set(UI_SOURCES src/gui/MainWindow.ui src/gui/NotFoundDialog.ui ) foreach(UI_FILE IN LISTS UI_SOURCES) qt5_wrap_ui(GENERATED_SOURCES ${UI_FILE}) endforeach() add_library(generated_objects OBJECT ${GENERATED_SOURCES} ) add_dependencies(generated_objects ${ALL_DEPENDENCIES} ) target_include_directories(generated_objects PRIVATE src/base ) add_executable(signal-estimator-gui src/gui/ListValidator.cpp src/gui/Main.cpp src/gui/MainWindow.cpp src/gui/NotFoundDialog.cpp src/gui/PointsBuffer.cpp src/gui/RightClickPickerMachine.cpp src/gui/SignalEstimator.cpp ) add_dependencies(signal-estimator-gui ${ALL_DEPENDENCIES} ) list(APPEND ALL_EXECUTABLES signal-estimator-gui ) target_compile_options(signal-estimator-gui PRIVATE ${COMPILER_FLAGS} ) target_link_options(signal-estimator-gui PRIVATE ${LINKER_FLAGS} ) target_include_directories(signal-estimator-gui PRIVATE src/base ) foreach(TARGET IN ITEMS generated_objects signal-estimator-gui) target_include_directories(${TARGET} SYSTEM PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${QWT_INCLUDE_DIR} ${Qt5Core_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS} ) endforeach() target_link_libraries(signal-estimator-gui generated_objects base_objects ${QWT_LIBRARY} Qt5::Core Qt5::Widgets ) install( TARGETS signal-estimator-gui RUNTIME DESTINATION bin ) endif(BUILD_GUI) set(BIN_DIR bin/${CMAKE_C_COMPILER_TARGET} ) set(INSTALLED_EXECUTABLES) foreach(EXE_TARGET IN LISTS ALL_EXECUTABLES) set(EXE_PATH ${PROJECT_SOURCE_DIR}/${BIN_DIR}/${EXE_TARGET}${CMAKE_EXECUTABLE_SUFFIX} ) add_custom_command( COMMENT "Copying ${EXE_TARGET} to ${BIN_DIR}" DEPENDS ${EXE_TARGET} OUTPUT ${EXE_PATH} COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/${BIN_DIR} COMMAND ${CMAKE_COMMAND} -E copy $ ${PROJECT_SOURCE_DIR}/${BIN_DIR} ) list(APPEND INSTALLED_EXECUTABLES ${EXE_PATH} ) endforeach() add_custom_target(install_executables ALL DEPENDS ${INSTALLED_EXECUTABLES} ) if(NOT CMAKE_CROSSCOMPILING) add_custom_command( COMMENT "Copying compile_commands.json to project root" DEPENDS ${ALL_EXECUTABLES} OUTPUT ${PROJECT_SOURCE_DIR}/compile_commands.json COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/compile_commands.json ${PROJECT_SOURCE_DIR}/compile_commands.json ) add_custom_target(compile_commands ALL DEPENDS ${PROJECT_SOURCE_DIR}/compile_commands.json ) endif() signal-estimator-0.0.9/LICENSE000066400000000000000000000021271452044147100160130ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) Victor Gaydov and contributors, see AUTHORS file. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. signal-estimator-0.0.9/Makefile000066400000000000000000000024731452044147100164520ustar00rootroot00000000000000NUM_CPU ?= $(shell nproc --all) VARIANT ?= Release WERROR ?= OFF SANITIZERS ?= OFF MACHINE := $(shell uname -m)-linux-gnu CMAKE_CMD := cmake -DCMAKE_BUILD_TYPE=$(VARIANT) \ -DENABLE_WERROR=$(WERROR) -DENABLE_SANITIZERS=$(SANITIZERS) MAKE_CMD := make -j$(NUM_CPU) --no-print-directory DOCKER_CMD := docker run -t --rm \ -u "$(shell id -u)" \ -v "$(shell pwd):$(shell pwd)" \ -w "$(shell pwd)" all: mkdir -p build/$(MACHINE) cd build/$(MACHINE) && $(CMAKE_CMD) ../.. cd build/$(MACHINE) && $(MAKE_CMD) no_gui: mkdir -p build/$(MACHINE) cd build/$(MACHINE) && $(CMAKE_CMD) -DBUILD_GUI=NO ../.. cd build/$(MACHINE) && $(MAKE_CMD) arm32: mkdir -p build/arm-linux-gnueabihf $(DOCKER_CMD) rocstreaming/toolchain-arm-linux-gnueabihf /bin/bash -c \ "cd build/arm-linux-gnueabihf && \ $(CMAKE_CMD) -DBUILD_GUI=NO -DTOOLCHAIN_PREFIX=arm-linux-gnueabihf ../.. && \ $(MAKE_CMD)" arm64: mkdir -p build/aarch64-linux-gnu $(DOCKER_CMD) rocstreaming/toolchain-aarch64-linux-gnu /bin/bash -c \ "cd build/aarch64-linux-gnu && \ $(CMAKE_CMD) -DBUILD_GUI=NO -DTOOLCHAIN_PREFIX=aarch64-linux-gnu ../.. && \ $(MAKE_CMD)" install: cd build && make install clean: rm -rf build rm -rf bin fmt: find src -type f -name '*.[ch]pp' | while read f; do \ grep -qF "$$f" .fmtignore || clang-format --verbose -i "$$f"; \ done signal-estimator-0.0.9/README.md000066400000000000000000000623331452044147100162720ustar00rootroot00000000000000Signal Estimator ================ [![Build](https://github.com/gavv/signal-estimator/workflows/build/badge.svg)](https://github.com/gavv/signal-estimator/actions) - [Features](#features) - [Usage examples](#usage-examples) - [Release history](#release-history) - [Supported platforms](#supported-platforms) - [Dependencies](#dependencies) - [Installation](#installation) - [Cross-compilation](#cross-compilation) - [Graphical interface](#graphical-interface) - [Command-line options](#command-line-options) - [Measuring latency](#measuring-latency) - [Measuring losses](#measuring-losses) - [Measuring I/O jitter and delay](#measuring-io-jitter-and-delay) - [Multiple input devices](#multiple-input-devices) - [JSON output](#json-output) - [Dumping streams](#dumping-streams) - [ALSA parameters](#alsa-parameters) - [Disabling PulseAudio](#disabling-pulseaudio) - [Disabling PipeWire](#disabling-pipewire) - [Real-time scheduling policy](#real-time-scheduling-policy) - [Internals](#internals) - [Acknowledgements](#acknowledgements) - [Authors](#authors) - [License](#license) Features -------- `signal-estimator` is a small command-line and GUI tool allowing to measure different characteristics of the signal looped back from audio output to audio input. Features: * send test signal to output device and receive looped back signal from input device(s) * measure signal latency (the shift between output and input signal) * measure signal loss ratio (number of glitches per second in the input signal) * measure I/O jitter and delay * print reports in JSON format for easy parsing * dump output and input streams in CSV format for later inspection Usage examples -------------- * **Measure hardware latency of sound card (by cable)** Connect audio output of PC to audio input using a jack cable. Measured loopback latency (bold red) will give you output + input latency of sound card. * **Measure hardware latency of sound card (by air)** Place PC speakers near microphone. Measured loopback latency (bold red) will give you output + input latency of sound card + latency of spreading over air if distance is significant. * **Measure hardware + software latency of loopback setup** Connect audio output of PC to audio input of DUT (Device Under Test, e.g. another computer) using a jack cable. Connect audio output of DUT to audio input of PC. On DUT, run software that loops back signal from input to output device. Measured loopback latency (bold red) will give you output + input latency of PC sound card (which you can measure separately and subtract) + output + input latency of DUT sound card (which you can also measure separately) + latency of software running on DUT. * **Measure hardware + software + network latency of streaming setup** Connect audio output of PC to audio input of first DUT (Device Under Test, e.g. another computer). Connect audio output of second DUT to audio input of PC. Run software that reads audio input on first DUT, sends it to second DUT, and writes to its audio output. Measured loopback latency (bold red) will give you output + input latency of PC sound card (which you can measure separately and subtract) + output + input latency of DUT sound cards (which you can also measure separately) + latency of software running on DUTs + latency of network. * **Measure hardware + software + bluetooth latency of mobile phone with Bluetooth headset** Place PC speakers near bluetooth microphone connected to a mobile phone. Place PC microphone near bluetooth headphones connected to the phone. Run a mobile app that loops back signal from bluetooth microphone to bluetooth headphones. Measured loopback latency (bold red) will give you output + input latency of PC sound card (which you can measure separately and subtract) + output + input latency of Bluetooth stack and software running on phone + latency of Bluetooth. * **Measure synchronicity of two microphones** Place one speaker and two microphones in the same room, and connect all three to the PC. Run signal-estimator with one output and two input devices. Difference between measured latencies of the two inputs (bold red) will show how synchronous are the two microphones. * **Measure synchronicity of streaming setup** Connect audio output of PC to audio input of sender DUT (Device Under Test, e.g. another computer). Connect audio outputs of two receiver DUTs to audio inputs of PC. On DUTs, run software that sends audio input to audio outputs over network. On PC, run signal-estimator with one output and two input devices. Difference between measured latencies of the two inputs (bold red) will show how synchronous are the two streams played on two receiver DUTs. Release history --------------- Changelog file can be found here: [changelog](CHANGES.md). Supported platforms ------------------- * Linux / ALSA Dependencies ------------ External: * C++17 compiler (GCC or Clang) * CMake >= 3.5 * pkg-config * libasound (ALSA devel) * libpng (for GUI) * Qt5 and Qwt (for GUI) Vendored (git submodules): * [KISS FFT](https://github.com/mborgerding/kissfft) * [concurrentqueue](https://github.com/cameron314/concurrentqueue) * [intrusive_shared_ptr](https://github.com/gershnik/intrusive_shared_ptr) * [spdlog](https://github.com/gabime/spdlog) * [CLI11](https://github.com/CLIUtils/CLI11) Installation ------------ Install external dependencies: ``` sudo apt install g++ make cmake pkg-config libasound2-dev libpng-dev qtbase5-dev libqwt-qt5-dev ``` Clone repo with submodules: ``` git clone --recurse-submodules https://github.com/gavv/signal-estimator.git cd signal-estimator ``` Build: ``` make ``` Build without GUI (in this case Qt and Qwt are not needed): ``` make no_gui ``` Executables are now placed into `bin/` directory, where `` is your host toolchain, e.g. `x86_64-linux-gnu`. Install into the system (optionally): ``` sudo make install ``` Cross-compilation ----------------- If you're using 32-bit or 64-bit Raspberry Pi, you can run: ``` make arm32 ``` or: ``` make arm64 ``` These commands require Docker. They will pull and run docker images with prebuilt toolchains compatible with Raspberry Pi, perform build, and place executables into `bin/arm-linux-gnueabihf` and `bin/aarch64-linux-gnu`, respectively. To use your own toolchain instead of docker images, in simple cases it is enough just to specify `TOOLCHAIN_PREFIX` CMake option: ``` mkdir -p build/ cd build/ cmake -DBUILD_GUI=NO -DTOOLCHAIN_PREFIX= ../.. make ``` In example above, `` defines toolchain triple of the target system, e.g. `aarch64-linux-gnu`. In this case `aarch64-linux-gnu-gcc` and other tools should be available in `PATH`. For more complicated cases, refer to [standard instructions](https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html) for cross-compiling using CMake. Graphical interface ------------------- The tool comes with a simple GUI (`signal-estimator-gui`) that plots the signal in the real-time. It can be especially useful for troubleshooting problems with measurements. It uses Qt and Qwt libraries. Internally, it invokes the command-line tool (`signal-estimator`) and parses its output. Here is how it looks like: Command-line options -------------------- ``` $ signal-estimator --help Measure characteristics of a looped back signal Usage: signal-estimator [OPTIONS] Options: -h,--help Print this help message and exit -L,--list-supported Print supported features and exit -v,--verbose [0] Increase verbosity level (can be used multiple times) Control options: -m,--mode TEXT [latency_corr] Operation mode: latency_corr|latency_step|losses|io_jitter|io_delay -o,--output TEXT Output device name -i,--input TEXT ... Input device name(s) -d,--duration FLOAT [0] Limit measurement duration, seconds (zero for no limit) -w,--warmup FLOAT [1] Warmup duration, seconds (zero for no warmup) I/O options: -r,--rate UINT [48000] Sample rate, Hz -c,--chans UINT [2] Number of channels -g,--gain FLOAT [0.8] Output signal gain, from 0 to 1 --in-latency UINT [8000] Input ring buffer size, microseconds --in-periods UINT [2] Number of periods in input ring buffer --in-format TEXT [s16] Input device sample format (see --list-supported) --out-latency UINT [8000] Output ring buffer size, microseconds --out-periods UINT [2] Number of periods in output ring buffer --out-format TEXT [s16] Output device sample format (see --list-supported) --no-rt Don't try using SCHED_RR policy Report options: -f,--report-format TEXT [text] Report format: text|json --report-sma UINT [5] Simple Moving Average window for latency reports Dump options: -D,--dump-file TEXT File to dump samples ("-" for stdout) --dump-compression UINT [0] Compress dumped samples by given ratio using SMA Correlation-based latency estimation options: --impulse-interval FLOAT [1] Impulse interval, seconds --impulse-peak-noise-ratio FLOAT [4] The peak-to-noise minimum ratio threshold --impulse-peak-window UINT [128] Peak detection window length, samples Step-based latency estimation options: --step-interval FLOAT [1] Step interval, seconds --step-length FLOAT [0.1] Step length, seconds --step-detection-window UINT [96] Step detection running maximum window, samples --step-detection-threshold FLOAT [0.4] Step detection threshold, from 0 to 1 Loss ratio estimation options: --signal-detection-window UINT [48] Signal detection running maximum window, samples --signal-detection-threshold FLOAT [0.15] Signal detection threshold, from 0 to 1 --glitch-detection-window UINT [32] Glitch detection running maximum window, samples --glitch-detection-threshold FLOAT [0.05] Glitch detection threshold, from 0 to 1 I/O jitter estimation options: --io-jitter-window UINT [250] I/O jitter detection window, number of periods --io-jitter-percentile UINT [95] I/O jitter percentile, from 1 to 100 I/O delay estimation options: --io-delay-window UINT [250] I/O delay detection window, number of periods ``` Measuring latency ----------------- There are two latency estimation modes: * **Correlation-based latency estimation** (`--mode latency_corr`), * **Step-based latency estimation** (`--mode latency_step`). In both modes, the tool generates short periodic impulses and calculates the shift between each sent and received impulse. In correlation mode, the tool generates M-sequence faded in and out with a Hamming window, and performs cross-correlation to match input and output. In step mode, the tool generates a step function and detects steps using a Schmitt trigger. The correlation mode is known to provide improved precision and stability even under worse signal-to-noise ratio. The step mode, on the other hand, is much simpler and easier to verify, and so can be used as a baseline. ``` $ sudo signal-estimator -vv -m latency_corr -o hw:0 -i hw:0 [II] opening alsa writer for device hw:0 [DD] buffer_size: 8000 us (384 samples) [DD] period_size: 4000 us (192 samples) [DD] sample_rate: 48000 Hz [DD] sample_format: s16 [DD] channel_count: 2 [II] opening alsa reader for device hw:0 [DD] buffer_size: 8000 us (384 samples) [DD] period_size: 4000 us (192 samples) [DD] sample_rate: 48000 Hz [DD] sample_format: s16 [DD] channel_count: 2 [II] starting measurement [DD] successfully enabled real-time scheduling policy [DD] successfully enabled real-time scheduling policy latency: sw+hw 10.688ms hw 2.688ms hw_avg5 2.688ms latency: sw+hw 10.237ms hw 2.237ms hw_avg5 2.462ms latency: sw+hw 11.231ms hw 3.231ms hw_avg5 2.719ms latency: sw+hw 10.776ms hw 2.776ms hw_avg5 2.733ms latency: sw+hw 11.299ms hw 3.299ms hw_avg5 2.846ms ... ``` Notation: * `sw+hw` - total software + hardware latency, including ALSA ring buffer computed as the time interval beginning when the impulse was written to the output ring buffer, and ending when the impulse was read from the input ring buffer * `hw` - an estimation of hardware latency, i.e. excluding ALSA ring buffer computed as the time interval beginning when the impulse was sent from ring buffer to the hardware, and ending when the impulse was received from the hardware and placed into ring buffer * `hw_avg5` - moving average of last 5 `hw` values (5 is configurable) `sw+hw` latency is affected by ring buffer settings like `--out-latency` and `--out-periods`. `hw` latency, on the other hand, should not be affected by ring buffer and should depend only on your hardware and the way how the signal is looped back from output to input (e.g. if it's going by air, the distance will make a difference). If you observe underruns or overruns, you may need to increase ALSA period size or count, depending on your hardware. Depending on environment, you may also need to configure signal gain (`--gain`), and impulse/step interval and threshold (`--impulse-xxx` and `--step-xxx`). Measuring losses ---------------- In the loss estimation mode, the tool generates continuous harmonic and counts for glitches and gaps in the received signal. ``` $ sudo signal-estimator -vv -m losses -o hw:0 -i hw:0 [II] opening alsa writer for device hw:0 [DD] buffer_size: 8000 us (384 samples) [DD] period_size: 4000 us (192 samples) [DD] sample_rate: 48000 Hz [DD] sample_format: s16 [DD] channel_count: 2 [II] opening alsa reader for device hw:0 [DD] buffer_size: 8000 us (384 samples) [DD] period_size: 4000 us (192 samples) [DD] sample_rate: 48000 Hz [DD] sample_format: s16 [DD] channel_count: 2 [II] starting measurement [DD] successfully enabled real-time scheduling policy [DD] successfully enabled real-time scheduling policy losses: rate 0.0/sec rate_avg5 0.0/sec ratio 0.00% losses: rate 6.0/sec rate_avg5 3.0/sec ratio 0.26% losses: rate 3.0/sec rate_avg5 3.0/sec ratio 0.20% losses: rate 0.0/sec rate_avg5 2.3/sec ratio 0.00% losses: rate 1.0/sec rate_avg5 2.0/sec ratio 0.01% ... ``` Notation: * `rate` - rough estimation of the number of losses (glitches) per second a glitch is defined as a spike in the received signal gradient; we rely on the fact that the original signal is a smooth continuous sine wave * `rate_avg5` - moving average of last 5 `rate` values * `ratio` - rough estimation of the loss ratio (percentage of the lost frames) a loss is defined as a frame of the received signal, with all samples having small amplitude (volume); we rely on the fact that the original signal is a loud continuous sine wave These numbers may be rather imprecise. If you're having troubles, you may need to configure signal gain (`--gain`) and signal and glitch detection parameters (`--signal-xxx` and `--glitch-xxx`). Measuring I/O jitter and delay ------------------------------ In **I/O jitter estimation mode**, the tool does not look at the signal itself, but instead measures jitter of I/O operations. This jitter defines how precisely ALSA and OS schedule I/O. ``` $ sudo signal-estimator -vv -o hw:0 -m io_jitter [II] opening alsa reader for device hw:0 [DD] buffer_size: 8000 us (384 samples) [DD] period_size: 4000 us (192 samples) [DD] sample_rate: 48000 Hz [DD] sample_format: s16 [DD] channel_count: 2 [II] starting measurement [DD] successfully enabled real-time scheduling policy io_jitter: sw_avg 0.087ms sw_p95 0.273ms hw_avg 0.037ms hw_p95 0.106ms io_jitter: sw_avg 0.107ms sw_p95 0.274ms hw_avg 0.050ms hw_p95 0.136ms io_jitter: sw_avg 0.102ms sw_p95 0.272ms hw_avg 0.052ms hw_p95 0.142ms io_jitter: sw_avg 0.125ms sw_p95 0.329ms hw_avg 0.043ms hw_p95 0.121ms io_jitter: sw_avg 0.146ms sw_p95 0.320ms hw_avg 0.031ms hw_p95 0.107ms ... ``` Notation: * `sw_avg`, `sw_p95` - software timestamp jitter Deviation from period size of delta between software timestamps of subsequent frames. **Software timestamp** is the wallclock time when we wrote frame to ALSA ring buffer or read frame from it. `sw_avg` is average value, and `sw_p95` is 95th percentile (95 is configurable). * `hw_avg`, `hw_p95` - hardware timestamp jitter Deviation from period size of delta between hardware timestamps of subsequent frames. **Hardware timestamp** is the estimation of wallclock time when the frame was sent from ALSA ring buffer to hardware, or received from hardware and placed into ring buffer. `hw_avg` is average value, and `hw_p95` is 95th percentile (95 is configurable). **I/O delay estimation mode** is similar. The tool also does not look at the signal, but instead monitors software and hardware delays reported by ALSA. ``` $ sudo signal-estimator -vv -o hw:0 -m io_delay [II] opening alsa reader for device hw:0 [DD] buffer_size: 8000 us (384 samples) [DD] period_size: 4000 us (192 samples) [DD] sample_rate: 48000 Hz [DD] sample_format: s16 [DD] channel_count: 2 [II] starting measurement [DD] successfully enabled real-time scheduling policy io_delay: sw_avg 6.696ms hw_avg 0.783ms io_delay: sw_avg 6.675ms hw_avg 0.760ms io_delay: sw_avg 6.701ms hw_avg 0.824ms io_delay: sw_avg 6.682ms hw_avg 0.822ms io_delay: sw_avg 6.739ms hw_avg 0.823ms ... ``` Notation: * `sw_avg` - average ring buffer size (software delay) Average value of ALSA ring buffer size, measured right after writing or reading frame. * For output devices, we try to keep the ring buffer full. The ideal buffer length would be the same as configured via `--out-latency` or `--in-latency` option. * For input devices, we try to keep the ring buffer empty. The ideal buffer length would be zero. * `hw_avg` - average delay between ring buffer and ADC/DAC (hardware delay) Average value of delay introduced by link and codec, measured right after writing or reading frame. Hardware delay is reported by ALSA and is driver-dependent. Some drivers may report incomplete values (e.g. don't take codec into account) or even zero. Hardware delay is usually constant, but can be variable for some codecs. On USB cards, hardware delay may also depend on period size. For more details about delays, see [ALSA documentation](https://www.kernel.org/doc/html/v4.10/sound/designs/timestamping.html). ALSA uses terms `avail` and `delay`, which maps to signal-estimator as follows: * for input device: `software_delay = avail` * for output device: `software_delay = buffer_size - avail` * `hardware_delay = delay - software_delay`. You can configure SMA and percentile parameters via `--io-jitter-xxx` and `--io-delay-xxx` options. Multiple input devices ---------------------- It is possible to specify one output and multiple input devices. The tool assumes that the output reaches all inputs, and performs independent measurement for every input device. ``` $ sudo signal-estimator -v -o hw:0 -i hw:1 -i hw:2 [II] opening alsa writer for device hw:0 [II] opening alsa reader for device hw:1 [II] opening alsa reader for device hw:2 [II] starting measurement latency[hw:1]: sw+hw 9.704ms hw 1.892ms hw_avg5 1.892ms latency[hw:2]: sw+hw 9.680ms hw 2.846ms hw_avg5 2.846ms latency[hw:1]: sw+hw 8.990ms hw 1.823ms hw_avg5 1.858ms latency[hw:2]: sw+hw 9.837ms hw 2.670ms hw_avg5 2.758ms latency[hw:1]: sw+hw 8.942ms hw 1.942ms hw_avg5 1.886ms latency[hw:2]: sw+hw 10.038ms hw 3.038ms hw_avg5 2.852ms latency[hw:1]: sw+hw 8.914ms hw 1.914ms hw_avg5 1.893ms latency[hw:2]: sw+hw 10.330ms hw 3.330ms hw_avg5 2.971ms ... ``` JSON output ----------- JSON output can be enabled by passing the `--report-format json` or `-f json` flag. By default, output is displayed in text format. Sample JSON output format for measuring latency is shown below: ``` [ {"type": "latency", "device": "hw:0", "timestamp": 1698776522962310475, "sw_hw": 10.750376, "hw": 3.417044, "hw_avg": 3.417044}, {"type": "latency", "device": "hw:0", "timestamp": 1698776523970598047, "sw_hw": 10.784796, "hw": 3.451464, "hw_avg": 3.434254}, {"type": "latency", "device": "hw:0", "timestamp": 1698776524978383608, "sw_hw": 10.928465, "hw": 3.261799, "hw_avg": 3.376769}, {"type": "latency", "device": "hw:0", "timestamp": 1698776525985503559, "sw_hw": 10.681216, "hw": 3.347884, "hw_avg": 3.369548} ] ``` All the notations are the same as mentioned in the text reports. "timestamp" field defines report time in nanoseconds since Unix Epoch. Measured values are in milliseconds. Dumping streams --------------- In any mode, you can specify `--dump-file` option to dump output and input samples and their timestamps to file or stdout (use `-`), in CSV format. To reduce the file size, the tool can dump only one (average) value per frame of the size specified by `--dump-compression` option (disabled by default). The timestamps in the dumped files correspond to the estimate time, in nanoseconds since Unix Epoch, when the sample was written to hardware or read from hardware. ``` sudo signal-estimator -vv -m latency_step -o hw:0 -i hw:0 -d 5 --dump-file dump.csv ``` There is a helper script that plots the dump file using matplotlib. You can use it to manually inspect the signal: ``` ./script/plot_dump.py [--device ] dump.csv ``` ![](./doc/dump_plot_edited.png) If dump includes multiple input devices, you should choose which one to display using `--device` option, e.g.: ``` ./script/plot_dump.py --device hw:1 dump.csv ``` ALSA parameters --------------- ALSA output and input device names are the same as passed to `aplay` and `arecord` tools. You may need to configure sample rate (`--rate`) and the number of channels (`--chans`). Selected rate should be supported by both output and input devices. You may also need to configure ALSA ring buffer size (`--out-latency` and `--in-latency`) and the number of periods (I/O frames) in the ring buffer (`--out-periods` and `--in-periods`). These parameters affect software latency and output / input robustness, but almost do not affect estimated hardware latency. If there are glitches, you can try increasing buffer size and number of periods. Note that usually both of them should be multiple of power of two. You can also configure which sample format to use (`--out-format` and `--in-format`), like `s16` or `s24_3le`. Usually signal-estimator automatically selects supported format, but you can specify preferred one if needed. Use `--list-supported` (`-L`) option to get list of all available formats. Disabling PulseAudio -------------------- If you're running a system with PulseAudio and need to use signal-estimator with hardware ALSA devices, you can temporary stop PulseAudio using: ``` systemctl --user stop pulseaudio.socket pulseaudio.service ``` Alternatively, you can set `autospawn` to `no` in `/etc/pulse/client.conf` and then run `pulseaudio --kill` or `killall -9 pulseaudio`. Disabling PipeWire ------------------ If you're running a system with PipeWire and need to use signal-estimator with hardware ALSA devices, you can temporary stop PipeWire using: ``` systemctl --user stop pipewire pipewire.socket pipewire-pulse pipewire-pulse.socket ``` Real-time scheduling policy --------------------------- If you run the tool under the `root` user, or with `CAP_SYS_NICE` and `CAP_SYS_ADMIN` capabilities, it will automatically try to enable `SCHED_RR` scheduling policy for sensitive threads. This may help to avoid glitches introduced by the tool itself (not by the hardware or software being measured) and make the measurement more stable and precise. You can disable this behavior by providing `--no-rt` option. Internals --------- This diagram demonstrates the two main threads and data flow between them: ![](./doc/flow.drawio.png) And this one shows interfaces and classes that implement them: ![](./doc/classes.drawio.png) Acknowledgements --------------- The development of this tool was heavily sponsored by Samuel Blum at Boring Technologies. Thanks a lot to him for letting the code to be open-sourced! And of course, thanks to everyone who contributed to the project! Authors ------- See [here](AUTHORS.md). License ------- [MIT](LICENSE) signal-estimator-0.0.9/cmake/000077500000000000000000000000001452044147100160645ustar00rootroot00000000000000signal-estimator-0.0.9/cmake/FindQwt.LICENSE000066400000000000000000000024571452044147100204540ustar00rootroot00000000000000Redistribution 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 copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. signal-estimator-0.0.9/cmake/FindQwt.cmake000066400000000000000000000027441452044147100204510ustar00rootroot00000000000000# Find Qwt # ~~~~~~~~ # Copyright (c) 2010, Tim Sutton # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. # # Once run this will define: # # QWT_FOUND = system has QWT lib # QWT_LIBRARY = full path to the QWT library # QWT_INCLUDE_DIR = where to find headers # set(QWT_LIBRARY_NAMES qwt-qt5 qwt6-qt5 qwt qwt6) find_library(QWT_LIBRARY NAMES ${QWT_LIBRARY_NAMES} PATHS /usr/lib /usr/local/lib /usr/local/lib/qt5 "$ENV{LIB_DIR}/lib" "$ENV{LIB}" ) set(_qwt_fw) if(QWT_LIBRARY MATCHES "/qwt.*\\.framework") string(REGEX REPLACE "^(.*/qwt.*\\.framework).*$" "\\1" _qwt_fw "${QWT_LIBRARY}") endif() FIND_PATH(QWT_INCLUDE_DIR NAMES qwt.h PATHS "${_qwt_fw}/Headers" /usr/include /usr/include/qt5 /usr/local/include /usr/local/include/qt5 "$ENV{LIB_DIR}/include" "$ENV{INCLUDE}" PATH_SUFFIXES qwt-qt5 qwt qwt6 ) IF (QWT_INCLUDE_DIR AND QWT_LIBRARY) SET(QWT_FOUND TRUE) ENDIF (QWT_INCLUDE_DIR AND QWT_LIBRARY) IF (QWT_FOUND) FILE(READ ${QWT_INCLUDE_DIR}/qwt_global.h qwt_header) STRING(REGEX REPLACE "^.*QWT_VERSION_STR +\"([^\"]+)\".*$" "\\1" QWT_VERSION_STR "${qwt_header}") IF (NOT QWT_FIND_QUIETLY) MESSAGE(STATUS "Found Qwt: ${QWT_LIBRARY} (${QWT_VERSION_STR})") ENDIF (NOT QWT_FIND_QUIETLY) ELSE (QWT_FOUND) IF (QWT_FIND_REQUIRED) MESSAGE(FATAL_ERROR "Could not find Qwt") ENDIF (QWT_FIND_REQUIRED) ENDIF (QWT_FOUND) signal-estimator-0.0.9/cmake/SetupToolchain.cmake000066400000000000000000000064031452044147100220320ustar00rootroot00000000000000if(TOOLCHAIN_PREFIX) set(CMAKE_CROSSCOMPILING ON) set(CMAKE_SYSTEM_NAME Linux) # CMAKE_C_COMPILER_TARGET set(CMAKE_C_COMPILER_TARGET ${TOOLCHAIN_PREFIX}) message(STATUS "Using CMAKE_C_COMPILER_TARGET - ${CMAKE_C_COMPILER_TARGET}") # CMAKE_CXX_COMPILER_TARGET set(CMAKE_CXX_COMPILER_TARGET ${TOOLCHAIN_PREFIX}) message(STATUS "Using CMAKE_CXX_COMPILER_TARGET - ${CMAKE_CXX_COMPILER_TARGET}") # CMAKE_C_COMPILER find_program(C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) if(C_COMPILER MATCHES "NOTFOUND") find_program(C_COMPILER ${TOOLCHAIN_PREFIX}-clang) endif() if(C_COMPILER MATCHES "NOTFOUND") message(FATAL_ERROR "Can't deduce CMAKE_C_COMPILER from TOOLCHAIN_PREFIX, define it manually") endif() set(CMAKE_C_COMPILER "${C_COMPILER}") message(STATUS "Using CMAKE_C_COMPILER - ${CMAKE_C_COMPILER}") # CMAKE_CXX_COMPILER find_program(CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) if(CXX_COMPILER MATCHES "NOTFOUND") find_program(CXX_COMPILER ${TOOLCHAIN_PREFIX}-clang++) endif() if(CXX_COMPILER MATCHES "NOTFOUND") message(FATAL_ERROR "Can't deduce CMAKE_CXX_COMPILER from TOOLCHAIN_PREFIX, define it manually") endif() set(CMAKE_CXX_COMPILER "${CXX_COMPILER}") message(STATUS "Using CMAKE_CXX_COMPILER - ${CMAKE_CXX_COMPILER}") # CMAKE_AR find_program(AR ${TOOLCHAIN_PREFIX}-ar) if(AR MATCHES "NOTFOUND") message(FATAL_ERROR "Can't detect CMAKE_AR from TOOLCHAIN_PREFIX, define it manually") endif() set(CMAKE_AR ${AR}) message(STATUS "Using CMAKE_AR - ${CMAKE_AR}") # CMAKE_RANLIB find_program(RANLIB ${TOOLCHAIN_PREFIX}-ranlib) if(RANLIB MATCHES "NOTFOUND") message(FATAL_ERROR "Can't detect CMAKE_RANLIB from TOOLCHAIN_PREFIX, define it manually") endif() set(CMAKE_RANLIB ${RANLIB}) message(STATUS "Using CMAKE_RANLIB - ${CMAKE_RANLIB}") # CMAKE_STRIP find_program(STRIP ${TOOLCHAIN_PREFIX}-strip) if(STRIP MATCHES "NOTFOUND") message(FATAL_ERROR "Can't detect CMAKE_STRIP from TOOLCHAIN_PREFIX, define it manually") endif() set(CMAKE_STRIP ${STRIP}) message(STATUS "Using CMAKE_STRIP - ${CMAKE_STRIP}") else(TOOLCHAIN_PREFIX) # CMAKE_C_COMPILER_TARGET if(NOT CMAKE_C_COMPILER_TARGET) execute_process( COMMAND ${CMAKE_C_COMPILER} -v -E - INPUT_FILE /dev/null OUTPUT_VARIABLE COMPILER_STDOUT ERROR_VARIABLE COMPILER_STDERR RESULT_VARIABLE COMPILER_STATUS ) if(COMPILER_STATUS EQUAL 0) string(REPLACE "\n" " " COMPILER_STDERR ${COMPILER_STDERR}) string(REGEX MATCH "[ ]+Target:[ ]*([^ ]+)[ ]+.*" RESULT ${COMPILER_STDERR}) set(CMAKE_C_COMPILER_TARGET ${CMAKE_MATCH_1}) endif() if(NOT CMAKE_C_COMPILER_TARGET) message(FATAL_ERROR "Can't detect target platform of C compiler ${CMAKE_C_COMPILER}") endif() message(STATUS "Using CMAKE_C_COMPILER_TARGET - ${CMAKE_C_COMPILER_TARGET}") endif() # CMAKE_CXX_COMPILER_TARGET if(NOT CMAKE_CXX_COMPILER_TARGET) set(CMAKE_CXX_COMPILER_TARGET ${CMAKE_C_COMPILER_TARGET}) endif() message(STATUS "Using CMAKE_CXX_COMPILER_TARGET - ${CMAKE_CXX_COMPILER_TARGET}") # CMAKE_* foreach(VAR IN ITEMS C_COMPILER CXX_COMPILER AR RANLIB STRIP) message(STATUS "Using CMAKE_${VAR} - ${CMAKE_${VAR}}") endforeach() endif(TOOLCHAIN_PREFIX) signal-estimator-0.0.9/cmake/ThirdParty.cmake000066400000000000000000000133311452044147100211610ustar00rootroot00000000000000include(ExternalProject) include(ProcessorCount) ProcessorCount(CPU_COUNT) set(LIBPREFIX ${CMAKE_STATIC_LIBRARY_PREFIX}) set(LIBSUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX}) function(checkout_submodule DIRECTORY) if(NOT EXISTS ${DIRECTORY}/.git) if(NOT GIT_EXECUTABLE) find_package(Git REQUIRED) endif() message(STATUS "Checking out ${DIRECTORY}...") execute_process( COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive . WORKING_DIRECTORY ${DIRECTORY} RESULT_VARIABLE GIT_EXIT_CODE ) if(NOT GIT_EXIT_CODE EQUAL "0") message(FATAL_ERROR "Failed to check out ${DIRECTORY}") endif() endif() endfunction(checkout_submodule) # alsa if(CMAKE_CROSSCOMPILING) ExternalProject_Add(alsa_lib URL "https://www.alsa-project.org/files/pub/lib/alsa-lib-1.0.29.tar.bz2" SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/3rdparty/alsa-src BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/3rdparty/alsa-build PREFIX ${CMAKE_CURRENT_BINARY_DIR}/3rdparty/alsa-prefix CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env CC=${CMAKE_C_COMPILER} CCLD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} STRIP=${CMAKE_STRIP} ${CMAKE_CURRENT_BINARY_DIR}/3rdparty/alsa-src/configure --host=${CMAKE_C_COMPILER_TARGET} --enable-shared --disable-static --disable-python BUILD_COMMAND make -j${CPU_COUNT} INSTALL_COMMAND make install DESTDIR= LOG_DOWNLOAD YES LOG_CONFIGURE YES LOG_BUILD YES LOG_INSTALL YES ) include_directories(SYSTEM ${CMAKE_CURRENT_BINARY_DIR}/3rdparty/alsa-prefix/usr/include ) link_libraries( ${CMAKE_CURRENT_BINARY_DIR}/3rdparty/alsa-prefix/usr/lib/libasound.so ) else(CMAKE_CROSSCOMPILING) add_custom_target(alsa_lib) find_package(PkgConfig) pkg_check_modules(ALSA REQUIRED alsa) include_directories(SYSTEM ${ALSA_INCLUDE_DIRS} ) link_libraries( ${ALSA_LIBRARIES} ) endif(CMAKE_CROSSCOMPILING) # kissfft checkout_submodule( ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/kissfft ) ExternalProject_Add(kissfft_lib SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/kissfft BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/3rdparty/kissfft-build PREFIX ${CMAKE_CURRENT_BINARY_DIR}/3rdparty/kissfft-prefix CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} -DCMAKE_C_COMPILER_TARGET=${CMAKE_C_COMPILER_TARGET} -DCMAKE_CXX_COMPILER_TARGET=${CMAKE_CXX_COMPILER_TARGET} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_AR=${CMAKE_AR} -DCMAKE_RANLIB=${CMAKE_RANLIB} -DCMAKE_STRIP=${CMAKE_STRIP} -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DKISSFFT_PKGCONFIG=OFF -DKISSFFT_STATIC=ON -DKISSFFT_TEST=OFF -DKISSFFT_TOOLS=OFF -DKISSFFT_USE_ALLOCA=OFF LOG_DOWNLOAD YES LOG_CONFIGURE YES LOG_BUILD YES LOG_INSTALL YES ) include_directories(SYSTEM ${CMAKE_CURRENT_BINARY_DIR}/3rdparty/kissfft-prefix/include/kissfft ) link_libraries( ${CMAKE_CURRENT_BINARY_DIR}/3rdparty/kissfft-prefix/lib/${LIBPREFIX}kissfft-float${LIBSUFFIX} ) # concurrentqueue checkout_submodule( ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/concurrentqueue ) include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/concurrentqueue ) # intrusive_shared_ptr checkout_submodule( ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/intrusive_shared_ptr ) include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/intrusive_shared_ptr/inc ) # spdlog checkout_submodule( ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/spdlog ) ExternalProject_Add(spdlog_lib SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/spdlog BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/3rdparty/spdlog-build PREFIX ${CMAKE_CURRENT_BINARY_DIR}/3rdparty/spdlog-prefix CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} -DCMAKE_C_COMPILER_TARGET=${CMAKE_C_COMPILER_TARGET} -DCMAKE_CXX_COMPILER_TARGET=${CMAKE_CXX_COMPILER_TARGET} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_AR=${CMAKE_AR} -DCMAKE_RANLIB=${CMAKE_RANLIB} -DCMAKE_STRIP=${CMAKE_STRIP} LOG_DOWNLOAD YES LOG_CONFIGURE YES LOG_BUILD YES LOG_INSTALL YES ) include_directories(SYSTEM ${CMAKE_CURRENT_BINARY_DIR}/3rdparty/spdlog-prefix/include ) link_libraries( ${CMAKE_CURRENT_BINARY_DIR}/3rdparty/spdlog-prefix/lib/${LIBPREFIX}spdlog${LIBSUFFIX} ) # cli11 checkout_submodule( ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/cli11 ) ExternalProject_Add(cli11_lib SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/cli11 BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/3rdparty/cli11-build PREFIX ${CMAKE_CURRENT_BINARY_DIR}/3rdparty/cli11-prefix CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} -DCMAKE_C_COMPILER_TARGET=${CMAKE_C_COMPILER_TARGET} -DCMAKE_CXX_COMPILER_TARGET=${CMAKE_CXX_COMPILER_TARGET} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_AR=${CMAKE_AR} -DCMAKE_RANLIB=${CMAKE_RANLIB} -DCMAKE_STRIP=${CMAKE_STRIP} -DCLI11_BUILD_TESTS=OFF -DCLI11_BUILD_EXAMPLES=OFF LOG_DOWNLOAD YES LOG_CONFIGURE YES LOG_BUILD YES LOG_INSTALL YES ) include_directories(SYSTEM ${CMAKE_CURRENT_BINARY_DIR}/3rdparty/cli11-prefix/include ) # serialize dependencies set(ALL_DEPENDENCIES alsa_lib kissfft_lib spdlog_lib cli11_lib ) list(REVERSE ALL_DEPENDENCIES) set(OTHER_DEPENDENCIES ${ALL_DEPENDENCIES}) foreach(DEPENDENCY IN LISTS ALL_DEPENDENCIES) list(REMOVE_ITEM OTHER_DEPENDENCIES ${DEPENDENCY}) if(OTHER_DEPENDENCIES) add_dependencies(${DEPENDENCY} ${OTHER_DEPENDENCIES} ) endif() endforeach() signal-estimator-0.0.9/doc/000077500000000000000000000000001452044147100155515ustar00rootroot00000000000000signal-estimator-0.0.9/doc/GoogleFonts.LICENSE000066400000000000000000000261361452044147100210130ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. signal-estimator-0.0.9/doc/README.md000066400000000000000000000003221452044147100170250ustar00rootroot00000000000000Most diagrams in this directory are created using [drawio](https://www.drawio.com/) editor. Some of the diagrams use icons from Google Fonts, licensed under [Apache License, Version 2.0](GoogleFonts.LICENSE). signal-estimator-0.0.9/doc/classes.drawio000066400000000000000000000322071452044147100204210ustar00rootroot00000000000000 signal-estimator-0.0.9/doc/classes.drawio.png000066400000000000000000002165041452044147100212100ustar00rootroot00000000000000PNG  IHDR+'ƓsRGB\LtEXtmxfile%3Cmxfile%20host%3D%22Electron%22%20modified%3D%222023-09-16T16%3A44%3A33.739Z%22%20agent%3D%22Mozilla%2F5.0%20(X11%3B%20Linux%20x86_64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20draw.io%2F21.7.5%20Chrome%2F114.0.5735.289%20Electron%2F25.8.1%20Safari%2F537.36%22%20etag%3D%22oMvlYLeR2QCMj_ZwP--Q%22%20version%3D%2221.7.5%22%20type%3D%22device%22%3E%0A%20%20%3Cdiagram%20name%3D%22Page-1%22%20id%3D%226iL3JdZxS18NPe7An8-a%22%3E%0A%20%20%20%20%3CmxGraphModel%20dx%3D%222092%22%20dy%3D%22865%22%20grid%3D%221%22%20gridSize%3D%2210%22%20guides%3D%221%22%20tooltips%3D%221%22%20connect%3D%221%22%20arrows%3D%221%22%20fold%3D%221%22%20page%3D%221%22%20pageScale%3D%221%22%20pageWidth%3D%22850%22%20pageHeight%3D%221100%22%20math%3D%220%22%20shadow%3D%220%22%3E%0A%20%20%20%20%20%20%3Croot%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%220%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%221%22%20parent%3D%220%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-39%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Bdashed%3D1%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22-20%22%20y%3D%22350%22%20width%3D%22370%22%20height%3D%22160%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-38%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Bdashed%3D1%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22360%22%20y%3D%22350%22%20width%3D%22430%22%20height%3D%22160%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-37%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Bdashed%3D1%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22360%22%20y%3D%22120%22%20width%3D%22430%22%20height%3D%22220%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-36%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Bdashed%3D1%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22-20%22%20y%3D%22120%22%20width%3D%22370%22%20height%3D%22220%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-35%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Bdashed%3D1%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22-20%22%20y%3D%22520%22%20width%3D%22370%22%20height%3D%22150%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-1%22%20value%3D%22%26lt%3Bb%26gt%3BIDeviceWriter%26lt%3B%2Fb%26gt%3B%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23d5e8d4%3BstrokeColor%3D%2382b366%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20y%3D%22540%22%20width%3D%22120%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-2%22%20value%3D%22%26lt%3Bb%26gt%3BAlsaWriter%26lt%3B%2Fb%26gt%3B%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22180%22%20y%3D%22540%22%20width%3D%22120%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-3%22%20value%3D%22%26lt%3Bb%26gt%3BIDeviceReader%26lt%3B%2Fb%26gt%3B%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23d5e8d4%3BstrokeColor%3D%2382b366%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20y%3D%22610%22%20width%3D%22120%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-4%22%20value%3D%22%26lt%3Bb%26gt%3BAlsaReader%26lt%3B%2Fb%26gt%3B%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22180%22%20y%3D%22610%22%20width%3D%22120%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-5%22%20value%3D%22%26lt%3Bb%26gt%3BIGenerator%26lt%3B%2Fb%26gt%3B%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23d5e8d4%3BstrokeColor%3D%2382b366%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20y%3D%22210%22%20width%3D%22120%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-6%22%20value%3D%22%26lt%3Bb%26gt%3BImpulseGenerator%26lt%3B%2Fb%26gt%3B%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22180%22%20y%3D%22140%22%20width%3D%22150%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-7%22%20value%3D%22%26lt%3Bb%26gt%3BContinuousGenerator%26lt%3B%2Fb%26gt%3B%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22180%22%20y%3D%22280%22%20width%3D%22150%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-8%22%20value%3D%22%26lt%3Bb%26gt%3BStepsGenerator%26lt%3B%2Fb%26gt%3B%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22180%22%20y%3D%22210%22%20width%3D%22150%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-9%22%20value%3D%22%26lt%3Bb%26gt%3BIEstimator%26lt%3B%2Fb%26gt%3B%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23d5e8d4%3BstrokeColor%3D%2382b366%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22380%22%20y%3D%22210%22%20width%3D%22120%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-10%22%20value%3D%22%26lt%3Bb%26gt%3BCorrelationLatencyEstimator%26lt%3B%2Fb%26gt%3B%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22560%22%20y%3D%22140%22%20width%3D%22210%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-11%22%20value%3D%22%26lt%3Bb%26gt%3BLossEstimator%26lt%3B%2Fb%26gt%3B%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22560%22%20y%3D%22280%22%20width%3D%22210%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-12%22%20value%3D%22%26lt%3Bb%26gt%3BStepsLatencyEstimator%26lt%3B%2Fb%26gt%3B%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22560%22%20y%3D%22210%22%20width%3D%22210%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-14%22%20value%3D%22%26lt%3Bb%26gt%3BIReporter%26lt%3B%2Fb%26gt%3B%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23d5e8d4%3BstrokeColor%3D%2382b366%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20y%3D%22410%22%20width%3D%22120%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-15%22%20value%3D%22%26lt%3Bb%26gt%3BJsonReporter%26lt%3B%2Fb%26gt%3B%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22180%22%20y%3D%22450%22%20width%3D%22120%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-16%22%20value%3D%22%26lt%3Bb%26gt%3BTextReporter%26lt%3B%2Fb%26gt%3B%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22180%22%20y%3D%22370%22%20width%3D%22120%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-17%22%20value%3D%22%26lt%3Bb%26gt%3BIDumper%26lt%3B%2Fb%26gt%3B%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23d5e8d4%3BstrokeColor%3D%2382b366%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22380%22%20y%3D%22410%22%20width%3D%22120%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-18%22%20value%3D%22%26lt%3Bb%26gt%3BCsvDumper%26lt%3B%2Fb%26gt%3B%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22560%22%20y%3D%22450%22%20width%3D%22120%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-19%22%20value%3D%22%26lt%3Bb%26gt%3BAsyncDumper%26lt%3B%2Fb%26gt%3B%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22560%22%20y%3D%22370%22%20width%3D%22120%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-20%22%20value%3D%22%22%20style%3D%22endArrow%3Dblock%3Bhtml%3D1%3Brounded%3D0%3BendFill%3D0%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22GBvXgYhu6KNHDGZjgeu1-2%22%20target%3D%22GBvXgYhu6KNHDGZjgeu1-1%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22560%22%20y%3D%22940%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22610%22%20y%3D%22890%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-21%22%20value%3D%22%22%20style%3D%22endArrow%3Dblock%3Bhtml%3D1%3Brounded%3D0%3BendFill%3D0%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22GBvXgYhu6KNHDGZjgeu1-4%22%20target%3D%22GBvXgYhu6KNHDGZjgeu1-3%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22-290%22%20y%3D%22640%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22-330%22%20y%3D%22640%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-22%22%20value%3D%22%22%20style%3D%22endArrow%3Dblock%3Bhtml%3D1%3Brounded%3D0%3BendFill%3D0%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22GBvXgYhu6KNHDGZjgeu1-6%22%20target%3D%22GBvXgYhu6KNHDGZjgeu1-5%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22180%22%20y%3D%22110%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22140%22%20y%3D%22110%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22150%22%20y%3D%22160%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22150%22%20y%3D%22230%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FArray%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-23%22%20value%3D%22%22%20style%3D%22endArrow%3Dblock%3Bhtml%3D1%3Brounded%3D0%3BendFill%3D0%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22GBvXgYhu6KNHDGZjgeu1-8%22%20target%3D%22GBvXgYhu6KNHDGZjgeu1-5%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22180%22%20y%3D%22237%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22140%22%20y%3D%22246%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-24%22%20value%3D%22%22%20style%3D%22endArrow%3Dblock%3Bhtml%3D1%3Brounded%3D0%3BendFill%3D0%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22GBvXgYhu6KNHDGZjgeu1-7%22%20target%3D%22GBvXgYhu6KNHDGZjgeu1-5%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22190%22%20y%3D%22247%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22150%22%20y%3D%22256%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22150%22%20y%3D%22300%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22150%22%20y%3D%22230%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FArray%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-25%22%20value%3D%22%22%20style%3D%22endArrow%3Dblock%3Bhtml%3D1%3Brounded%3D0%3BendFill%3D0%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22GBvXgYhu6KNHDGZjgeu1-10%22%20target%3D%22GBvXgYhu6KNHDGZjgeu1-9%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22190%22%20y%3D%22257%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22150%22%20y%3D%22266%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22530%22%20y%3D%22160%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22530%22%20y%3D%22230%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FArray%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-26%22%20value%3D%22%22%20style%3D%22endArrow%3Dblock%3Bhtml%3D1%3Brounded%3D0%3BendFill%3D0%3BfontStyle%3D1%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22GBvXgYhu6KNHDGZjgeu1-12%22%20target%3D%22GBvXgYhu6KNHDGZjgeu1-9%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22200%22%20y%3D%22267%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22410%22%20y%3D%22280%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-27%22%20value%3D%22%22%20style%3D%22endArrow%3Dblock%3Bhtml%3D1%3Brounded%3D0%3BendFill%3D0%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22GBvXgYhu6KNHDGZjgeu1-11%22%20target%3D%22GBvXgYhu6KNHDGZjgeu1-9%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22210%22%20y%3D%22277%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22170%22%20y%3D%22286%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22530%22%20y%3D%22300%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22530%22%20y%3D%22230%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FArray%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-28%22%20value%3D%22%22%20style%3D%22endArrow%3Dblock%3Bhtml%3D1%3Brounded%3D0%3BendFill%3D0%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22GBvXgYhu6KNHDGZjgeu1-16%22%20target%3D%22GBvXgYhu6KNHDGZjgeu1-14%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22230%22%20y%3D%22287%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22190%22%20y%3D%22296%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22150%22%20y%3D%22390%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22150%22%20y%3D%22430%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FArray%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-29%22%20value%3D%22%22%20style%3D%22endArrow%3Dblock%3Bhtml%3D1%3Brounded%3D0%3BendFill%3D0%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22GBvXgYhu6KNHDGZjgeu1-15%22%20target%3D%22GBvXgYhu6KNHDGZjgeu1-14%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22240%22%20y%3D%22297%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22200%22%20y%3D%22306%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22150%22%20y%3D%22470%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22150%22%20y%3D%22430%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FArray%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-30%22%20value%3D%22%22%20style%3D%22endArrow%3Dblock%3Bhtml%3D1%3Brounded%3D0%3BendFill%3D0%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22GBvXgYhu6KNHDGZjgeu1-19%22%20target%3D%22GBvXgYhu6KNHDGZjgeu1-17%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22240%22%20y%3D%22307%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22200%22%20y%3D%22316%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22530%22%20y%3D%22390%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22530%22%20y%3D%22430%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FArray%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22GBvXgYhu6KNHDGZjgeu1-31%22%20value%3D%22%22%20style%3D%22endArrow%3Dblock%3Bhtml%3D1%3Brounded%3D0%3BendFill%3D0%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22GBvXgYhu6KNHDGZjgeu1-18%22%20target%3D%22GBvXgYhu6KNHDGZjgeu1-17%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22250%22%20y%3D%22317%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22210%22%20y%3D%22326%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22530%22%20y%3D%22470%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22530%22%20y%3D%22430%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FArray%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%3C%2Froot%3E%0A%20%20%20%20%3C%2FmxGraphModel%3E%0A%20%20%3C%2Fdiagram%3E%0A%3C%2Fmxfile%3E%0An IDATx^_%DsN$' 'wG9 %I*YH2Tw}33sŐnFOW9İ%[NC6~Ťw(3Ufs+U%$cwlYq#Bw_#sEJbCFN;-k˲nb,;k;DŽBz,^v5|f~gz)'/B„b/kZ{wny՞WY2tUXYSAZ 1a2C5;3؉S 8/>ϜIJ3q(^I*ޮj/?bp. VΟu*B4iQV#X< )^I@v}xg+_(3*רu1= f1-$?'@&_<+D/vfذf)߻\DdcN6̩c8}(`ohK/ϣdH(q +V.Bn,0q\8x]7z3o6Xٶi Ry ikvf7+FXWL'޴n:iQ$GJ4j,C;mrྜྷ1hd̟9A9~cQVCW(UFr._JUkE&c~Յǂ"_ضCނE1llZ:?0r,?Uk!|LOTr,ZEKGV_ݮsO 7|q$RJ ([/t*xdXb28'EJ:n>޼BLYye f`֔Qy7-P&/@i[(-c*z#ظ_]U}/b*Ay3z[y>  gnjEQr ݹV!G<FmF Rh'±:wZtwإC V~aAEM CFNAbk5+sPsoHK8jU,fVwlBEK)$6wќ0yȆYN=ѡ[?՗`+'F$/ChڲzohX8{c;>5O'>uLUt=54Ʀѣc38u5W~~Sls zun2+g=&;ߺctjY-vŀq:W;mThfeGk6/G?A5뽫>ߺq5$ȭ\s=疝vB̚< ?#2gˉcPq%Cpk)}NU~|O3hI O+ V\?[wo.]ıbhո*8 dHS7 6XMZ j+ t4̛>#F!cԺ6i E݁{R$y *Ɋ)^s*(w[4N $RBA7x1JMS }̨Ӱ'H Qtn`joja6j>;5| 꿋m ~Ȝ-YU ݷ0v5]ݘ1yT0:r1Cm'{'D<B,H&jA-P4رe*p2H>*޸. VGk|R2j*zu~/<^ĮI՟Wa9j`ea?b zk2#b| /A}:@s  '٫xn`x#-]6boT$eL#Mb=js)}*rǝ< %F2yÇ-Yj,:*^ƄWҟIR ^[7_4Xq9>F(^"fN YyJ3zFn?rHD>U>rIm>6-e 5x5^MVL5f7Tyk伴:yQt p$2kFځ1I?i 996 ##j#Ox畤u*CT6ڱ3/ra˼<,T}Z*Phܼnݼ_`EڸI1ݽ73%QϞc_?V,X#AJiʗ^9%kw)b)GϬd= 0Gʏ wcTVt7B{éH%Vν3xj[tUְ%<?1cs_+An;#>Hn<6Mc8zWZْ%!_W-/]-W͕uPfyOޗ)yqgoF)͕'̊)qU8q;gQT.$H0FJ.둗 KLǞ6,۰W]:dTU. V$Й26~UM.'J|<~hv'ticgửZ.S}ɏgR\Y+|uș'yVdUj$V5^BuɞMtmH3'0OgUZ(Y I 掝/c\lryNv#$$%vW>F+XKJ\rػwe({Xw#+:9/"F!*5jϯl;}Jz!'os5) 2q(?| ؔ%0cjw.F2A;%˯RUu#ME$K`ݘ [έʴT(R^ñrlHiԮtlwѥ#\P8]R6rBF:l^ )PCH|-KGg3+rVBYcILYR%eIR*rYR+9z·ɑ;?̩*-WY~2z*P]hm`okSFG[ͧB6lMB9$ep䑊 )s.~GYiP::6,_4K]rw)0f&=U ċ2*َ$(CꏥjT߳2wf`E2'. 䑚G iѬMgYWZ88 9(7[=*ȑ'?Ʃ@Fv)HZ^|)KKo gɮnmVLR>n4kڪ#v>s]";jdӰ9,^PqK 1Y+w)S33R-—ÖJ1BdLB^2#ח/"c6JSx؀ \x_K=B ybx.ƍ]^A#?[B6 q.HId~RHy?-Ll9\)LƑr.?nx0>Z\/]MRa:>۲J6JGN\¦Ԯd>. +ؽ:Gᎏ'y*j>?/T+V)V*=t ̊OF䕛lXe+sQ&H+RB}<|p_(*1a;_A} ȕNP%yYYXfL92Su03+?V/|A_ 30X?NE{nlVQ a7&N" 3.nu5AɬH_ԨLRسc:;kRo Vw=jjj k1~Ӟ NLvYpܾuClݦf7G5b-M csK7cixhbNo<`㤩y9IƜAה;IK0ÿ1X UdyTq;JFsb&'w69@#`cX"Η˦ؖ VႴ{;h2@L V"Ȝ,Mp1$`1 B=!6pZ<` 7vb6:/ _0ژ~?t"' k2XZ$ X^؃y23N\73 @{eA%`{+m8~iJݜ8l8u:t^Nl`hc9kwf9@ `cX ̑J" au2CmM${f7> y62\7tQNyQˈ3?)ƌWx muM9),o,8輼F,D c,`{e+3U\.)nPF 0ÿ1Xz( 4'3l,Dv"@{o'mQVxe`\e /e 84 0 Jޯ98 X[N%(*t^\$= #";:(# 7+aQ$@%@hvYשUDIg g97輼wN@q:/t׳gAH .}輼WOAUP(us$*cUbt^ve$  {ϐ= It\\Ngj{/Up wR8%:/'js2nQُNͤ˾I^xy9ytIԟ96 Xo>(t^\$=nIt׳?e$@!|Ù@±8V91T;'MQm`\!@eUQP W2 8osJ9!:/gꕳ-f`|˛Ŏ}-p*T:l^t^S(c( #C3pݒ 60*-PE Ts:ttd0שYd/ ؏oVb:U='A@MH441 e60˨x"@?d BYΛ;t@l 6ؒ{>'@sHB/9( Xoj(أ輸H{xϐ=O|DI[,+W+SH@7#J6S ("E60(bx&@[.n%ə[ש@Hx5@)4yi@b%,HNt׳%$@m`eF2&r!Nh`χ>ٓx׃myFUH"@{>L#RgN˙z|Kh#@{;n|J9UJ@7P$\&e$`C ̆J TUn;1ن"ujYK#짳+`Uωk~f`D IDAT4d0z6MvL$` 2 yy"@־N{6e`v;`T{L%%ʕ3=ɓ=r(Zm#CШE#44NlC{ڞ|+?L8y&LdP{ BCѾKg{n~'̓C'ELgk7ЩW' ~ gSԵGN"qhۭ-|G7"d^R4a∉زn+ݻE "xLR}&N޻u(Q",_w iXZxr^m۶ٳ;li,ae^tmt&O}vUJTG.puk،N-=M]1 lsO⋳'2UO@يryt~b*Vg.SFÇ;m{`Q 7+7.ٟ.ޔaxThԬwe:.W~sUQ|~ CvԱOQ[0s9ĉÐ6/Z>?9-Wq浐 b#l@7lݸb+W13sa n>ygJWѶs/4hJ9q`5@yӢ 6ژa̝|XT^ v0Y|˲!v2_8vmۭ|Aނy6._KJGE|420|{$O EK 1x AF{"e'#ُۤנRZn/ϣjh׹7N ϞBm{ޏ?|MbЉx!n\eˬxcBoŗazVLF$mEo,YBGMǃP`&nL!y" d.ʬY˿z!HeԬP};.$/X֪X03Wf(#,C*`L-\`뿩*Q e4-̖&6:kW1_9,UCQVC?T˝4^o=`:uޭ;BޝaQ#?L_CƠfNtkԃ<=έPn +׻c͐?^&՛Zjhٱ%#lRn:%@NB#x*V.\`*萒у`X~*[K13'¤#^KA![(odyCy{95xlUŰutJܹqYۦMPF쾹W-U0Qp nF/+ bV,1?tjH&-dE(C;-^JL~=B_.﮽)9ogLI%G(^ʞLs-G9q4^54F=0o@HZWPT.exƫdyh=Wj)C;yjr'Ȯ[P\e\'ʛI@ Qa3OPXp&v>|qC0~RT-; E utʨ]ׯTJ ѣc35f2PxM K7tFՙ\ 艙Yq.XM#q=I%U%+DX0L;Ilh0h@WpN8!C Vdi1i$kxNsqÔi Z`NQ!rl^غC,[GPM1|h vq2hN-Q۽5y>]&).X=䯊N{cP$HH0o!cm;B|УS3TR f.CUPqO^q'8X4{ VFNBK+qT[ft[7bՒXA&Yk``Ԥ}Wa9XdNd+(~>;6Z5*%ƍH7Ef5Ѱiwe3C{UXhަ Orᄑ*0\ezA_ucsTЪ~kt2gDP` :} jvޫ|؀ضq٧ ۰^x9:>N9ϾT8|tp @vlމcӁȔ%Ɔżiѭ_W1J@!/">\z Qx!N8'Ϭ)WWeK٦hS5ǿ9FU쩳Xi1M'W+`޽ȑ#'g,q{tzڲqr,OIE1tRu  wZWcZ# BΟ *W< W f4qQTy EsbI7}̊+<kxd*܏.\RN_Kh' K DgƋ))Cv]ɴH[ؿg;e*"K*p{W8H`%E73&QhCwp;|asW #AX Z *ՙ4icj9Sͪ]hrH0Yq+ }8uSZQU9H_6eMϗʗ^KR^նJ>hN_/'g_؇ߝ@naU.&Kt>sŚ]kFliu>v| F1笚v <%R'*oKkяjWN&ᘭ"/[Kҵ(,YReR\AJUdY;wPɢ7J ԾSd $;!NgS#iӱJK*kXq9ٗݠU Ç*;#Fu͇ͪɁݪj͊`eȁ >W9 IMQ+ AǠַFټ*0,8Nq4?zWJrΏ5>;C"TZK}$ԧ*Ӓ`J}{ U͢d4Yp_Q4WjmBeގ6M:W?v[fs)X!X,Aϑ;*{.B{ )S$GT^ѭuu]Ә|e+lq,ٸ:s@ V\DYƓcgΖ]\2oEwZbݥBo5RPcOJ~|gy#'X5zH]7qwO-esMZL*)w+RQ /C6 +)1M0YsrlOeGUJR.س]eBdO6) #TlNJR  V$S̛OMy΃bKno-o;`#ẙrVgI|K_woWJӚp+<ˣOtiЧch)ǒ,ɈJ2P`e׉HD>|7:ʎ-ѩU}H2rN~a) Uݗ\71Gά '7ŕnIɬDY9ޗ_"2G%.X?b`TڍIu&Cv_P]s.X=+-UQ?]^xA"QNLPK۾ߨY\JtgV$HdspE6~(\xѕʧb*pdQS":QFUIzwŦn _]lxfQX4sT,/'՛5GV,C ! wܘ>v:^I FNˬ|yKԫPUjU;5Vg_ VTK VqG̕7q)Ex1eT%G`u$NsgǬ0qgVRR,WB_`E2+%JsTfȚ6Y=~8 9\ѢMW$K+V~Γk^mrB~W./ɣXr!FOG"%Urt=:P?4lh aTh_m|vm߄[9H)Y_VV!A]<Vlm"W]6;0b\N&M[`Nªwm*XL٥l :>JѬ*+x8V.<9tT]f+}T='kыM`LX]핳/NάUPQs&ω6Xt:u+/.TyR ^0$NDxLo`%q9V*,K$/{Pk7a#TnˎxVXcO]"gCLd *9Sd9L[V ,R꜋<VX)U%뾣. [5{Ny\4M_|Vl9y9"k\gVt{%Ujʛ^eʬ۽ gW1uPR2,Y[/|Y"G|3pnݺER 1GR 4k]{Ź (Ud-N[nic`ܰ nY7nǔ1SUf&C2˨]"M3 f,D0l0 ?TezaU>S@woνy~.D`%rz,hɖ-t=I z^8~U%NGpuuo@ug[7~Icݨ([Z$XRd~vVaw.WHj]$葃|~3 ¥tEEW2+?t30K`œY̳ʭs"GFg{QK_tWF{rܷ]ƌ#X=ټ@NDNؽMcKܙgH[2Pg9]T 5M t~cw]~W?U3# 3rdlwSWtϊ`՟~@d)PasuwU\S%LRART7)r+Z6mZ ܪ+5Vҫ7nA#&+E&l42:#>R2prvI,۔O#:YQJ}:+  ȐU `j֭[c;7 6#=yވ>ه16H^Ĝޠ'{{pĘ:93AN%DDDD8uCy9D)tL&SMPlF@@@N"9E@1KNK:t׳N_lC$`o*XaZJ EӜgl0 5cUV "m`gcI+ ،FqId,3071K``&oES|C}ÙxIK|t~ 39SǨ! 60_icGvvd@C9LH[ [|g|ِC7cCAt׳̩ DCqi؆mTEA@AsHޛ60۩,p \s$@E>ْ' !~n t^P9f`l>@i& K˿9 !Y[?\\ $@. k6l* v~$H\\ $@. k6l*  !I Sxm̈́(( HA0ٕ ],CYF:/O9 83YQxQ$ُL30hO $`0f0Pvg:/sWg B=r> Sk#} L[-M@ғp'uxs$MibC8 ~?t30V+es>|! o :/ۨ?@琦7 -;&m`SY LI}`雳%Ox'B, as\">}($M Lstk B=)NH\xׂmyFUt0INH\xׂmyu6(L*k a#ݾB{o4QoDDDD*L>鼺6)eP&-;#9[Bjf$`Af7+T4EzWm̝Ćs!{/3oz(Jݎ\30:hO'`m`!:/P0ژ!8֩Yaٯ'f7+~P$9:3%`1~足.9JN&`cZc2#;3])`J>@i;4? :/8fh1gHsw9C0ÿ1Xqzq΀<;JL0ÿ ,]KeWQauH3CmM${f7> y62\7tQNyQˈ3?)ƌWx muM9),o,8輼F,D c,`{e+3U\.)nPF 0ÿ1Xz(ɭd'{pX<w~BJ#| Lkݬ[NE18׳xft |&g?Q\e 0%6c8C,_8 BN@J /N6 Ih}Əa[9u <=NCѾK_Ȉo!aDO7'zf7b۴輖Ο! g(\4̛<`^ۭ5p6`/p*ڿ*bihܼBGMOL:z|ߡ\1s dZ-Xa2` CEWRDYP5r.B|=mEӭU>ѓ( Δ`@NP>gS0<?I%WY >Ǩ (q]&?rQ|~ CvԱOQ[0s9ĉ ~}] I^| ϞB#?z4ҩU}>yA}C1*/<|~]c?-BzvP^@u1pD7.|}: *U'(s=;6mp)\8wKAp 7/"mL2rǝvǝ2{bVĿ60jr=F+gȒ-'89wjAfw1*~*vr)6^^lf,Zk@v7IU9rS?߻.%sjɜo[ףf&xF=2uqH֡B,H&zWF V-};c*`V6=>s-ۯ"%O ~~ @:Ѻc ERp noV G乫˵ _soArqP*o:$M3dF?ABnĠ>w(<|ㆇ`^~} +˜: @S"unlZ=:6Sc,S A1ژ~?t? k2XOR&Lx-]F j);_<΍APruL݆]q UNj3Jڤ6j|\vU.MR[JF >IJ{7^|ϘYmpċƘ1c\'QKIcȨ= v͝vǝwʗcXK rX믿3m|t]O+l@wudﱯUeK"F{ȩj׾~7d Z?~Y`eˆU8|8~0N|um=ܺFN~ܻK=`U ײCr? {(V޼N "5hH`Z 4y\>5;&\{wLIRdsjS96FboKρyl\e`.٢wVk`[Ukau2I Djޤi[wy|d(o'm~2yPb5$K*SZ ֶ1َnDj#G6ď̊+*R/*5kAy:ƋDNU&G GM|_o<`Crʝ!Jso}BMѺԮmaۦ58e n5ȉ'ac{!jGΦHуUJB clh _yҦJOƵگ+,ی~E\QQ U.X`P_B&U^EsVUU՚ !52G._HZ igdAʬA}ȝk}CRj-L'A>US"9y6oXM V̟ѦIuU'u:ƜAu +{ӕ]R$g*Kʊ# c*͗3'ĜcpMZu@XW"VbJ6:~ݥ%ND&`eUj3KɊKv>|7W:ʎ-q+,Te:\gL! ;]9+rR_#o?Z6ߤ<9:o9_9mPܶQUjDwf9Pgoy'VR C5=M7` $Xo,pWü~ȑ%VƲ;O!?kkά S/2+)_ƸKխRYPA޻w79ԏt)eV\JrFDAsI: ShVHpXd*˒yd&U)Ka%LvjgjGk0|$LHh)ھ ﷨)Q;UUVC4yʲ\<VlQypuy0r6m(w\ ڦ%._E.ϟڋ*a6NZ.9wάc`S;9@<Ҭug&ҜdMdjLl ^<)g|&ٹ:(ɤ?? V LļU%IѽoʲuhcఉJ6F.i@IYNw>Q|pt7F浕)[:{/?vG-) oφHLʂYqu/\\.%򈡞9i$~vo \C'\ݕ}~3jn)I(1&Yb%EyC%̚m";ab܊%!s=u4Q% RAIҡsTPӵJKzqHX#;y<6N],;}nߺj3)4f~UNApU쉏Yl*[SudBzW%I#A0~% EYK6yc`E7WyMNن<{N)Z]GH!7'F͸hruIadSr+ݙErʥ4Pqx 2j:c(df"G?A"б{.OػSJѵMC> RjRa"EJe0XVx,b @r^dQ0ژ!6Duhf7%(t^Re&c1m`Q/){*b[-b c5t^Vӈ31ژ떁9gA7+{ ,f7+8!06"`1H! X^؃ y9X~\g:Pb@%@{缍$`{"4t^NӨ5c1 Bx$@{oMP*{0ÿ1X>&@c2\7m j4I1\$=3 {p0:/+׏S3Ø60?*C;#ITomt^֏]3ژ떁ٕ&_etf7+N_5W輼Ǘ!`1'h  {ϐ=e`\W$0:r2Cm}j6r:/ǩ2ژ!<`o Sb(j PX_5hc -p$8{e`=8ǩayʡAj$L ~V*6:/kǮmuʋr/2p:3+t^^0ژ4 hgH 20+pC΋ fs9ѡ6J>P5yI Fj}98/>$`Ae V7{Ð#wR9%0ڿ1X9( G@7mgdHHbO@bϏo %!KLB <DwHKAuuCHHbO@$@$@$@$@$@&`p5 X30Ve! !:؆H,L@7=bR4  "J)S%p DqF$@$@v$5L$@O Bt30L$@$@V @$@^`%@N$@$`I ̒jP$@$@$@$@$@Bq @`&@i ɩ & DlK`RIHFYM#HbA@7m  N !π# xW 8(S  xo     ,fYP0 030do$@$@m`3$@$`* Dl²s  $4A Xnsl$@$@C$zHHHHH0XV$@$@$@$@$@>&`9 +z؊HHHHH8#    #`E[ 3*1ې[cOL?:7t\n/N7:=ϝ'wP3.|oD3X};*Xq-HO ؗ(9 "gDDDD9g p g9s$@$@'  8n8=  20(b @tt I `5`VPe  `{v|HHT* @ `X ks'(9Y pw9  @&m d; u60肒 @ !b-_$   60a+  D7yp\  xoz  `%r $@$@Om`\$@$@$@$@$@%, F$@`XHH| |HL%m1UXvN$@$@x&(6# + BtYyHH p65gJ$`An85  m`6RE% 0  p"DrN$@$@$@$@$ !4HHf`<$@$@V#c)]ﵔ<xߩ{ Bt϶X|G @{o 5*콩,9oR(ڤ4tvfG$`#6RV,Dum o(/yp Bt30G&{_{ VVYIŒ,Ärbbؒ`GLwwo 4s1&@cdzVꢰ$`*{Ss{ 6X㋁@Z4 3g{Y@VGLm`1ŶG*w Bt϶8[ DM+)Zzzv ,4ƘW8/ DO0 IDATHaI h7NkX 4)輜ɨf`uΎY 5{hm`q7^pbbeGa-Jޢ1H,{pئfUQPyߌK@Zg7y5-MZ@s^xd؁ ;X;I I\ '@e8RKum( @i{?۰ o9]yES)K7m;|M$S콧y:s4r>0yʗ׮^yJ!t4dz)'/B„"j״&ܢ?~Ȕ t2x57/G'7}zSn+';0G5oB)?`](R|s=iҡ^x{<~W;Um`V,#׊E?v|r`7WӤE\yQtn"*`ǀX4Ǟc_#Y^H'1Nq^ B^/ ay*o>jӱ'z7`KρطkN<]@|UG29}60;h2k>aVm>F _= 8|Vje GrT)EK04,=1>SArHga!26 Aq2L+?~\y `ĹȐ) .yUKFνqg85m\vCu7^|T= qⓃ{Т~% 7 o^w!CؼsG>kRn\]{ Ϙ4{%]A5Bv@!`J-e*doey!Bum=-Xƫ[%rே%ۯBUS~,=о8uS*&\8qwUJKS8(\C w)Z,HAD@ ]'P;J (.ykwǒ{9s[W2wfoϝw{w- {}/ l8u8o}gFpp/8M98o>( "6D E@al\&-#8s؂/b=7n|ba$h<1b;7^X&jX ~9 yxKqWD{}Ͳ1sV"`8{*U^>æ5,C:&V  fM8+(VV.$IZgD*5zntlUO3m n'|<0mZX-sCl9>6<=wJlpwX} %f>Xn`HJ6b<Ԯ48ā۝XR@ [w 1խ18!0\H1lL)pU)!#-5jGN6.rB(;YBzF0,SLJ{qz-U/"D0={˼9F5E\оE~ތ ERNR*Z'zT*]ϊx!$H"ć!"w@(tD\)Qd\Ab&CW[be ?L=Kqac+.ߔmyq;r^54Bmb<7:yėQncy~绊Ey1r8 =׏*LKѡ<%V-%2 ~\E$ռ潻UHl?>h&b1>~;.Hde?/^ÇC&ܾA1tt\@yeчNc录7l."Sl ukW*BF`tHJ*)7UG}xQ yOBڿ A<=.~2|zt&Vw2RF~DwVRwV޹='óC3l\ܗ=Y}*h+:7DTHSF]_a!\D*%WL熕K'z21C_f/FI@/czMۻĊبɋԩ7dޏE[L5XEw`ӺL{dx,oRLZ_T(T\pNU \tQO`µ{_)VRJ-塞YHtKݶi ;&>x7&4G gq:1zk+qjy byYPoνt@R)'4XqĊ "Hs?1KdEn߲숎[Rn{bQinD|HXhT29M.NnY\熞bEOǚ#% WLΜ:رCH&-Zv췳P 7nЉ2e@)IKU_D0q0޿QW?*f50I[+"btɕ Y)Fur+MZøt./&4)ѠIk lЉV4bGb%_~LF@^ U{vi-#"r rFADEdJXBE{{X|܃EA-bE} Ď--^&/V3$_f-mogѦ)/1-΍۷nJ{vn(#6j5@0y1sCϥK'Mj`I@+ӷ,bEAnf7<^yqx~?l"!"ꢂir;>ds{k~X ^ q'"]X{]:5p'^ZEG^4̀NLM(.QBUYبY U{[j`"~u'Kw,^4T9~?Ӌ/!p:5XQvGE1vb7UPe7:]f+Wws3c;d9] `TJ|\߫cg!{sz[j`jaN:NGÙ8 &r~~f-µ2e@통-!KXb<&Λ/^@Dx^U]aܜq +QQQ|eO*B6*`$rElٰ®m­|AպckyFMo+O.GIj{gHuN׎ӹ&PXmqQP4hKdeҷ>Gtw©c0 >qZ ~!}QJ9r#oȖ#+V.K)N S$'O1j(]>DoJo/2fΈ;5ؽ}7rΉV`hBhվ%|}fϘac11l"/AeHk'kذaݻ&KCp S1X<.t<Ƈ5Pxa'bWxx |2_j%rTR3s47w2EV:|5z/RI-}}5r+|OB!cMϾL+>3!l"'ʇܟʟn߼.`9)a]5mގs 8(U ,622 |ryR5ta,[+CATDU&{tƳ0qܣ3I#'cbE\`Iq*4 Gפ.&KX(V(}fƃbgͲ5G[|ivAO7|b:ׯ+WH޽{⢫YZuPvF&!:m V@#lŊ{Ow4ں.C:`i̙2G̪;3q vEdqO0^"J<=|r|c4jPb_< AK@j`E*Vv-+oށ. `X4iwnAeXT-f@$Dx&"$mZ lط^vݣCOlX/m[:!xgE~i`[#jMѹ;T( ';lվyxYDJbŤXə3'vM0q`/{LX9m$ڏ`2.+D`墕Xwx?˳@DgN;WIfܼjGrÃc4+F~o,6%e&VD_-r|Ub z$E'y!~to{H"ҺF̑kϞa6Yy0 ",7HIQfe1-ǭ[=;zKeΟwk'2&ëGpuu"Re&M (VK;cV_BከU&~SbE[vѓ3c<.U᫥X9z{ 9K`+g".G Nr ic!|sa/sB$`fםbW>*ը$EKҮI{xyZѾH2ҦO+Jɛ{q9Q&ru$Dq ȵXX2v0;qx .]Ž;Pxl+@?۷)*V G@ 6۠W@^-9y$To*_ Y"+qEϜ-3M^ɣ&˔f SL\wXǙd2:~oH(p*NS rKU6RN8q/Z?ŤXqgϞc찱ї3!4j;+d޷@ <~8Vb}Qq]I ZEVF+Z?@"dJ /Q/={&-zBKXٿ%[yN|  :W/]Eܟ³'WyY~v$@ T50 "BsVֻkSSuha50Sƛ"D+#6ٮrQzvm 4R߬UwȐ!ywc|9sLE$;br^^5r>$`NT?ʻuxK+"~+pYK$L50s7+-VV/.VT_YU0G'D50cVB^jQVV*+ZI{sVJC0^fmt6ZEV~+ZI{sVJX L%oi.<Ð!ZXJʜߛoT"j`*yNse'L@bNJ%Ѝ9:~,$wbEub{ّYYQ n(#^gRMzG`(V\'YqWۿ SAA3HZEֻ-ZRh%ev7ZM*`50ihCV*B:4ŊVRlޜ~$US 6:c IDATE_NۈZI `RgV BQ{lSaw6٤A|C@/cz[#ĊkYe!0zpx-B ;m>#":{E: ԧ ~o^/y}TpxEǵ?/c@_qp$<~[mx%-_4}<XbƁ9f*Z&;o CR0w8*5ܪ㱊>AͰr\\ _r'_=?,={w,Vӗ'{/2}Xٵ}3 B0?v=$]پ]Q] z(ߘu{;>A'ƐmDV_%I? b J|SB87zWcȨișs4j+]{ȡ8}li[U10l26Y1mG1п;fM7#Uk֓=g+Ϳ+=ej|(MKq(bNEQwVT+_OΣW&m:O9yD9cHr>BQl%po5+aױH_EZ+"CDV(psm~.Wg\Sg~l2iX>`H&-݅s"Ч+6=z}3I<'BP?O:q3e_HTRSl԰@yZ_/?w脀 ^dY h=1PzS. G~\s`R6YM ?QHĨMZ!i߸%D ؐ^XjLBx}+G ¯g'/ӤCnȒ5;J.yL7FKCke$Z+s$_Ƙ`!Y DAȗL kBo!hץkbE ﭛsZbe(ezy&\,݉f5}OE_vW(}18?֮|vb%l\=FdɒϽzGbUe^)V:{e" ԶW;1s@0~F[> fMzKfH# c7yzU/];s0PRwE|^?ߓ qmwةܗ# ± ԫZB[٫i`⿫ɇ/Ǯ)VĹcτ7+R_^;|s3aޗ6~;2xε6|âSTΑc#slTX[&ҡU`Q>"1n@[Y搡\:nRr-#bT\ QeK-\]XoΔƖB #aβJՙ2XDsN?U]`jߵWXJc录7JlEl?td9^dg$ 3ct 3Ka"L__-ϟD[ GIl9mzM ZoqgE4g5r q_)Jl8+lza| SKWu,eNE4v}D~+Nvj`vF@];~FP7HIy!DAE⻆q11SRm֐ȯgN`LhD+Ŋ`^Dn2r9ԫ\5kN2r L_w+JT=5+41۴KX. ẏ)S糧hH_X[~,ٓzﭡb\_+o+T}g2Jk/͙G/˻!"LÏK&%}Xqƈ1ċ0~U|>޽5y?2wϚĊسEaA}]DaZH: |CF_4 ?M@XfQ;  B@kʸ0s(<{L^78S1eOqѠIky?CB4,V$OR[M40K50I Kte]R 1н_|vE)Vpqyy]lqXm%w# Qp}%&{k(Vj!J{lA'~oLDB,ЉȖ='={&{%ص,byċɽ[/<". ӵG %6ppNYaq_4.t  mx&;$+c2b͊`7  A#b+W4.cUhmg F{k/[4坕%^;ck~j`ftg;,bra4*V5c' E{kG`ogV(A aV3Ch2?FKzEo@UOd50sVۑ/;vP^ZEvp$~pU{B2`f@$ce,m*V57gGf ^'`O9FHa;`(U/,ʹ ߫gj`qjL{!O`HO@3$@$@$W (@@Q @$@$VS Pp HT*D$@$@$@$@`50Ei @\N$@$`4f4 Vnó9 ؄+;% *BHHM2HH@ZEH8  NHH"kHH@EW9'    P)HNH"L\s  `50y w[IHH&X &X) ؗV}h$@$@$nƕA$@ *BF`@) (@p"@$@!\$@$@*`509 "X LGr$@$F`"ğ #H$UhblN$@$@6!j`6NIHk=G#  wxP/߀!!!o7ֈj֭زeKgݫ#΃[߿pxu{QQQQqpl@$@$@$@$@$@v&@bgHHHHH@m؊HHHHH(V Ñ h#@[ ؙŊs8     m(Vqb+     ;X3pG$@$@$@$@$Ŋ6NlE$@$@$@$@$`g*U*jrXkڳ㾾5JXqb:}LuGqPuܘheÑ 9  slO$@$`"} Π$@$@]q3 ?{O?0G$  X1`vO$@&@bkHHQ(Ht"40@  {ù +\$@$@$@$@$@$40CF vLΊ-IHE/ZK$@o{.   U PY΋HiP89Q p:Ls:s$@`j|HH,xkHHHHH(V E$@$@$@$@$40 09܁4HH F`A$@&' &w ' X  U PY΋HHi`\$@$`rL3i> @̑QQQQDD$@$@$@$@$@"j`r!    = ,xuGUI6bY':ƻ40ӻ  XiA?&V<\*MNkPA=2 (VTEb#!(V f6IcdE35X1hp,T+L2' PRy9/lSE88_  !@1sg%Xx"Bb%!+$([@`奔2Kz"}?,V<"S78 ?6fo4}Pj/_4}<LXyBaV6RE0 Jdz9 i*XLhrD_wuvE=fX,[ {J5+a@h $M*ū"UTXe҅KYZwl>z[g7#+@D%B S ϟskWỲu1n8$O \J| :nW%rQH"\`H.M4gO}ma>K/&{&K;5ؽ}7rΉVk%V6mڄ*Uīo#~ۈp-kSӮ\J.yPhI;,B6"OD`PdɖϞ=C'E,j5@pD,]0+~-vB,(Y!'~Eܺ7x_+Ul?{]ZwA>O'[03&{obJR șԅ1u׍ײI1r^GAlտ>d2wxKѾ)7n#)VϜ@2+MtUFаX0ktO0NN ,Yyn+п;vHH V-[Q4WJ1OÐw@( ..n =|yV+wF­swaj$ItIP/;'  0Le&qEV/1#”S`|mǶ.~|:\7-۵D:-eDf{󎈈Qd1L]:>gw$;+B< 杕տcWd^2cӨF)? WmG1VKXSU i  0{kJ`X2g V\;(G S} Tsr`P":u*V/uՑ[o>U]8HY{.v 痂﷽!.X)Ly}l4b9r=cTW+>bرRXDJTdٳgXGP2o-P#'DŽQeTdE~+?1.q I@owXO ] 0t8/tse yg~ ˜ Dϗ^_.ob}_eeaX /lXabg$I^FJ>{*m:]* 𦪈VKZ`$@$@$`:b"Rv܎6 ꥫ|k*S‚0{!+uܟUHdų#c(_bE,Vr9" DDDfZiӦ۷:a>_z̝zJmyڹ~I]/Du*o]Cw!s2_Oa3}o,W0Z\:}A=e1mO7~X~"2eyw:_LJq[ɖ# r?ش{Yz~W_+&IHH a g_ 9(K{x`w wG1adȔ!:"r)4d3%;½xDjV e)Sħ?Eo>FW);uL&:ywDѵuWTS#Ue S ÀC/?C,bǺY3fo^oʔ)Y )ҡL+d̜U*#-"%h5+aҹ WcH"LߺwҠZI\,f,^'˔rjȶ""[L_b xb+B:~XwV_#\{3;< ϗ2e*!?X tl9͛0~4 q 悽"0KNV&Ȋ_!vܺ".E79?M]T¤ghVu-X*ݹ}}a疝@K2R ,1}zbq2 LTsSi`e_%KL :V+uW-,,5ђ/_>Y}wI?~Ű<]c>qM9u ^]ey?'/t{vgWäp:G?'D™2rJR*`}D^&$V%|:Yq{+޿QW?yE|OYhuE]JIA/(VX/lJ$@$@F0bu1Uqѣ`oV;ݪ98]  '"`40'bnwV"##QjUSUQXX&*bi`&\|4HH@]d59@\bah`5HV3Ȃ$@$@XR_gŊy% 0cbPE0 LeHH D 3Bb/FT+Zv$@$@$`6+fXq8(VtHHH@wLR_g*bi`ζr9_ p` @xHLNM@O$@$@5@$@XQճ HHfr|  #+HHHHH E C$@$@$@$@$`!40 09܁4HH FA$@&' &w ' X  U PY΋HHi`\$@$`rL3i> @̑V     0"V3Wh E@$@&'40; H8HHx$@$@+\$@$*U=y 0 kHLNi`&w ' 9j`\$@$@$@$@$@F$j`F m"    `50 0;݃HH &ƵA$@&' &w '   ŊHIHb+QDD$@$`RL3h6 @t`c יd Xa}[hͦf$0ƻͦ$@$@$l"Vx81mp #>@9CGGnxl;WXaK a.دXoFhpʓ \PB(Mhҥ;oށ㇏]vU)k&9^BX>^' FI&'Tx"BbEI3R<=RJ-}:^@nqO]JnȚSY9)V|M0!b%** •U z  G0XQ2`IL,#)nݼ]g~t:,ÃRJ$IJH:oY&tj[π?Y`!ضi 7W?O 9fdIաQ0q0|f%՘6^ QiO v x"ȆCQT GNoMtl/E%={wŏ߻!(,k"{n̝+ךKlڴ UTWFP[_T]sr"*A%q>5kZӖ +K1jdɓ' WÇ(R ,rٳgĺ%Z(kPRue+Z7ށ'BP?O:q3e_HTRS׵BT-ۺ˟ݾuޝ\qi ǏijOedEёC`wUjCH$$M bErBnH"ϜÞב6]z. e$@$@$`I*Vě>AX4k1"Ďw=7 O7/4rm$.Caظfϊf`xp,\q;hZ[bW!8,W/J􇦘9afcZ3'_n+j5m/0< eqX?L;WI4 +5ğWaAXAX͞obJ2#gkRBTm\7^'&2b"q8re!{3#M_ MQq+ 95N2DtiK&m:n*#hx,5 }'`Ȋ%fQ2z ׵Vq`XǷءch^}C|в]KRFd^7﬈M\%Pd1L]HQp~,\\J[A/aMU+ O q R%s_;4W_#_>yj.Ց#W ; WDеWXŊe}:`!oyKѡ,0l02=Ɔ}<}rJix/}>„!Cv:ܻwϟ="I?~M67_+#~-8*׬3F%x% S},Ǝ+ʼnEJJ={v+(?~H`0j܏|F."I@owXOhj7d}2KW?xEgOÖ5r{w!cW\AFtJȂYcنsN]$I^ϞJ~W5UΟŁXA/M)Vΐ= - . rgE\2qr;4lbqʚ# )sÿ"ܱ!DdKQL_:M]<{12fɈUʣeV1nR;+@OjƤ1c dʜ1چȁ#hߴ:ywD>УCO!bwedᅮӿAņb%6{=}&Ŋ(X $brD<d͚.ӦM۷o't|d6;,=sVBT1ayĝ~={9y?;fߕo]gpߨY[bEYɒ5;jW(5bpھmTGOA^a)SF)P4(^ /Z%44X.J]`OQFV-˗.`w,OT۷=gg_j6  0)\R ̳vn=|<0 ;`т2{L#"BjMIO D%UB wVT(-K*۽6DlUAbӒ&ĊxD'ѕ?.FGz5мM39z&/{kh֦D=!&.7=qG`,wVbccŊ3FFVڷo/7eʔrXXy+qCq2!R,OoXb&Z!//T cp 1S ܻ{Aj%qᷳx=̞,SU! !J[.wj]?:"T+WohB/ҡ`aH`o$M^)dݻc!gϥX?X tl9E͛Y ,ai  0XwVt\>Yfy ;KGr~3&I=vl^m=ٝw0wvn)tk!S,bU"RD$EDT,!Ɔ?g?O)NDW;oٱ<~N=)s#Rwђbſ*&Z40+.Ǐd4tuk,/>qM9ϙSvQÏ>‰?˲=;3Wä]:G?'臌&*VEF>D.]cj`!uh;w%GȔv.U[ y GEfmpq5D>#2[7QԥAϾXbԔbEHH fHJ4*@L,E\>z(/s͘L&I$@$ wމ}awV"##QjUSE(] UĊmW  p<T%VL5 Rhd&+&vM' p Ls 77IX'PE-   \ث(V&I@ \EHH(VlIW)VtObʼnϩ L&Ib_ВPE0 ,k= //bŰa X  0S8FR$(Vΐ= - 0 ̖tbEA:T+LsE̩ x^q==?GPE#W& %[UoSXqbs$@$@ 40S8FR$T+LKZ`$@$@$ aX1khX<"V1u~HHLAbn2+-I83d$@$@$`KL%]XQЩN<%U xs$@$8^WzObEoϑT+UıIHlI&bŖo3Fɂn#i$(c+8jhƥX %;" 0 6?C$@`.IHi ~iIr$@$@$@$@$@X';#    Ћ"~HHA HHt`os9 kx HH@U+z"p+NjNH0 jG9   ^Z     0$CF 0 kHLNi`&w ' /sq HIH(VHH@U+z" ` L@O$@$sd@TTT AcHHHHH,Ƶ@$@&'40; H8HHx$@$@+\$@$*U=y }%^IDAT 0 kHLNi`&w ' 9RB["008n^ yˏ1;yݭ[7g Z,A"VmƎ땝 OMi>5-§E4 Y,MܟC(V`PCi0𯏆S"|jZOMi>5ESCa' $Hb@3'$f٬VҳfV5$$fZ^U@ yF9M&?_OXɤ~ lbbbddFs$M8>::e}"|cccee%%''3;y!il6!MHHPz.Ap_X" D-+Fa'622R@;HX4!PҚ5kbcc/d&l! "ͽꪫď;|@a67VU5'ƄgX /vCDDPl XPRAq;MES^;rmii3gNbbbxxȑ#'wS D׬YhѢC1 0̚5kaիW|*eEEE Ü:u/{jkkArssfuСQF zSZdIbbbLLOoϘ1[o}v:|{e4uTNB )(.]ymHEmc{oڵ}]޽<;7o3<3iҤCu]SL9zAFrJ 2|'y睗_~}8Oz'lذ[|wzjdz_|ɓ'7|sƍBMD/>tЇ~XZZ:cƌi,xoڼ< ?>;!]+뼔mhhXz5knf"z x{!!!&￟/^\XX FaA~{DԧO'w}s=۶m[jN۷رcwѽ+<+xW233룣=SӐ,gB<(w5;2c:sIz5?L7Q=r|\TT v׏=C^pٳgܱcǁt:qRRsss8#~)---@y.#˲Y}[HA G7n܎;>Oo9.?fFWƎo>aV~/ X uZz]_<\Z5}ήw^2r޽CCCw9uT"Z;w.uڵ!**stl;}t!CQyyy\\A۷o߾>)S|nl~fiӄO;vٳ˖-֭ȗhXu)(._IA1|ᄴdeg7Όa/+~>]Nb"1>]5k֬{,>>{+VhllhذaO=?l6gϞEEE_~yLLLXX;#Gܰal~7wݺu]dɏ?/:R__wSMMM=_~e߾}&Mr?:tPg8<]  :ОhG `gu HI,hXB7pܹsyW]u#Y&66VU I,rGF:rLBa'PgTbu^J"HN,h{G.QP\MǴy:YN_}zFF}'ܹsGz7.^w& *bE1h'%cL.CJ,iY7oOy4F+0 c2*++!!!GyϘ1#;;{̘1G$"1~Pn$C Y]2dH^7Jk]j>} /WWW{D4lذȧz6͎U{YZZZTTtĄO_8qbJJӧ;?ݻyyyծşի-//o„ vz$5ˉ@E2S㓍3DTu{r$(gYdDlٲ˗-X`ʔ)ӧOʊorUW]K/-_<==}Æ ?46N,zXr67VU5'ƄgkheNHp=V iZ-@mA+m"M^G .v1P2JO:xqm0 0[ofΜ)< {wݾiRR|z<77מq 裏;- ͘1cƌn'h]P\{dc i9ɞ*9ɫ8""3D=Ft=XEm۶oiiYjUiiԩS [hFxWhFZ 9cLBD]Bw.}OIiopT6gRUze5k̟?۷0@Ii h&鞚ѢOJl\ ;=uAF|\` mi)6ٳ'VnvU[[kXv-FO@ P/ֺO75)Eh'HbΧٛ"iHO@|MJڴEQccvyi+j.1D&ftr>5BhNYID H.ǵ677o7&yoll4I,كAjoL @$N-d>GhS3DDB y)""¿+'EHb4@|&q n[\pЌ_RGÅjP!yꩅu}=^zdƛ"aS-d 0HbTƝdV6utxMsaAqڄ>RP\~ͲwێZLw-7`ӹq:G\:7܉PjyoNMP ~S{\BV$@-V{ ه\i& "6BV:*ީjꏗmg_YUP\@*CpSVk&uZkQp'@y[y~u-d{1i&ZtC'-ds?O $@a1o9$U { OD\ZHe3o (٣I`6Og: X%8S0l ge/ ޛ(uvq<=XehՔR]Y6=J_V]GGٹr{N='z/OD4礅uՔ!\\% m"t܉PR폌+Lǂ!"/OQ^(djXE=+SdI@mX%%Ƅ)=|-O8PVpB)m5Q 1E m@Ng$@I=bCyÚkD& ]x 5QOzx!,B[YUk @Hbc{rDڗ6mUGmE]CN ?uֵ8>'=݇#k7"hӷcd[EB[)~X'u?urKD{R“^qcB[U@YuVB;1Xux~'o(8XtjssBsv_ᙩ>Eʺfa@/3XpA@l/r_hշzMHw3Sc#D4b_GKEm/';\B{sv`\h嫀ĘpbFNJ+`b.͗NIڜڄtW2\S"mB .6__x9yS^Ȧ)m.Tn ٛLJ 1u/ىSܞEⷥ_km)F^}5:fkD8LFf$@]Z{\_ҕK뱒?'; uj{I)=3nJ<:dMw kx.߳oúƵ{\C!B+6V-Bh ף 7.{K?,sx˥_0.o\TK\Qzעvό0T||[??kê@L\#6Nlhcr6.-SGř⣼]'; HD䥤Pv/t__:^,ҠĄ _&_ ub:iCS#.BT(PQMUdBV7v;܎0u6_$ҡEhXr-_ej̀9Fž"i:\F8 <#G1qEh(җN~ IDATsh:$l nI8I܉ xRUb' vymsfM$kbעZsMm"CF܀r mmۧ9][aiFh(O2ό P_=6JsFP&_z|׉g,-l*ޑwW:eg|C?6Rk|jaʊ( H!5bk^/m~@ 6ɏx&Sid?ۅ/Le?Ov@1)<uF:y#I,*HUО{N.%gZĬbSIEƎ:~/n!"] ;\K 'HbSeF\QꈭmGE9yNUtd- (e4|wVKЦ6m~@XTk'  [l*"dc inoÆ-:Ad {V[-^()v/!Gwb &0 ڏ<q 79r~ҥKTTĉiӦF8mڴ~i„ QQQ]t3gNkoO:)/%+?d _}P5|E,gn=|m} m$ ^j+VKVڷod3fL]]pjܹ|MvY__?~xSM6M8nƍаsM6{@Z6/TGt{T?3unO m6s['g\m,'of<ϯ\/NDk׮MJJz뭷|7xcG&nݺm߾=;;ѣ{6lYYYǏׯ߶mJJJ~甔"zg̘s TS?FXf3#{[Pl{n Y*Jhl+~[p|;nVTT;V1,,߽{78pjO c4 n4Ӆ [ZZ8::ӑFk@b sȏ˶ ̡_,^κ Dwbݪ $2Thhh\\)$&&O9*rr2b!"jZ!L@iO4⤄r?>کEO"04>5-§EZͷ-OҚBDOM+p+`JRj2Z[[7c+++G!:s8U~xuuju7kO[,nݺ;VVp̘1z^ٙx#{I1J2X aY~$>6-i힟%Ν -x-W*}kZOMi'H:kD.QaDž9,QN6מ_wpo LOIljjd*,,2d~W˗/'ZN<ˋWXADYYYf933Z!z˅x۶maaaW_}[9*WL@<^4V1lP8IC.Ј MR["|jZOMnJODbD:_OxdlgQ^RLؙ>!Դm|o?q𸴴(>>{s]ti>}tȩSh͛?A  3sD?_~D4vشiӦo?̙3 ňW7ʸG69y"V\0wycd Ld siUUzVw|b#MP/I,BxHb?j(ᱰ^f?4{aÆm۶-&|_~9$$dMMM7tӚ5kt6l0gvĉgu:g}6{k&""bԩ/BGYUNԍ 1 i Tqmu5L~TITzG.W\!$npۑa\SyyyyyyݾQ?& ѥ0fz'U\Wx}WihX ' L:~PNIl<3n<eG>bzePVkT 'HbTMGbY4ŠguTN2J|Ntjjvhh!I,93+~!EWP\deQbwV5j8B/(iɖcڼ+(mz }R"P(86(줅5\u|=giYuyoJGzj`cV $@aI{&;ʱR:3T'v^5xFڀ X$ 'I9Z%<%ƄI50e{C ^d͘4D#YF8 WJC 0o/hA_"4}hf:peЩ R N=BO(/{`ҫSH2Ԯg%Gn0~9sG |OV8jVȵm>,UT..JC8!82Xj 1a||MnJ eb\N7fWHbT‚T5> 65/ԯKa9/Nev j49#J@21r6k^_i5 LTZ25vBHbvCU P#gfW&,q qx~=K*$@I6+= p<-rLЖKa\ 02c- X%/iE9tQ)7'-LEﳪߣg PJOAcU8ܺPU2^XϪ֊|$@16PҳИ6\Z@ 6V$?ǻf|O3_Ou 'Hbc.nD='U֡J/nh1]dNDC+䴋Ӵ- 'ZSX↳%ْ ܘ:vm2gYPH%̲tX6(=Ϋc"Vu e+= p/1&e+j慾JDl}=X"J2!DZo2X!:_%J)G=bC(_KtKDG5<:WsBGx"zdcz 1≈ bPH=$@yW7V.sd+mG;όKlUė+z^@DY>lDvpDNa91e^ַov-8b%UĎXR\&{l/&|$'yC_>?\¶JϢ٬YUjjҪ^ JM@Cp'@I[Y#k$Etgw1s6f1٬YjP @$܉Pl9G]&/z C Y]j1dH#d@eO Km5O [2*׏N"_ f.u\'̙nr>9i>w:ՌND(g9AXU״Cl&{,q?G¶\&eB@$@1jhZWBWm ]F [8]~t- m"M^GG ) ʺ>ͷй!PLreK<_ a^9?QD[|hadrH Sz c[Bw 9tb x!,bK27i3 ^feщXE q|m+Nfi>DΗh9*Ͷ,Op'@1:y$XVq!=s~1^.S ]f–!ұ=`G"tAj:eZ$@I%d\|RrN 6@mڼKgw N88Ad7ol2gYui[Mxcש_B S7oo\-`{UQ͚w͹{2?oJF*=vl2ߺPx# t& "cCKDDͥ5dй+`blDvp{~Yit*ؿTUkh-3'dg؜l,>\S5+6O t. j;깮Ei| r9jgu[ħE鞖ry*Ou)'8х@^km͚񈉪VWPt,t蓒1i&QY,Ӊ,CU' ()1&ԞOF_5riXwOmV.%w ?p~{SۅJD۞D<t@\vip'"b| +rmf.TdUlD̿֐B9@ q!|c[(6GDɸ$\=/~채FDtxޙqɍViu#G\l(/\ne㨞/ t + +׆SB-".*6m"%S"Pp:t@q5E~Џ1#hV`>DiQ$`SX I,+aO>{0SCvxpu^V?xaNovїK_ogmfv;uW؜dh%$5MNm}J8»:oW1+ *JB'$@I2pJ>y15twOm~0OPbH!wb3'Ù6~S=㟸ys c-^gB~"Z_yɏ+{xc=~Nl3d( (lCTC _oڏ0 1+dmk7Ngv2tHPIoD;#TW.WdO4 hWmĝvXjTCѳsj):YNY_G4=Ohh~} c3&26@'$@y6q[HoE*gt|1!vgzqn+<.?EJ;Fxb~?RލKG!r-ǧyF+,W]bR.SK`,tXN !| ӿb]cdJr¹],5{{^sQK41j%[d$Գ!❗_d)<1D]CAvyv=![ȹf^7#𤭙}FA04wbϯKp+9 'x"•ie:OGK" @R[yaҎi_j$>^.!" E6P;p k/f < 5Κitq4I,8S$.$9d%-;FP@bOO$nFBe#%wmc IDAT btwB= U!o(bM/y2P2l 3h|}I<~f |D^)FjHbd#5D0{AEd3Fc6𤷝{?ø 9+3cde~d> \:9p_|rԐ(Ҫ6y}l|ͤ =Te~\rF , w;殸VW뫪h׃=ebaq`,Y""" )( I,- 4{GSx_HEp,Irԡ&}͚WWJ3_Poh;pj`  @p)|6ia{ C-||$'%n~. ?NI2E&Yܐ(ixjL#v]lVDz%_%t{oߜ )GK H+Ru~J1iU»M̯C x֎ A I,2SCYMe9+Jziw׏u>}3 7Ȉ2d`glWz"5RN#AB $ܔ"KX ;u4q[4k~:ta@RFX7) ,8$@ac/B uk_zZZ\GG |&9.u&BL/o2I80xJe{ P*UIU׭r}zبva?$IM+J-TI,l)Y ;2Y߮rFCӧ+s+9: ft(iYuM,`9)V.| gzPzғ:"OvȌ!C <$jZe653u r+} !PRU<|!H*٬y~ܻGOPD' ,'PR|ԍW 4y<TbP:R #^Hb9:cIA(yd:+FLX S"J@.HbcfNYΰ9b@q3ygf@`$@1Ҫ3uսqDU"PaJO x/JT\KϢ:+$4}]x^O*= QY'}s\_ү[X$ƄK>&6{7m{FyĘ0`1<:-!H!PLfj|\mqO_# !b% @1+$ѱLfjcb>:s|(W(i% 60&ǞX34!gHA tnHb4\;,qy `F=%6= X%eGHvmU*=ӭ\Y|ؠU(I2ûrRA X5l~FI\|bIv- /> 7(76I5`6k^_)hp'@I˪kZ%[)~ՉwH-ԯ#"l;$JXX~EubYRrhkUzB $ɫ8n2gYPvN hI7܃?v|$d$@I=⢤N,(2Z(T1; T'7MQ-uy:XbHbc.'dJ1;T'BdaP<Hr4{j=@B $>#odvՉK[˨p)G, Չf$z'쑁$@1Ҫ Km_N e5k=2(NZf5%AՉ&GX<|쑁$@11tO[#? YD U !P=X(6 0C2ƵLX S"oP'$y>777%%%""n8r%---?p.]&N/OUWWO6h4iӦԠ/@Y5Ǔ{bvc p%khݯ`;p >,\bK/jժ}L1c ΝlڴiΝǏO:hڴiJ9ȴ'YL#/ra@$N~j_Pzr Qz ߀ -'i!ʋߚS"|jZچ&p;ʥ!1&ǧh>曅 իڵkNDC-vO9=ӫE9ٶm[dddd w/!->uloMi>5mxl!Gf H5`ޭ?E>ܴHOQ$QTTԠA~[o***SYZ]]m[YY9bԙ3to=[ncǎ5 fX1czeg"}[ZUw MOObOъVmNZT4W2"0JTB1'\bPQ>:W+$5"Xg66bOPDCRy<#67ujbd&^4k1}lڹ$F]*`@#khEq*M+XR02$&oգ6wsT̵X 0hSMmXG(JxE,`Rc[b*{crY;blzZ#ĜR^E T5 ^(G'f: %(bGs/kbD ӫM +GwjLZ]ߢ-B1_mV^R$\W)A x#_bkݪ3Xmqn=hYBLJDt4IʕHݩ wM ON8^s\gaRǛH Xm{f Gb) W]GGHmIvPmN5q:MgE,`~z݉}.aSWb%͎}ep~D .V8*8@tOβj5 gQI1ǭk,b]10j8' ^D Ib4`$Kw?Nj<k:@E,`Rc[nJBK3ޫmSq\?2 t$}I:T۬JB(tvьh}eibL'裈9+6+Nkh~F>Ӡr.&h)A rSb vO[KيQSSnX8شwJ aQ1+Vn(tNg3[@2VEtr~6)5srD |bƩf" g'"NG 3{jn@Gz֍;lEIY XTt!ݘR }1fuwԫs'*F󝂉lEɘY(aM{"Xm]6TwxaURm>Q 8hNSMg裈L*+ XT1}$Gy7h-دiF$X1̡ VuS38e}IUE24gIU۵Vb@$mj;@T$q~^D  4^R&4=ےThEczQrGG VӨNI_n:_ڦj[ʧbvQ&4߆5NE_:j Yj-+Lg裈u~-vqW^_5?^r*[,ŀ/#-1;Q}| F~KC"0>ҩڮͱaɳMY2TI(bcJ91N IGdoov7Q\2L=fՠGLs|8_ U=/xD h^lo,J\X@zk_٬IgEA io[l`11~mq>nL,+11}M1l{b4ߙrI@z;q(M]"& ȤQEzU28;Mgiom}n3!&ōѳD ֥p[_Z*0u݀2J7D 3&_yUNe _'f: {8GŘg(bcùAG{?LwH46<`d6"0)`Y+Ymq=V4_f:HcꍝX3`LM];c!lkE)c@fnc'&Ǣ;1<+1ꍝbGA\@[Vn׍'.݉I1 \ELRvXN5Xߢ{a{H\(bcjdd-S$ ]E{Y/ƚG NdnUNe_rMgil{2>rOLQd fJI(bgG9bwnLa$!ޝc%$Xxo%9Wpv}Sj7"0fBQz*{ͦ Xe:Hc Sv]s +Lg裈QZMᓲ旦346H<-m!8'K_4p8Y)|8] IX[ߢe!l[L2JWX پ[;V6K\t϶76ټt2XHGn@[~_Ƴ$nL~~P&y(bcy{β[̹JMgi<RVXqg?fs59{~ \ݘn7wJO5"0<<;:ک͏/ g5_$d|$e1ۚ\6X1+M'i,?3,IG,651=[M=+^sKBW@9o6*kvmծ͏ &JyQvfQ췰 k򯼱3tUSi)kcdV(jk^E,`L}DyWB`1+}ben@qY I(bc&\seK!H>5NEˊD6"0Xy*{c`$tN4Ƈ$9 }6mڴphllEkNԹ K JMg*VlK}"6nԩS28H#ЩhrsKŘ~T| ]EZ:56ء/=`B{5 ;#ئ#Na}gJ9z$ -m;$ЧzPPĮ[kb>ZD6nf̘!3ej:HWC[SqsI)m:@B+wܑHKKg?ٹs&{Å{4.rsT@f'r4~v[[noW<%Џ ZYL{Cedt2"uǎoilllkkS<5unǗ;cut ›MOi-v9Eb IDAT\~O֭[n?/ xz ?jQ>V˧[o3ins}]{_|q4`0x?T</{EIݘ~ĕXHTNF@7`lʀYmrrruֽ⋑H{ͥ 0p^%,J $X7 ]tt2wO !`[]d{b4 O1dXҜN|gX]?x;T/u+Lg*#hO-ԩpsZ+'pTVVӧOW<-EΩ[yAJn?>u?IV?4wy~|;iooW<%NqQgNRqk4}*O:$k fNP8.x TqN12h⧦3tӳpuv]bEV>"7Es&YaV@ZY7%LYJZw/7Ls:^ kַ֬x3۔#!݀>U0t9}t2+O?駟xFIr3לr݀>U0tfj;ފ6fek47Qxv\KҮOT= C]t7Py%vʔ)[ k׮)Sؙ tb {kO k 1n uTݳ3i7owU<݀.`3 ] ݀>f:@t'x"ŋ _beee*<(GyӶb]˱t$+LxբЧzYp)b?|,.1 ~*FlKvn' &"8{,+o.䈴Jns.M3'SzdW0[$񳏝y9Y>%~G+u+(bHN.ys80l9|)"Y:[HvF#"=M;lDw%3-?.oS migJfd֭;m eKd/aY7kq{K8!{M J $gK /Iw8{V25/GngooJktȾē#`e\̕Q: '$n/#VLɋ,' =9nWH0r,% IO}>\A`ϰ$}쓅,Ȩ T:[=$k06|;C KB]![ IvtHS\K^{s\R0A>/(啇B-Tn{mw.((ЋOk~wܑ!gX8bY>#.Ƈ3<_C0ӥUNnݺ!U_s=?=ػkܹ3:ܥ mx gẋϳ "_WA 6L_x6=c AqƎخX"bd, Twߺa>lD<硷GVBZ6KQFwHX4SK2qE푚;+%#W~MȫHgtE$%92BY/[+t̻UR\dyk9V.ddK?H霽 8m^%,+G2uN Xnx;yX?#\2F~s9' }^=g)|/fWsF}}?Ψ2fi"7q]sL)t%O+$-dm~GA)|%㤾F_XT2U24wIm'=Vo7ɪyz",ȑ#u翳Vו<ȑV) |TFMkM OɮF}OV mS,B?F2%\. Hk""$7,yru.ESUB{z{o_n KB/ ɤj9⃌>ٺNb{,G6[ĉJ([ʤHi˒ 'Jłc~~/H" ;d.q]%;'~ɧHdz`L=]Jnt\zC{Ӧ֮HH ,U_q HٚkE"#"y/G^KD$(LqǼ?OUzIJ%HҳGF^)"\q]l̓`ư~e߯SK,t6IfpMzq={1Ee2utwHl\+K;ʖqICܘnf)\).U2|,{Aۖo=ȒQU v*/"YvlEHlRvL=MbJw"Y둢R)$o.9li!v˪+HԒ rGt˒]Yʂ}c7u=ҭѻw.((fQ&ko{C}燋j̦?n ŀpH{-#^>_}w%+ovKGxfhgTVVQ<eonaPz,@ԇW)}_P&/޴i_>v؁{V݀cdn@| ]My$z- S+dWM'h,b-[lٲxkbC[an@W?qv^ܪpvP9bϞ={'ҡN&=-Rtݥ0 S,bo~>lsssk?Z1&U)-bT:򹦓S"N)֏Ϳ UUU[lQ xK[v'M5ڮͣNrk4~_׾o|cP;N(74)p<~S7&>sj`!"hYV,S< c;Tv1%b Mg(,bV]"j*:\>5DT]. t mnV(_ P&_yW^yEgl4ό>|P1ClǍS C4t6LJo}꫖e+"vN Cnj pq if:Hc q`EgN Ѽ}|ǎ999ׯ窪yC:8bџbޣk VӉ9WbWXsѶmSO=nꪫ֭[x3:n K|\#,ԐM ѼDd۶m"RZZo(M o ٪Ul)FmkMg(,bMo4s/M74eCs܇kэЏrGUqwV2PDs:… ;::D[nY`ܹsyCQSު<- G@j";zeZZ|-%%xf;SLٰaC$)**tF^֥M2 mM%'_a:@ta*X@_q*E4OSLg$W`%P]Rꈽ&v玒М=.CZFm:@E,`FfLV^jsV`nLi:HWMʽvKn@?_$e1s?wZ@@WCwHrI(bc.]% nL]ja:@E,`LFОY6-hd:HWֹ(\ͿƚPF e3XW۵VJ(_c$?vG:Zs"P1"0m>Fvi򯂉$[pΟ\e(bcoWv$hQ*q|vM8okEn;{(b3b{_7(\0* 8tb{ӵ V 'NXH.ŀUF\~둺M'i.[kRF 9m0ҫ_f:HcC+eC #<#7Lgi$7S7 +eΡ"0< )dWP8tqDijaf(b3u 2+M GHXS{n@V( g=1^- Q9uq~C 3љHpaV@k\׊_PƬqE8{\E~ʡ#$ťg9i9%3QƬؤk%gb@? *O_t(/R%͢g"0HOc=@"iW;;Mg(=E a$Jؖwhϡ9<G2c #=$jFim<ֻ(3vX{yK7`]g)/aFzHN"#=(5"0#渿~aṉ ;_;`: HW[ֹ{Qo=5u]{O[}gɦ34֔NKc9hخNն?<"0#-w~(ifw={(b3!7`S ; k|]$ ]­T/eC "ݘ7F/Ս/Nټt9!NW?e:@E,`pzNt>3tް0j2JO1? 1YӮD$l"_b:HWLl,Ks^0A S2vsS7XR W߳pR/M3Q̞Z;H¨R@.i/mQ}uE1f/th' esMg*`[7.8Fw\~R &<"0&`[.QT<ޠG2"wq'ŀ4Oﲿ<"0DA-ιU1}$V[+M,\L*Ux.妓4s5M%- M3R"h:tO-|.H50@Էtjnv+_4\LjQVmY(w 5)F781I(bk fz \@t5[/(6ټt>XҢ [jb3=l I*-6U۵%VV4{t>XأASq󸔘@ Ij34D s[Սn@߱s>^2HA6!<"0.[EL{CM34eW8TTD\f%%o }1m]g[t=$a{'g;t>X1YT0QJNXD{K*z;Ã(bcÙͺsS͏I@ f(FUU,"0&`[gOpSs-%";,Tg:Ho 4'IAw/7"0U}_eo X.kF,X,$068ܰ$0"0)#h683*A{e*Ilr}bo^*"ԱIg!<"0ik;v]9)Z|獧Mgb1J= E11ǽZY@DD^y>Y-y\M܉гC SSڭ1ӉD Hޚ]=M VRl8E /ilSj /5ulҸ 4M}/ ic3uNyA13JtG퐰j. I+"1U^lׁ'Qƨ4>Bo'88b?aD 3R"0fFizL&%tN.lq>\zژdOY[ߢƩ`U^}J IDATtbSd/Q_+";O ѣbBwbxE,`L*Ċbg"/t0 OvAO*(bcܪbSqtcӮ Ċ%n@Y }1"~z"∽:vnLa$A}Xeͦ3QƬx)a a^`m*"{_DdbXgLg裈 {E)~1bL'x^vMƌϙG 3{,}>ە\nLyw }1dt`L] 93VmזX} ^D P~ /tuUG66MC"0.kOTwebq]qY>B:@Էtjk2J1rI1m]13W&O ֭ƩN&ƍH X1Ymq>\G*51o^*$vKrI(bcãC"C+t6^Uinc'YT<ݘ>Bc'xE,`HO,qvR_Rm׆vV$N"XȮ==/.s Ik[rSȥ<"0FSS-bPsQo$MFѳD StHs 9%1kvWyKt@JP`y/eID\@Rt'5͕YoIŜ+_$1 ]hioȱa}EѳD IHOTg: H{ 1g!"0&CtH?s-o|"Xq1~ UqY1W:1}"XpQvP7#S1)@ګ*- (ww z³(bcurYX=7{?sG?0E,5qYLJﱓz_nf@2N&݀E,`BC3kB[ e(&%}-vQi_ĖY\wu}w;GsssKJJꪞzꫧvZvvĉo&}>;cƌ)Sw}̞R/L3wTα}(2FtMW\qE뼼Xs=ze˚/2u򓟈Hkkgyg^zƍgrssH]]9sWw{/=.2vwFE\x[o}WWo~iӦmܸ;k,˺&O|]w1f͚GH~wmq>\wǛ[q߬9ۡ߹"6lbb^"7W?;}cEz unWps_s5[[['M4o޼H%htҥgy~׍q*<ŀ2J1bwbłpkW-񪥣7z%ŀ m sf]yo`hTjIý+?OzWqfzxܸqV껫%Ư7.~I6Q]xW0effF B{51 2vi(q*E㥅#bź / F]Z:UK/{bj稘+ƵD̻I\햎t_t8ܷ)))87\nħΞ={ {w}\dIff3w=s};,Yd„ x/Y*]^Km-wɓEd޼y\rɺu\{W\qE|>|3ׯǿ[k_~_]{HxcW.)2l:;@f՝M һ|GN?oW\q?+) _kP1&?RGYRq$ Z,d5_C9GT1ؤm*QԶԳŹ!F`"s@VsҪghUOKĀ,jumOZmN"Zh癷Z u?A*q%0)6h 卥(r\ypeVҊ*Q&oiN-v+F󅳾G 6ZjEs~ޙ/νE6X$M⊬v݀l:ݭDw3#z15ZIĹ.MF(o SԷ[TF\WUК^G TUZ4*C\VU3OZ+IۚQhEcDc+P匣G+mxt@jQ&-~m?ކҨao(zgNŀEѳF s[U طOX7DD$渏muG!NюX,QEvꞮ/E.;bt5hYS߲Gyj6)D ֕SNEdqz^OI^*wMc:bѫRٳhONjڇ'CrA:u\KEog\QTGeDfO$PCrEh Jr|fY&WbGbO gaYiSwף_,:AmWCrivͽIt"i(XȮ=517FKzءYAYS٫9zHDlR\J!h,<"0&EgSWjycs;U۵H**XyDLJ"XT4v;c 5NN E_?CYR0QJI).N)اG;~. `!9? /.fc&zش> Ipg=ҢTOZT%vЏqե;_{^<³(bcu٬Rݘ n#+EW0A>TwH^k6_su֜,kP+/IHQ&})٪gwJ}AVYmq:45K>0_.{R~ ;-RgTeo XE1. -i3~OE,tz_.;$oatq%0ltjDwpeH;2a؃#iኰ++ u[޳=Ә\)Ə?$~#쀔ϕT64%PN%,o9CR[2OcguwS}/qW*99lsr'c$;rD f =MvEDЏ3̮FwOd$aEDbQ-jmo=j8b_;DsW#ЃSK=_~oխG=ϼ{ !hgP8)C_5ɏ^֠#/z=/|ۖ"nvX ߻5dlq0<I_)yWm:'j_TB jjzu뤙}}U/Q-Mbve;)rvrW4-b ˞n#]º4>A s\-vO= a= ^1;\{K;ֵMs`` ,)(]6}axDI9c?^7IQ!\gơ׃iE\I]15u#n0+'d=YTuxi ,GxAMv@YDD]$n߃[K@њ]=ZJ7IF:=~kDu:6c_e=6E,` SNh󹁆s"Y 5tK1g%zn~||aVu`Euy񇤠ߩ ? x+":&_6.}->4IzeIsľ~p}L؈ahQ r!152R w"|Qu͚ӿ;UC,qEnvs̠%qۥ2GD;~|@+ϓeOE˞_t-v]_>DG[_ 5U3[5] hm?9_'% G S]. qIok h4B ˹-q>_>lx %*{( _>_9߮E2cR>WA}/`تJꊐz޳tygx~+eZ%ؿYgt*C<"0&`[7.8f; =,˼j]#"{K"2Kcdנ-Ob=̩q*-΍0.;k-`[cRXĪ)n/E7A)zqiSا~qp 7>poS]bFϠ; F)b w},C<"0N jjv8 8+^V=%j6^PDP,`5lΠv-ȒRl+@),b8G tC?ŋY&lk[Dz%@윿93 )RN8>N,"sA>X~ghQ]zHEdݭqБ.v+NZ+'YfKw|p2Xu-9{bZ+H*{; [ G35 =gU}n^r9~eu1(blKn;TD+ǕN7:t{ ,w:#eͱ*ϓS[ &0 % ϩHQz,9{$4hΨƻH6/GX=~hxG @[]Yo̳߈\3uM} }*>uy}6xSq]v y73X}a}]?ٳpN Q=P Ǖvn8ʩGɾ=޵D}>po:ؕP/3(bWny6sߗW7p{7ʨA7k\ߪO,<+A?7Ŀv7G/rVplxBT:߻3" ԍkrˋ-C_y9~gTԅdɰ<#WC|U8kVüאjmoM_ة>;P3GyS7 v)1zIwڮq*n[2A[$H伜{?ZyִqNL.Ю%s@Q5Wq]o[lة^]Um׎]2jQiw!o,2jk2!z/7VJ0HQFSY}yQBnj[ڽ gNQtKƷ=f/mݱo; 8ԍkqЯJm}f$f#8h̃vaXT1(}ˠgW?0UuS?N VJU\JY7?kY-Z IDAT7R.Bց ͖{.ivT^Zힳܷ4tlWj>SrO#s(g+H'&}$cE֫,څl\V$*BnmnOƲUU=m#7rs.ZXl#(nbmlj7h tZ~$59.7D#۫{@F uGs].vscD=C@kk?p &Z-.eUUCuӿ$b)KI,SngH/V}?fyo c;&vmĶ҅R_EJ%dRmI,pz!v+=m~Ns\~@gaJ. K;!!oG#?=K2X4諒*KCQ4Oge˯ k'ً6fRm"m,-~#8K8h8,9z˻Gol0*L!K"Q%)řKjVB I9W{2wϳnY!&UZpIZ.)c~dž >X+X@MR:Ćy1fV)ghjؕƲ^ ~(q- $ GޢVի@4ShB ҄`_γA:VY kk =}cqdh*qM4, %*qD o|Д`UZ?]C}c>1X xo|_ph.X4JԖ]Pv֯U b FٖDm֊9ٸo,$b.)C$5} 2rpmae_N,ojj9ni0p$ATjv =q%Vپ$Yh*qe #UyEgwW!nh# & .kg!]CO|X$Iq5 ZqMGP wbń=oCz ,hqM/%Dn'$ʺpUFrXݯ,hNV72,t$62t`Z\@WKAI'"*zG oL/։RCV+)nnTYkOHbm!"T^CͬaiYIjVE q I,p3];'1j$PӀa\:&#UW"X@M!_UV0HUnKI,&!TWkO|j:1RB\^5j:P k;o('X@Mn}wMD}*$PӞb+ΒWtFV\!ІR&"Td?}BVOyMMՆR5W$jTj7W%V ;$P W^20-NV\kHbpM9ej@\|E f`Z\:µrm!_Ѿ!"Tbre+Urm 1HYn_jydR[=c:1hVfG)jBM|M\|B T;E<>/a:1h3YWiJnjuj5'$n0ϭjBCɧ$r3DmC]Fn~}6!2$P_U~i}ڭh]jlUXOzv5Yk /a!PV|k< cW;)Nա ]h qMdM.O~oO穬->0Sqix=ФhqMmOHb4|Os{I$~V\BWI6RG o@JU"n|ό\9sPoTS*}"AwHbczk}M¹g:ƩׄC,|C hBVFҟdšٵM4/+#i~HVFMt$Њ$wmZO( Ar:2Wu1lЦ[wݐ!C"##cccv8qbرQQQ;v|Gm<8bĈ._{l۶F/wO駟YU.^vA{* 9_''l_;Nʃc'k\-Р²V^ iTA7 mO666~gvt7رcժU~O>쪮5jTrr={?k/VvtMÆ ۷os=#|ʮ;c>}Iv?mYU^١s4# $~3ʃ?lE_f]tZn~ m`{mO.\ݻM6X"33nx{j!_˗gddL0[xr3wڵ%K{}ה.YdԨQٳy%KE۔Wt:y{xl񓄘?6}/:Gy reUW@b;[ !scnm9+ǕucB}ϗHNNV3a޽/sssGn5o޼ⴴѣGN2f̘b>\& ?})+9bX,G՛z6'X%xq򀿵?+:ZOexSdoxju.YIk]=^r|^#zM{5Bµ4hۇ^h^x;ue':g/_e M].BNbmO;tVVVJMMR+++KKKsxUbbO:K9W^ye…[6m?rrrn|*IfVy$?^Z{QS %Bav\ upo" QZ'MM"⳦GkzZ B[U _5 |dںF67?] CZ]]]z4.X!'ٳgπzJ90HRKLD35ei"3gΝwrTgfپREEbQnfX]ڵwƬMxxm"44T#ySzޡiK8k/uGkU Ơ93_VF%yYͤJR;5=^ӣ _hRk8z]e!{` l?& ;uرF.(((-iMھ}mŝM6%''+)ooڴiJ92dHZSxUx#9\ޓH2lV_h󬱩<08i"m։'ĉ߿ٳBѣGO>}߾}_|ܹsgΜ 2eJxx3 ֬Y/?|'8||ϝ;WyG}tӦM-:rȢE6ocM9UO )Mvn:ˮoN9)1l*//Zr1 >^x!33sgϞꫯ!!!ׯ7C4imLnx ,ִ 6lݺz饗|͉'* jժe˖g|5\ʟ6(!ڇ26ʤn$c `l81+v[$!1s쨰7&i|>B[KF- )ő0^m[Dsb|˗յkuֹջw۷5bĈ|nnͯf-20-.d,Uy~cəsAyIx:i݂;2*\^SmDžjЅiqA{}c[Z7N! Ry㙑yEgmmAA?6/8Uu!1Po#_L=5HnXhU!W.[b*v)F& 2 1?c81F];]};Ǫ݄V>.uYuqL RB[ݝ"!4!t|ħGnbgRl%!$!fKsJ-eUW@/f_.}\^}Vo!!d-lC{&&7tk>WěwSi? Dypm!@Z5yZqQaZ݅`|8&6?$*uyXf W u+ s`/xfdkpeŽgFfe$ey{[>L hmyEg<Əuި\ۛLCR+gm^ub_əv|۱S\`Wtk{0k쑉1u?~@4]ݭSQ7SdWSXW6W<鲩-yȚ)RFH+ڀ ԗ7IVx:)xuvnfӻm`i:}p?[W&N=9W lh a/I m@0P߀I&_czo-b- <sUO}, d2L} j609\9s.o}3呓>w) X@}!itu-$Li/_VU=` u*tYM 1@+509Am m1VQgB$&de$-l:mrܧW\v>^ld?<|E_V6x])ԑZs` y:7gFYU+=P{ymom?ڀ `N,YIyEgkϏ}QOzc{YQ%MURWY5<ۋ$WlKB pm?+8valaiOg(:Nf˸vQ;J6p'А4[W]VuC+3 q8oGa|q{_8O otx=UĘEe-0zdڎ~կ˿Z֏fݭW]FhƝX@sq3bgQX "6"ҋA_Fssznh !듮rYaRYCT؎gFn I:ېm2)sZrFxښP~J mݞ ʄ{>-P"olu~K ۏ:U~瞡KBM?2HRzZ^_mog㓭2<|kMْc/Ukk8#4*5Bog/f MV/wQݼ$ޚoLy՞o˪^+WY\lhT}rBq5Ah494Y5|Lyuj!z/ ee6JBHB H%oMμOn@6c=aw\)kg%ĝX@[ΜmfuzMq}>8Cd+zb4$sL]S;FOqxyEg9;u,m7-&ce19?[=.*xkY JmMw̄ m@PJh JgȷPu_"~ ;lk\eUW/V sbmQU\yRTYx`8ulA40-..qIkжpmh I,9YI='{meŏon@@onHw,+~6?@5!|OB hќ1GxLFWK[o m5@kHb- 1H ƥK64y6kF63Iɏy/9%&2뼾65$F)Kؙ+?ǯN).=K@e\-m'9, m5@kHbHo1^Nq`6N뗕tS's8q6Ak+gnkyhͽ896) hZA'xX>I\Em4kJ%y5c&H m5@;Hb `= Fl~y@F\4$:DYUB'Al @K0':/L%.Lв6dpiB7X@IE؞ .(m9+]Ru _2 JHn+:S^SmDžjx$Х4[ڭ `mpbnt$$ I,@7HbA Xnt$$ I,@7کݓeYQ]]vCb U-GkzDStFi!IlK!tvC')77?DGGKnKtĨx^#zM5=^):NZה0&&F3Ķ`ܹڭ(&&oݡ^#zM5=tӣkvI,@7B,Xv0!!!]w]vzM5=^#zM8=jFa'n0$ I>J?C !f̘aqРA444<;v7nw}^ۖ۷;699Y,/X 999"";tmΪ>}d2LӧO f53;***99l/?}wym>k}1k$']|T+\} Ǐ?zmMM<|mHbaϞ=!nveWVVm׆ l/y֬Yjժ;v={[nijjRmLmmm߾}z-xzkϞ=fyԨQ555.5eʔgggggg߿Ac VWW^رcƍ?`̙O߻kNϚ닑^ wVj>$iĉ|Եm۶zh׮]999ϟ=ztmmЦYzЦe>k@<ݺuZ,}ݷz1VR~!;;; mk֬Q[Vꫯ*OM&;#{B!Į]]B#G/iK{A^^Dy:bĈG}0z-z͏/Fz-<|n֑#GڞYӔr!ĶmdB~Bf9wbuqŊ{$Iʖ[&$$c̙w!޽{-ѣ;wT##FPzCgLkF5h D?JXۖ/;vիܹsm75-^ӎ'O_gM;qqqЦ漋ЦMνFhջ󟕕3fPx㍷~{JJJQQ??rȽ{uIJ2u !DۖĒe*++KHH?OBBg}vʔ)111ʖS悂y8p@OΏ/FzM;> &ضYYxk6##Ct¡4˹mHbu߿wq ##c)))ׯ6,nB-]Gw9C?byVOm̙3ݻw0`@~~~~65Nj4m[iǜ9sر~#M\ is0XOJJJ6o|ܛ_ !fscccEEmoyyRl.Z+l=⡳fɓ'?ҏAfX&MTTTcV_~O^~1kѣœ೦~>۲eKΝ-6s5M M˲enf{O>&%% !B 2$xm)sl=ظm6G}xHi߿};Ϛ*dY3gի˴4vB5Ah0f&Չk׮s΢-[ <.V>;w޼ys~~ȑ#{y޶۷o߾}Bŋ۷O)ꫯLիW}rsssss{}-]\b7n\Νo+j .\gϞ333^ 2#!eY\t|ִ`&i֭oº:eMMInlܸQqQۖѣGw)44k׮w}'l{ϝ;7gΜ[n~ZՖ-[.}ݲ,[Ç<...,,[n<ӧmgׂeHoHY}݈Ji7e˔]6rk6-sk6g bN,@7HbA Xnt$$ I,ںu$Ij7'Œ$߿_m˗/UY`UW]f+7F hC{tȐ!&I&ҥKiiiFFcΝ_IhM;jfڭ($$o߾}iĝX@[1cƌm۶$IT\\@9̛qÉn:pءC(׮]ۿx+l5kVbbhXnO?իWxxxjj믿n{ԗ_~{ڵgۮL8`}ٶWTTL:SNݻw_lY8;78vXFFƋ/(ԩSqquuuoUjjj&L0a„ 68q^{w!UV%''Y&++ݻw_~eΝo>|ݻ?|pԨQ]t9gΜrƼ>~ƌʻ/s=cÇٳgmm-2r+V=裶V=󅅅yǎ?~9('f1G=ݲeBeǕ]<@dddMMt̘1<,Ǐ$￷믟7oSRRW\qŰaÔϟZr,EEEB}9d2)ϟ?o߾,>}ZuV6l/l{'%%ɲqFpQL2j(ӧz*==]y2m4jMHHXt,n\\\mmkҥf;{@Kp'DFFvMyj}X^^.ϗeGW5447{^z l՛BBB㕓$..nƌcƌ5j 70iҤ$!޽{N9n;wo÷zСC,YԤܧӧ]$٬}Tv <ٳgO81??Ǐ2dPcIZV!j ٻw)}lٲGy$;;O>o3h պp &i4#""\Deef+t8ލ7XRR~͛7_=kǟ;$6$,,V?MMMÆ TZ"33333s޼y_:hР~=zÑ};p36==}ǎ;wѣ},==?>wڵ~oNf̘1cƌaÆ=S$:1 IMMݽ{wqqS٣GSu]W.**ڳgϢE6l6h޼y%%%6m:vؕW^)x> :tMZ!Ĉ#>qĜ?<;;[O~/ұc>÷zkܹzʔ)+,,ܰa} /:n:II, ;wnHHHzzzNN8I-[v]w=W\qŸqvm+,,I\"##92q=z̚5kΜ9<b̘1֭ɹ x└%~W_=y~Z)ݯ_oVx^|E[ibwڷov7- 7o^>}jժmaZ ^qqq ]n;FvvY`hU܉wbA Xnt$$ I,@7HbA Xnt$$Ў8IENDB`signal-estimator-0.0.9/doc/dump_plot_edited.png000066400000000000000000001706241452044147100216120ustar00rootroot00000000000000PNG  IHDRiIKTsBIT|d IDATx}|Twd&Ca "DE KTjhLRm}^?zWߵEZ-źȖV RZKQ#n!17 I&d&dnz>>9sg>|BP#ЏCH9CH9CH9CH9CH9CH9CH9CH9CH9CH9CH9CH9CH9CH9CH9CH9C&d{HeY @֙)(h$HWWl 'u]$]}3μeԤlyut:B:p!.\KHl.IM$eYys]Wi4U #ҁut:Bp-!ҋ CH9Caƌr'@8^ 8u%۶=dU0L,˒;v u>/CAZ_o<^3$@FIY \וޥ>O`0|0-sԬh뇄CHc zMMM{iD ; z״nݺ;ɶj}3Iӈ4yu]mW>ːߓ&@r ;TQkivi垌u]ڱc:::4w\]uU 36lؠ/| ;vL=n544藿${$ZJfҽޫo^{MUuuGyDwuW$ڪ;ѡ'|27pϟ?}i֭ڷoLTuujjjb={h˖-ŋo>r-^zIPHUUUںul֢Edɒ1cOӒ%Kdߪ9H{H;C{ÎVNe$isNڵK7|^vޭ'xBgV]]:ٳG7tmկя~TK,ѡCvZ~#Ҋ+ӟcqF͜9Sv$#Ć=쳺5yd:tH7oVUUU~wViiVZ`0'|RsfϞgҥ*++S0֭[Fuuu#9`̹+;\U:ImǝnBcm[7oֵ^J~-YD^WKeXeE%/^ٳgk7oݛб È+ֱjnn֌3U]]7)sN-]Tf͊kƌC+--e]&߯J]z:x`YfR>OꪫsNL$v`9~+=3VGz0~7L`Ph2 ͙3G---)6Zeee3gѣi9@555Zn,XYf kllԢEkQ۪f镖)򸵵U<`0 @93Nco\SSۧ7[oKEqqm}mO|>Io߿_W^yedSNɶrԁ̤x@4k֬Fh^o3pF}e% [;w\|>ٳ'f®zȸ:GNutt}{_wY ;y-]r1a KVu\)`I&-RMM}Yx㍑]]];w$izڵkΝر#8~_MMMjmmԙmTYYiw^HTYY;wjѢE z饗zե&M4)]۶sN͚5+A .-Zgq566aHӉ%;ݫy橭M/B¯H[ˈP PT3|m{WWN,҅ q[N`PsDbeiժUז-[4|?is-Z'xBZjUdZ_ݻwBk̦֬3 CT__;wj]6r슊H}p ?~{0MS`P7nTss&O j1YTWW7ʶm-^XW^yeTCx<z뭪W}}ΝZ=c c<+ B=c۶o뮻Jutp]WMMMd >R6:r]Wpx wVr!#ҁ:"FB*3ɶma&bQ)`*og{ԧ>̵lygUVVK|u]9#L_t&_s$brRKT[Q`H(t=Z]J}Lm[ ҟ'vmYA@^ ډu ڮ% @ Fx`%p۷O6mm۪֚5k" }#au]mW>ːCjb1RcI*3s9 T]]}GyDK,QKKm&߯Jgϖ$AZfmۦ}Z^2a} _رcztwA/%I{$iժU5k֐555饗^RCCLԌ3TWW'7dzW+0 ]ymۺ#﷪Je饗^eY?Gιo>m۶MMMMZ`-Z_Fӑ;ju8 jV){C2|hϿ#cI6oެ:vmjllOS~}6mڤ:hzꩧ}.YoժӞ={tM7I=[u]=SZtjjj$I---qw^m۶M7|ʴw^ܹS ,W^QMM֬Y=:# GIUYY:::sII4`#!?<0 kieg`YD^uclyyi)㹮;_z饚;w~͛ɓ'9j%KZ~_K,Qiiۗ-Rqq,˒狙sGNk֬Y|1uVDTZZ:dYfi͛7OΝJ|>UVVꫯֶmzoH 3Q\Uq'-C+we72ǑwWwc*Nx] al&M`08>wްRaY-[… 5gUWWLٶ*qYYYkjjҎ;بnٶ-4/v(mwR/PB0 b$ 4x[:3ߕW^K.DGݻqFY&*17P" | kZx,ˊ,ED ډ-ڮ% @ Fʀ"wȬS2s쉱Uϝi͑oꭷҒ%K$I>ONmۑ_SSS Ðm +(/s߿Hβ,M<9j]߸bͲEhѢEDHv(>ː4ݽ~1R=JU1W.̙%/~C[[̙#IݻWI'q߿_Ց.H/v(~iVɕVx?) Ð3sE.+r&Y'Iuuuڶmۧjzx-ҪUT__-[hO9-ZHO<:::j*͚5+iU۶mS[[***tUW ٯϼyѡu0 ]yZpaR+hŊڼy:;;5|ֲ$6͊BPOضoۺ뮻j+\USS*+sNH{PM->ǓmW>ːc븯耴w%馦# #`0_g=a'Zhϟ?c9#LpMH ;/ՀH{Hv0mN@,=Z9}5B711R693d_|`LCU&W1. uرH {ѣ<2 F@AK5=wՖvrzi.u])%  \91B` 1X2 C*=[?x͟':tH4c ~GH(XI osV |FQzM7th#o>Ow}wM7ݔa |(H# y-![~#  ;]12hRS 6Fc4g%ј~` 7b$;|(H (SSR 7`{8;&܈0uԍ뇦 R8j+ W XJ0T; dv7@jR\G1F0 Y`0(ϗ Cj`:NzjYAYlB@A (Pg*rzZ/+xrU VN#!%^WR8 mYVoH(X}ƣNoPit: jZ=ǫ$[YqywDnG=D{cLU0Ha|r]7m3[UQQcK@AVNbK8 乖#]AZmiaG+o( =Z]FnJZ=9$⣐J 1 BԷv'҅ Hj=mH{H>+jGȶۉ~6&( 2v Bn,o[(z)~=ޟƒh|ED@8.4(vl'݂ p X =>f+:Aw68ܾmy#Y-(PB0 @;i:rIDc#FKH?M: iWgf4V2ҾA;AU$]d8z>ɺFtsuaM4FJd?b$B)[nrYמ-Uyq #X2Tg%{Lt?=2؛sXHG 0@^{Fg ?X2T$%KV~O`x{{+ɺ1 n VQGvKJ2NhԮZM7($%EINK|[FU4baHr4BDKe3Af"F~$SK%}{r4`I+202='F_3#YVw#k$tȟ>xi'v={rfGճ,% VX)v9z=]'%F0a oTXVN7: LX8|*NcHR ڮ=ظ65KoRTSO[^QU54F2 9FrUj#HSȿ_tҎӀv+ Sf Tpyo$d%u]%g8'p-E}astz"HʴrnޟXVL=u|$u4|N]u @v1@8 ,0Aqg+0?(d%lĥ}7Ý6R6 :I>튶F-Pb)>acc=ҏ߶S܊V8Y7HȐ ;]ԮΡ%ځlvG w3K{' nxaˆ^&cJ#]71ISnHSzsɺDf@1@ދT:8/{ZĂwـc!e(z)')}Ř=H8OJ_]J#IċͶk,H}Q$s @60@~3Mpat,T԰lzm\8?V"H דKxc#%SiK Hk).'hR9aw^cna ,#\p9I @JFXۢb3F% 1R_0 -H}cFQ G ^>K?~#~vr rVN7ԠVN/R943wN{\J|+_ѷ(!mG'CnTHŸ9i`|$IC3_۔4 5ϑ.bᠮ?w7*lGhޑʽH9ܣե|+t_ کbAۖ2TUjr"uiZ֟]/I4ZnXym_vs444'$M>]Wع@$Fm=xi+Z_4R7fb$F$#_i[Aە2tT3HKe91 ;ySxѿ"i 5'z|eHFbaMEK\()\k-P^. 跏ާV}lᲩZzz#Gr[6ۣV>E IDAT>~?_}HG"+}f͚5$^ ;3jSO=K.D&M҇>! HSYY.2:7MD#h…*//\|0}^:=6}__r~͞=[uuu}wu=K/դId=cQcz菓HJޑ6'I֝}~\+SI_?tO }_}"n[n[~:nΖwE_ݲOG<᷆6u}E_r%ڲel٢ؽ{VXzHgu$Ut5{fΜ)I:}x≘9q}Q566G?Q}=:p3лIֽծ]t w}?Eu_?kZp$iݺuzSp+@!GGCYU7BΐI乖Vi  ;yJĮ_trP0jM.Bͭz"W~_5uŒIzK?taF\/Rgˉc2{i%5Rgw|j"-a:^yݤYi\rN?yy,Y2kh"'?^_TUU 6h„ m[_%Iyú[%G}WwH;)q٩~[]t.첨zg%I^Wk׮ĉ%IsnIғO>+V4@aJ1C\n_ '==\3 u5)۶کNƁ@a TL@qXVN7\oII$Y'I3/]HwGSϿH[K"?Ͱq9k>D~>a„![[[cg8 T'l{u 7hܹ2eZmݺURuեɓ'G 鉑|C\XnHdb>m!GY=ZiGou"B#dЎH5CRA@ީٌ9ތ_RT】R@E}{ H9gD~ ~Iѳ jFӑnc|[R }K_K/'O77,)(o~u]x^:qĐ^{(`\d:UT9d$#t?tH7ᾮϧ^ j;zT7$RqGKak}#J~Ҳ3gT췠FM1;E2s\/yZӁ׵g˳Pٔ%IS?+/ZGYRxvEzۓǵ%΂_7B3gNXڱc>OG-?I ~>U^^GN\555Wӧ#;@ := Zrkƌ:yvءЇ>* @; Q,OxV[99tFh)Wql~g6µOB%h?vޭÇVG=_9B}{"/B:Ѧkkמ=BU S_$=E7d;g6ߢFuC\8Oow袋TYY&Gf}c=6f\zZv֮];$o?:::K__2ܹS/b#5~hϞ=jhhP}}Π\tiVW IHRx~TS;7c\.m| ߓh4 \"}v}_\ ǫ *UKϿJ'E/t52b5UZ<9xR3O<yx?QKdZŚT5]}~GO^W3f~W{)1`bJinl #ތ :|CQ(GRa۶o뮻eO;quԤJ#eo>8ԋ-ϸ.\0O|X/IO~ IŔs-J3u]~zG%Is>ˣBҁ0:j=mo#0 VN3H1V$x=u}1zTfOH|&a:I" ,ojKP[O9ی!!n8 Txc!CKw)HHҀv0wROu [9=:(t{7QU;ԴKVǴJzS;̿ ڱfŋ$?3)'#HN555iΝjhhPKK>O*ڳg^|EuvvjܹZ|~>m&۶`]yٶW^yE;w$-ZHW\qEԔ`0[jϞ=,K/e]Ƈ86}] Hbo)]PZߥzKD.րvjh H0Ծ#HNIӵ`!%i޽ڼynfiΝz'umEmvڥ[nEzqFX"lۼyu뭷J6mڤSNNR8\~_ԧݭ 6H/^<)m3.a=.=HSZ}w57=`juFNKMZO{׾5=y5frͰHza@n<גcG_ɦJ 'oc$?=*++5H罁\֭[U[[j~-[LPH9e]{T PMM߯wyG֦;wNP]]vܩ6I;CF@@kezֶh)µ`tD$IMώ:vZ}7R1% H-1)pҢs9'0 ]|jll$qUVVF|:tĉ>'NTEEEd M8Q---'N΋ZF[YY)q"ю }=5'muKVH@2Nlx1R&i%<#_O0D|ag~_NgC?y9}ݨxdYLvr/ͧΒ}a{5_3ie[hJu:B:p!_Gv}GHXH^oH/k&Z* ٣_C7554ExsssoT\8pmolRc) -&YJ|!=\GHn)c1R8#u5\4`)K﹉0uTq[ AM8QRx8m;j][[fΜ9Ne---N4)Rmrg콁.b]xQUYYW ;qܬ7rːݮ̝,u,SZ6H..^l ?x )'|$U9F|!\GHѻ'¥*]Q⬀%UHwFo 'O$L X_G$ ɓuQI){_/)4M555EWA[#:uJ477ԩSg}z-Ho\} È;3/ &]7:x&MJg׌7S&HSJLI'en >+V.ut:B:}1}ke!F'&y u%Fx2V nK yЌ?w(mQ:ڴ RT1/gnA@BNR lb+6ĩK78Fx($FB1t$0k @r :aҢGy$駟$-[LW^y͛'uqFi޼yZjUTmѢEu) i룲555zW$+"a馛uV=#x>OuuuKl r<;9Ø9ő0ėsbNsƋP*T;ԴrJH_{Hn]18W##`|{LXu9f+) Ϭ#Y U%| M,&P,M'c@.T[:004חQ d{q'\[H{nƭr_A/P8nSoHR9#Swo(;\TZT$$'x/G=***ROOO$Jޑgp'Ztn8m.%><v 睷HOOO:;;U^^0鄚.T&kV'7PB@rdQQ1QNwO٣V2B1H֥*|&f v7C:sR{LwHvt;ZgB߳:OH:;iXP(/Tj$4_6LH kMi-عVN3wHE,0=LB " / as&bUπ ${- '48(4SMNH „ ]7k1B9NU$;5Ȏکu) F^1ܓS,ޙxu T[U*--Uuuu4ܣPP3s|G"FJ'ε+fԑwBi /JfI-pt\P /4kNv1lp>uwuBr3^÷_y)Chd18k', oN:HF纮vuf{%Jm!dget E uyܢS.!F0$\ viF]ܫgz&gls -Z#;mmȲ hL`$`'K .:3nh-]3E/׍`H{lqʑk۽eR=%IzmVۙu0)910%eq]\ke'I-Z]u K#ˮilb2jԧ?9kNIҲL_O90 N =R}yf\.Zz|=ƥte{a;Q!a /TZ,5^4KYtR 1Wh JȆ 齫3Z#C@ިl3k0}iݯ%?us`MLUg&FD| U$`ⲴWPA\ו:Ol= u  LAi_t6uMϔpÉX9$Cr)mV /uw(X\6:mW_gRcǒT\%g 93:Fj|`|#a#p\k&z)`^hLޝ$uKL u= m7D iV* -Z#ǙqhHkmxyR˵VwfK丮+c| /[G guY;vl|[պyRyKgd8v)Hϊl,Xx?ב,HfH 4^-<ӘW1%Fm)5֣k)[ ͢8$ɕ̢Z4jׄ1g6NiwIX_HryW~m:(a  /|/'8K:_>=XuMt?ƛf#NNHuyׁ(9J̰\Uq'È+X\&u'_~XJm뫐_[\%W&bioFOL.9bOVt@*BZ'V]WJ)gm^wNHarfvg护k04N%Gr(b$`sKIu?v@C`^oA=6Rk8)!G[vUrf?|F2*9jG#riAnEmOԢ:mњZ qY{Fu |.Nu ՛yi0\)TkCZ9}1+E@c*`j pptOkY≠B{<}bzQ>~F0 [g۬5=S%Cbp%Gm~HXP PY\ + '{lPlzIWnQZG(9 GFPUj隲VƐld6oX!IE},X" Fk5{Z*~:ұCG&@XGZxQWjF=nLd\#KJy SvVc$I:xzJ|PwH9(A;~HEuV ;ytNg^0ڪTJȌur־ق5=0ҲH$=̃O˾p`!2>?dir.ޘDQ|Vjsd\ ϬFr|f'78Z>?s,-g5襽}A]}}7`ql[Eͼ/Y+ј#LɟbX#c̀Cqt2[<\!|Foq-⣾ݵɽ0c,5咩ARX`Hr(I>ϐοCuR b(`\  /TLB3&|P)z'ÑauRrV2M*_y}]rf7~((-ٯ;[k>Q.F̑HGSI]Iad8\u -u :!z =]8|Hϊ]_?k̃O˾ΡK::O$|%]zTs홪9Q[p̑H)W*GIr{"10^rD;qƵyF;z>?l5!SjSW,y$V^njzlάXxҳw%|Lٺ$)4E|S=mZz'jo4\|v54>DUTy`B-N];)HwbcטDNdb" w|M;v H؝T wοdPQP_ >E$!VqV,uQㄿ?aſ)9t5r>Q-$V H ;y!E$Ԥu}݉W8 :ݞ']KSL|p2ȿgJrc9Eǥ7X{;i~ݠ}̢zߙ7#u5w&qMm2'6Ȉ:ލìp]WFR Emuc+N5NqAmF};~+l% ]\_EKpbiyZ> 8Vf n`H9Cs;`4U珜ao&&ccиluyׁp{o:ьGeˊ%cĹ$\ pɦ ,) ˖|ˏmtKnKiӲmi)RZ K44\`bru'm"Klَo%ȟW$y4ϑ-ǴV-ڔк]e֔ĺHQ`5! t1>\߶@$ic{ǎGMR}LD$Bu_pSK1 !)Dd*Yɟ  c{8k\tnřw#Msz~GP)J}lA.ZLc M[ݫ>pslM%""g)@*$V{DjعzOEB_,[fx.t zM{K} S1ųf\2*iD^#":O6-郁u] #NGc-&-nꪯ2rI-<*rmN^I7Q{uN%""X ur^kZ+>]g¯Suӱ5FXbq!И#xCDX;-r!!cVӮûQeZm8-}{YS>k~ 놼XꆚlDDD#DBf#]l d=lZR.옞k"?W@`M%f)#TVW }@D-GsHCMô/W%"""$2C*u$JcZmNA\ƪ[J+0cvU Ug)?r8{!„J]Nd pgJ_ |u[j_CtQu Ymj9 LOō qMxtd^ԁ~XCg~}֕{3s.[OIE*GORԌ]FFf͋>b=@GkU(0ODrAL1ec0 u"a=5x'cRۢbq:g#$ +7?)[o^Mtfy;qK 㰞結=Dcᘰ#"4 ԋ&s ІNը;S`1-h gč>q'`I‚z ,37 u>i^jhlƝx)Sz/AGPǒhX"2 _6N+ҙtW%""׮Iv'؝}++}3|\m] cbtdԫD*kCu~vDdA H`YUF7!)KڜPsgf&X{#I/QaŽL㘦$$#Gi&qHE1:@YGDDbL®sDK? \v¬YLQ$Vd_e_ÄUMn=~iA [-dydQ"SGmBcY'4ߟ}9LQzgLlbz1.d+j/Qr 7?Pr,'qh{bg -룫"5 /Qz⧚h~NpcADDGN GV_N^QC93NV70h!&dSR.4$nBuU$I,$j ;DDD}ȴKؕi4d%- Or3UX@ z^r [ED Ą;KbԥoM dFM'S/ƴK><(Q?2%q5/2 :`-I=ξQaŽLcU|'E'RU?WOM`ˏޗ.#O ;DDD$q#L]*dY Di ;"2vW5NRV &<;DDD]\A*Bhqv'c3d ^p&.<)x[U4Y)ֆBoZQ""f]A2v"I; 룡@wn%vDd mFR;DDDQmaqv,Q̴U$~Kǔ%""QR .ZNѭ 0DDK2&F4Zu)a'A}cM "2jLN*-O+\dy4d9KQ֖#F7#(麎u@^f\E6 MO*)fctQ'R/A+Z9qAV7 "":UE.YJ y!F ;"Jy~U켋h}S>RE {գN"" .Q%B2Y(Ht-<"P,)*|qXO6%DDD)A\TavRK&(l2rF,)ԋiGDD . >RQaŽR$I,2볘|:ЅѱڴU\p(LDVŲiAqhxXTHx JZx4"SڔA)2%D@<)3'V XTF:5t Uؠ4@L!)d 8bq `Qe""Y NNdl)4& `?Dd3IJŔ\,?܇F7'z})PTff~CBDD#eXChL"(p=1V'Jzr ϿPWH~1Kx5@@@v(Z@g#%vDd Vz4r! ,?-v%/h-ؑS>|e1'z}g@;I;""uEHN 7#" ;"2QuS.H;+^ /4I FV6M[X\t]EL4O5Uv'c3.qA_/qm}<^"싟Ĥ#%Do~*a/7=W]ulvTF)\ܰ^L׸WQ,駟ƌ3t:1o<;=~z \r N3f?)^O?tSL57M"''. 'O˱f͚666Gٳ1j(b…xgz?&$N*U߃tfQqBdX mMbdx8u5zs}g㟯k_ԞZhM{6W.뵽j||˾w'o@~~~<8}tcǰzjx^w-qؼys<<=pi,YG~?.{aFQ#0X7|=L"[CD vDd3bE}Sg[__=ϯU;?}u mXQ/,$ES?G8^$q_"zW7G%a/n]6?+1fT&9\s 6s?gΜO?'NNO~^wZIccc4Yw饗bϞ=֭[c˺w_4YrJ|عs'f͚xK/ DD4rYL G 2_s2QᖈLC kiW\\<\\Ʒ0'ob|cln&bw@XhAΜ<Mʋɲ⊋ p;#rN?|7mvk{w_Ç뮻wqƌ[nK.?THʞMl1hXdhpaGDmUѬ\[  uQuOҵk]*@\m\gWRn'vPɹImwhWy̞=o ߏM6a۶m{S$8}';ҏFf].Z"& 3 gDd 32%v\]'rv%/hgg< 2V\AޱcG'NpV~7.Áx۷oǹsp!r-`0o2eJtnDZcp̙^>ZDDD.k(mX ;܃oGDvDd ڮOo?xpy11Yu+EWS.>FN5V{g^NTժxmJ\A޽{7\wuxWgOX,|L2%s䠦?φԮe˖aʕKQXXP(vkrss|r_~Νݻ+ફ*KDDQ5 xհ"Ätɴ1xϟ?oM~T<W]@n\<  "x?exˣc`Udwg;߻}*^q[4' ʕ+K/  M^^^}U\r%Z(((7!bҥ0a233( &LUVa۶m(,,`ΝxQVVݎ"m6DD4&.It'ҋ% Eå*}Q^ݜ麎:s6 KCSƜ'Lo|ּ/\jpZ@S|A<Gy=G|Q"}Dp9y]LQ: M[ dsyLD>2k$V$Q%X\HRBUbF0ыrٴ؀;.8Av#Pt P'%}H'rQ.) ,ng) N~(l2E'z3s؀4$CY%(%a2rNxb#z/ FD6WOx,//{/쪪*l۶ ---:u*r뺎]v>(++âEp8ۨ{9s/OyD j-\EO,?Y0߷?oHi]ušDDD$ZC@6 NSBwqQ ;(..7/]۷6m-Ӊ ɶ]vaϞ=[aZm6[Vu K޴i^/ ڊ˗ |D$c Gť?݌77(..ƲeW IDATn!Dְ[@H\<"vo%Bcg"J(gDFmٲ^{- rdA8q@d͛b #77˖-ÇqYCEE/_ ۍ˗>ϰMd"kru BKXo{œOr:""Dְ\&P9D ;O<}Yl޼~P__G$ x<zh6&M™3gdeeZv#++ 5@4MF !5Sn9#Y]aw$&AL  "J?%vر[t:{aڵw#'B^\.Z[[~yyybEcEuhjEkZbE@CV"Py>g#hp8"#Z__c+--ӣUUŚ5koizpݦj7ofMHG4琷GrRjqe0<Q"}D%E\BLإ*gc(%K<(Dat]Aqq1v;PSSϫrJi,.8r.]ݦ x^8O~6rݲ,d<+Y,7S4Mq#J(>xopUr! 0 C6R.{찞c%vip:صk~?&O Idlܸ. Nl(**aW^^ 6`ʕZرcJJJ0fs p6n܈9srډn9-^tx~T@Ska{fz8 _K(a#&oT5Czx}@-s$""J4vm4$ KQ ;χ>>yyy())]w:c 躎uaƌ{L3g_D0̙3re˖?}_.L՜K ]{ewIJ ;"""0P&R8n%OؕߟK3gb̙n( ,X  ŋxK4zrX"""Ja"ˆ@tҬne (I9&+[5Uc.u3nO_"""=%j|#2֘%AG&F;"2yYW]WP$[N36:^+Kmg@;I;4Q"Jy"̞3a44Yڂ,75DDD=%L Ub(u0aGD)ϡ[%V'-sqAxx4tSF.nJits )K8NR&#WօM= DSDD48%q3r'̀Qʓ$ ׎Ss3j IF7peđ@ En@D BAkɯ+ΨIX %""VT\7:q4I~M `ŽLí쌚Va:Iu![.:ADUiMn vFSZ*h9EF(e48BIC vD4o'=N* dQ7/8vDDD.QŅ́~vDdM-@fE#uȴ$?2Y3⒈ ;"26]Pxah YW6*xQ(}0aGDq*$fEUЈхġ8&Q`ŽL!$*WA#""2Âf vKD ;"2o6AsXT;xL (ŋ O&TYfX Fv.h3%R.,.!(n[AD BS@t) IĢ8[@DDdVULI˄Ģ8 Ii>Q:'R!s>4DDDhb0PҾg^`t (Ax%ТAu]U([y [Ή+G#h4%vDN[ o-y!F0g ^4 I&#"R.mt3(Fʓ"""xQ$xA(m0aGD)o\t OZX<䁈F1?Vʅnz&Q0aGD)/*#[)gt3ktVƝ S]2 D`ŽR$I2ŽXaZ*Hƈhd))QyIln%tr삧|]$M ""2\"tvJHE,0DL)(ODDD@EJ.K8E'vDd ,NI<2EH,>.8ADD8%"ٵs>Y&Qz`ŽL̀8;9f'Yq8 :/ju4[ 5""ߗi>=71(A4Q0aGDuX\tF7p q,cBPBD#:x!숥[f-_L0 ""2i( tvD =ZIai Hʺ&H*fD#XKИ4t\tFv}8`FhL")}$4ޅwjVPk Yȟ<sVކ97܎ S+y;*kQY O&ɂg-A4bJ'>|stH;==cӗ`FĽ8mniS+j8ވvMxw=?XW~qgF{̻LKLy!IDDD#[]tM0 ^4 IpsdQ`ŽR/!,}o@=;qaǼs~\?HMSw;`۞e}>}ϙwW7G#Ihk4YwI?w fOƃxqӡ>rl+sUj=Od+ۊ~2l|sͷʱ X,9y4.hHp߱;vd˦KA !70DDD:&n ,BV\%JaGD)ϡHH hEC[~xFߊpXG%ҩ6>(3'GFuɲ⊋ xݣUk)2+L]qqo>>n^GwO}R4 ï\x$yw"9;KeX"""B\/HuTJ"(Y#ȴhs%{qr9pC'B~xnAQٶkO4BؿMq~r% ^|xuKOBj\n !dHEXj&LBbt(8,LA Nb˹3xHRMPp4.P1 ;_[P,pe['K}/ʶFor6гhRۊwNu:\4q4 kM ""2Ld 1XEwPհq \mJ|C)~?ǫ&ٮK"""3;Ҥ :XK9&E'F+>w(oۈs'܋sџ룷rUG#xZ:و\ +^i_7YUs~=R߬߇g{l[q= ?GxkIv~,ui3m{j~mNʺ&D9r!`q G'F7 ]QgĿDLb Z# yLDɎ*q8}ΏnzM.z`1VÑ&q^q\2jb=RC'xo|C)ܕ0& W?YݼLDD#8-[M( I#0fQxCD)ۦ&d?|)\z {XX3t3 &E9#Eo+^q[^ߟ[5gnQ<Ήs/ƵøTK1{de*)2&.W*x۵zLM7Z\!F,_PC@w&AiXÎ(=X +xGzj(yVuuuu5 Kř #mhtTz /} Iy<üBVCz%G|QNxFpv=)<.H!PC>D }dII$ [J\-.`hz~;yOdADD4R' Ŧ6-ht (A#7>6V\Sߩ gSXW}*8݃F[r"ICR n%NIhʶ=Tj@ܢk !Kqa.~2\3/WOn@DDd"Tn~[ǥ!j:lt (J,:z<(Anaװ G񱶞4 D'ְ#eXIֿFlX0 YXs¤ƣa ""l22-*%ҎeLX7!vDv{v{0T-RPy d=`t #Iqb+BG"D'P[RcY] 3_g XPFQVqssC@߻`uCw "QʲZۡF{%-V[sc$9j#"""CdbHa\UL0V|;$cs̎ ;"JYgϞ>U}?^1- Cؙ6CvDD4躎-:KI7Uy/A(1rn%DOPuCپ];M ""2/AK~he4vDG$5>y[[B+ODD4"Uq pXs BӍn ʼn ;"JYӧOjE(5+XQbx[_bUb6Yhr(MHJ )`ŽxCD)p \ [ u`7DDDq8Ip8"NXO>͛ uuuXfZkդŒǬagBDD#ցsa"N;4@9I'@"C^/***D4Lp"I`:u٘ ;Ђkn!jX8(a}vx㍘:u*}|ؾ};E4LjllLjTA!f.JW~K@u ""EL:\tt[@D $awQ,_6 "@D&mQP9GkqC3ג$7DDDXSR.R63d ͇,6D'!ceN''Ugp""f蛅ţ.2DDD(t΋d<:Di@Hnܹؾ};~?dYzظq#͛' DdRF! Z5RP ᘊm- ""2Ĕ\;#/4 1d~H~ѭ 8 ;{l`͚5'x+Dii&II2'i/3 F$a #ZcH#0fQ$$Iŋ1k,47GN.KDx"21]qN Y9ŽF&]q$!s*0%'#29! N.I:"_PCF\ BSBDD#/I+)bQ=8̒۽{wΝ;7Y "^y^a1)>rZN ""NdG%IZ®jhB,˘'  h!ZN ""NuҒ>1(13 I@dv~}v#@D)Nu(&^1(a:~Ҡ Z,+7\/&%F8t]7zg/ IDATD'Cv\| j X!a@8j- ""2&+2c*!$?Df'dJoF۷7p&IUqDMrHDRnQSuM!fhkt3(BNm6[&NE!?'[D?U f]œk*6- ""2ĸl8'f3hDUA=h"J! ECDH =Qi]_DDDDݩF$ g*}YM " f -DD4"jWî=[X,JJ[@Dqs]QWǂDԿ&Q+Nh E# 2@5~q9$.%7%ERFonGkǃ' DdrVjؽc-Ü\d4itVpQ\0J -`t (NIM=3/BɲkMfZBFة߅Ť8In1ʼnR  ;ӑ9s쒚 RosX"Ha` FY'hDr)bUԄJ[@DqJ]w%" &2hAq)~!- ""J{ZX\F7┴1qD(ԩ<Qr\V` ۡ+9ʎ(j-c1>lt+h(h9F7␴S۷cĉaŽ3.[ fg;PtADD$T)IXWct+(IKu):u;@-`/@ !G0Q ,uGי*4%f(Y{d. eymhOȿN(cG!!@w%BHE,@V%ʕ,1Rs3n~,RWy"[@kj {n .اEn$[<]|ƖyX4Z.{|Xd{Zϱ\nJuH͵6~ o=/pBW3\12ER X~CK]d!pEмƵψP.,䆽@cސ66@vn X hC!i"B+ ;, T@ DS;8YߣC}uDFBXmI [PBXZjY cP-r|k'g&e'`.;Oȑw 4%Z ExoK-c4dy=u|sim]0@_]9^h rI?4dV"7Y|,؏CgP{Z:>9Z$:_HٷtBu@3}DpZGW rd1o;wd4!G}߻H#I҈QlЕW^ }LuٳW_}&N$̘1CQQA""""""""T#d]]]*++QYYÇ:PWWvҥ"d G~~>pAo6iDDDDDDDD"M;wnZ5oƦMzQRR;#5IZ;p+Jmn|iMDlJ=zDz<' dgזwv6Xgǿd|%@3Y}03|辏$81P> >0Hߔ!P}G%6P;nzl7^[h00uTL:5}#&Fqt[h;]Sa?]49P3豭qRR˱f[.{%.w8mme4AkvA-~8GGkh8@Ȏ*-r{Կ@B 8vIdU"hq.7ZGYJPR(z(ɷ32 h:WU #D]֦ȶV5|'Yےz%@D^;e8(.h9:҆GW$pv7< Nn. Tg ـmL^Y @kT#QR P/pEukB3]*j|%{z@=sGdGI| P‘cT@ V"r9aE[ND%@ p2g~!DUJ*Tp=,yhW8H `@0wf=WG|(a}vn@=ۀv/ ;KɎ?[hY%+MrJȝuFQΉ@8ymGAB9yH\},D>?cm*=Yl5"\ֽ_&)@Ux}m|8jQ{>4t68oјpH ) %1VL#aBbVJ1Ke\.m㤮]qe-mU֕Ri:dn@Ky2IY@ ABx`fݳ/4<~\Ɯp?:I[ ȋ&IJSsl= yVbոLRn!/bГ@e\W}_8kAHT sJV?ffyE/0jUA##ԋe2FbRB ɲ+f䞄F0>jRFvع7xCo_=i-ݎt̮scviE s?A%-~c.]$&ϩ7iݱctݻzmʕfQIJSBDil\4mJGhHf$awi}U*21vX~M.;@J2sgw]d:yٱc\ 1:cnVs1㲲cAF %$)Nlj3Lr]wƩFsal6dT%oȑX˲fϯ01 kK۴,9=AOm)oh;kwXhX ˲3ϴd]3-cwKG>3bfa;Gd =u2;w}YN=zuLn7B.Խ9i`t`w.ˑDL1)a׮] ceL͝Q-P -ahG&cAoDҴvݻWGC=˲ yknV;"vvd2FbQ3{$Iϟ_4PNұ$YA^{8hxvd2FJخ(:I}K_21 Jۮ ^,AXYkvu\M+80r:k3L&L&庮411PeYXm#㠁<@ړeYX@af~WoH,l붤b7lgoI"#w=^CVD(=2;~O~Vڿ)2Cw6ff@2p43od]낞:9[oi޽Ѷ>=C:v옉)Ms46H:@ J%6r2ؓkR)rDB.\055kKF㉈q=Z^vc:Iرcĝwީ7xCccc:uꔶnjb "}.y u}_'U|s1]y^i̾}466/~ :tDDӸ v PRdyKJl zdD'I=r]Wm˲?kdgT0:$ zthɥv)vd5%a;#)mtLԮD\ڜ@?YhTV&W~Lvg@0 >˓n zP,K; .ZE)s.;D`Hlhp}Uϑi HFkn@sz0Y6dMH)wD ;wFsv"#9M_AF">`ζv;u_1JnɾgNvD•'ҒDJVQ@۳ <ѹ1h@h 1-л8׋߱֊oYץiW?j~(mq ^@ I@=#c3Ž= c2FF$ A x4jyOfbQFtZCxyYS vBtgc7|,R.J D ;fd'MddGP1-PKm 63;Fy>ɊmfDz/-jeiwx~L:a?fn@Ο2muw\TiQS /Hބـdb@׋1QAO@L $ZQPHl z Ћ[xlAvdzݠ7"iH=;"nlA*iQ.Y2:jgH-_\4>&j=LHs. HtnKSn`5Zʲ,l팼F îs$ @+v ,҇2zn l zfk]VX~L:a?fd,qDc> M &;ZEv cFg@n>aYG@ a yMtA˜,]boƍcWx 9ۥ9*VQ)iBv6vՌoވ5v؅:HhfAoD]tA3S$57j7|* HSGbV%#s1YEff0ԧ0AE }9V؊=ӷQTވTh8h= @@$\v3R,tB_G@=#r22l'7x \ 4 ;74t#tBHvF> @+ a NWwܼhl,ԏ.v6s`4 JK:oU:O= ͔ F$M ]z Km ݭޱuve}%,84+(gK$u<=˲tڹj}~N^g@:̌CӉ)Lʎ= u@$<HVgr{LI}X͏[팼F#\@q mksGR|\ac`Wc1XB4$& z y;17 j‘@;F;n^47j 4 ;wy5>EUʑ@[:c1 E aK8EAOkvenR :F°T LyV")M]?nl<Ԏ\@k a ҝb2VT9]nf ԅv׷ΑS43֠7"' #H Lm07jF C@QAvBo"iڗ;Pn3viN W3N d;IEMvB/뚭'w(x4=qXI3y Z= IDAT 4[tݪ4hPºs c 1s6^@ a Rq[ݖ4F$. z d Iz-> SDMh:v"2Ͽ$7{T02#It NЛ{teEA(\p7~fth$ɦvFRx=d Has-d0wcҐqq@3tB[6;(z )hI;#s+==™ z ˚," *G=moʛU1:xzxTmO,\7#qPs-Fǣr]=1Ik64Z ;tު(r I0;;6&4Z ;J\@cһD:o\:G]aLi<]Çoկf:~N>-qo>=OLLhhhHoR>iϞ=Չ'tYkh7 -I[*J/ re@x[Iq#ccon \ݛ :}N>/J93߾;R>ϨP($i߾}$uo}Kwֳ>)}V<׮]$~7~:tHcccz饗O+nhr|k&?Y"ZM76jgSD:JJ&[zΟ?*N_>亥z.\P>Jdt! oG>sw^R) ~ D:zA럌xNOS p?I*J|' FZ;$;vL588ݻwer.%ZT<]~]YvnիWL&u޽{ѸLf>R'ys ¹E{1vո'#7"OIU xxƦ]Mf2hވص҉1>a7+.HhllLׯ롇${JRqٶ=@ZvM<^#fL&5111}{>>::*`qF#jsHZ;  j.?Z GhGhG1"FBzzb%v/WLt-^tzQ-J' /}]iR 6ʞ={tu]}k_SvillL}}}7þJY37lgT02jёwgӝQ-=xxib$,pS?1c}D.vڥ/| ^Ҏ6IڰaR׾>_^.\XtIӣqRkrlV"r ˲& +I"mۑ7׷Q4bQZxsBmnfegGnexx}ݎ,O33zGbl]IhSVOصob<W*Zv%m7oo(6w$u.dt̙Eu~hӦMɸ۷̙3Ѯ]!k,KYcҐq#cF k_@xmod].rhm)qeY_<0۴ivء!kttT80۾}511=zTO޽[z411_Ҿ}(w  oǍ;4˝ WqOu԰ h-y$RmkxxX.\ׇ>Eu,O<ǏW<׾}_8>OihhH7JtAܹsd2~ZCCC:vue23ewsLE.E@ rg@l痢\k8԰ϩ0j]:O{3R,+un57@K@[ImuaޏIo[,dӉOL CAOM Ƣ&2BtY77^#Wd_sް&,j:ʻ9y!fv3E*=u_oFbQhAO*qO_BuP3xtc=ވT S,$b?_?q:JK8¢&BHSx/]sI1&~dضW5w0v/}pknϗdedS5o4X)dȀԵ}AqBב.}~bTo1R5$I^5t;$g,˒7KHݛI-v"γFhvc^,*ndRaV|wKcRa[찝GeۍiUst{5Wba͂s @X6 )j̋jg!y WE+^v)^v9R}u79Fc  7^_%1'ݕu }_@ߓ$Ȳm[4?cǤ!돚>NK*?{4^sBpz1ĀTlf^S[bђdu wXJ# $H!a+8o7iDȊ5T|߯uxd 0]hJv"<l.X>VhhĔ}uuK^W`efWL2H:a&FFJ {0wNPSy5fC{u T\7Sh@d:hb4{DXjV3ꯜ,k:[_M~Q䖲]\+=~h:ʻ@ݛc9MדV|q6_y7Λeb*ő}RGz*yS;Ж ]T[VZqzT!Jw-:~,slU%!ov3 }Q]]RI/^}t{iփo~t  hYzyt6;NudOu#ZW$f]g9[Py5Ig,Kގ5V7]!YY$W_/unH~Lua s@9B;y뿧ZЬ1Z e,Z)%*;RzK}&6;\ږR^vyw?<0QW}%~两!k_k\ c|+JZiNH@k"a 29Y/:ƢU5u뫉?ε/cI{tAۨ7c7_Yᳮ$)ݮܞ/9rFXlR,$9>;+WBKCr$1.IP hIx Uz``R&UXjە 1F<2>w>cZؘtq2,*mIHݛeYV]d+6 @[+'wv͖ -oTy;WnϗJ#г,K7ہ6]i6G IK=+P9W.{ݚWdU;zō{n =?"G^MG2*"[qYĽk/5юgJ ް?јםM }7Om%{jlNv /K2_7;vjۭS3:ב~oŻmw|ߵ~H@K"a 2~'j;1>"XsםL GkՒY=_"0`#VR^(%VMdb@AoD”=8fIRҸl\R1T9Uӵc״_˻9|IVv`鑟#P ;1S >KG2؀mQpZi`~~Ai5 %~ܽh?~ѡudeǤ¥/*\*]׽1hUAGsZ/LM%\YRojOeTC8l’dBs,OxTםBhXȏ{4B,w]':ձr^:tέ8\ %c=~m]laN:ЏV|FWFWZ1T%z5O,Hk`O^?w%N!@#a 2n*Uk!kk_44Eu薚C署d5s=i"_T4:I;OukuK]\JvmJO,Բ8_wp:@ *ә5\1dSU݊-֡FAo֭m[^yέ2Vb%Uy"\2 KUӤ„JO,T z@Q@$p5p21-,,;zGf^]7OG5WSn~-ʾSߏeYv)8BV0;t׾Vm@ZCJ*k°GK;}D3 ;Vj+[={UA劺M{N]e5ŗ˩7MR*^׻]*sGJtbd[`\I%M*L$YYc5u~Yh$Dji9]zJQ檮UZu zmnKck*tbrq_덋R.>7DMSQgԠ\0{3uEk-"WH[˚jr[z y)˲ĤX]մؠ(H Í)ӟֆm5/>]Xl GmD ;# V,K5]Mb9@G  xOS ;#<;ZPR>DZ/3n:[ h~'vkQI4틄HH',B{FܹґJuG>y*l-X3޺PXZnזlRhO$Dxm*J{-pܹ;7*/p54@Z9/l>RO]u:[n׵&"!5 z#c3=16f IDATж-D_}]`&@ s|4)۾z,C@$]0Uug&dNBlr>|?h=a%R+KJmDTk@$sc3w:ETN%Y1csG ֎|Ɏ]Ӡ7bt^2^zZ ;\SXѰWXjI^qhht'Vv_X#ء. ‡s\,c&U[ĜJwzNe9=U;Tz]\=G@dx'N&4gy}jS$b##a 2z,Wi[=N$J PW(oSKuR*ݏ-ķtX̶mB6U 8GZ&zq)[%*`lv$d%>Pv"Ҵ;ԣM*hcBU 8]H:GA@dt&A Bi*$†@|nYath-bw4N!>P/ "-=[zAO5SdW ;ĂV+޺blVD@$sci `U7Our*~BӬi@!a 2L=P QX)'H,F|.tHD]bL3} HKl8,'">P/v"IWw@9DW&Ԉԋ;}_^г@9Yd]ԋЛ{& ?%a+cD|^E+Rq;iЖhr^GE@B^3EҴ4hK4/#)@zgr^S,A[程'P">P/nBϲ,l7j7 <ԕ z Xz [N (BA:!Y _L|$D' I07 M =V71RCmIG@lvth hܛ6wiNh}mxZuԇ9zz rHXkb˲ tW(OK:.k}MWGjp5NbnL685-i(=QܘU~fN}gNi F=D[ zhU *HGm @=H' VwGt="v+$=#wҷ uα 푵2Bk˺h^$DNػZtW{p0{|$WDS. r6[Z+i6>նxSq$DҶ޸`O0קw&Ԃ/yzti9sFΝ8?edY?~\O8ڷoxEۗ'&&444zKTJЇgϞE׌ĉ:{~ ,kddDCCCQ&сdZɼ]77Ͷ^bLw#-.}|]17'͍f7h>>qs,@Zuw#u|FO=N:׸o}[JRzg裏رc:{5lV7uws߯^zI###׌^߯}so~Sccc-}l.yvc !;#=Hw6g2FIOn/|5O'n߾#KK'i׮][W^uAiGА\ו$]pA|^W*R&ѡC444$/a:sw^R) ~6?~ٳGTJ{}ݧ 34np۱1Ulݸl~q:QG=_:-ݭ7J/01R/(sPA;z+|K~HGbru]J&y~522mݦW*)L… ڽ{d2I=˲tY߿5;wWysIĹE{}u -ؕ޿nZ}_ݵ/n'oj z飛l}gzK_={#4#4#4OW=S+[J1ҡ-I#e^"b$G {OTjǑmɱe㥣qlVdRڵkעk<ϛOꍍ-J Jx9OemGccct-IFkU^k㷯0[7ktjAR+_`ڕM5VgUwJ܏sHJ#ӮŎ{f6yY7r172f4YKZl 1ڐQ'#/bkJ^%E@9[ɞ={t.k_#[vVl u~:Ima{;e9kTwzw #4#4#4Q԰RXGqG t_|[ ]ڵK_VfNr֯_ .,IӣEER)eEr9ٶD"!I[veIdbb 6]PчK^nK#_g!Aj^ms 3jj$0~F}F}FX>jTTws37^[4VPtRHh'Gob<W*Zۼy~E6lTEw̙E5~hӦMɸ۷̙3^{ddDvܹsQgYI:{vY67h2'd?^e\SoZ*Ί,AjTT)7dO%##(r jdYkzzZi||\GQ7mڤ;vhhhHի'o.qtqMLLhddDGՁqw^{5MLL׿o߾ 7ӧ511ӧOԩS4Z@AX;|hprO{xSO" @#艑!rGbokIg?Y˲,=:~yq۷O<8O}S7 R)5W~XhP1d]^dhf_0FfHv"Kr:-U+)ɗV1lnK3ؽ}ɝ=n/JOt*% J_٠HSmTrQ#F\4-ݷ115WO?GX ;7AbՄ&,&eTQPBI\pc>ps;OKB'?;?/^{Q*w9][.#)6 Mf&g*ow4=3Xݖvإ𻤗Ifl]tjlNmssx8)E(XFaW 3SܑZo'!?ց($d4wJmNgi+>3X#65߭9R$U!xQ:sO7?nh&lvfɑ;Zjm||A"uEvNbS#;_%fFZfs)}2m!^cB X3#ef'*.Q,[蓻IԻެbWr$#55T֤X-kkJ勸$Ib.};S@H[:dv#h9Վ5z[G6;wŮ`MNv.1I̥O7h)<9ҁ**HGV;F'kJQ{ KYY%ٜډuͼ!I̥O8G/ʑԅ9G"?P@9mp;%eO4) n[n*H*nӓ nQB_Rw|' '!:ǷkOD~```MJ{=}Qf߅ٕNs(^Ř#X(XR 2+0I" r$X `MuW4nXsыP GZSHQ̅qABX?ǣ3 Q^ԝc/$4_A %6( o-~bsABMf\ڙ2O&udsXˑ~Qn HV3yQ\KRlLTW$XWIn`#!;r$+o DRS MBtHST;bA`Pd]εZ@`Pdr;=`- GRE|ngj7g]6Sl 9Bpho͹ 鷏or49(Wlv?g8K:٩ t ȑ }UoprSDRqÔUcPȑ,7 v99_W9D vPl`#`;F((:c7L\5@!GztABNZ!MNUopgsA"193{nRSdF P fsȑp(( i޷ǺJr(*H`OX" ␦vł 쉂7r*k; 쉂u6`- G{bP|nNIϺ8lJ~g@ G{`(8m97!MN9 x#=1(:)+%Twa:P@H`?/7nX"ar1(nH`/!:  Gr `#`;F(6B vPl`#`;F(6B ,a¢%IT8B>G@!_%Jj,Ud6O8Q`$'rcfffr ݕE1 C'NPWWת;8B>G@!# |(T9N9ko7fح"C^X2F!#q| XB>GJ*F~ֶ *)))twJG@!#q|!Q~=IDAT`# ;F(6B;ɓD"ܬ>]|9g:x4M]vM2 C jii]"466h4'~nFFF۫jڻw|>_Zlc^IRcc#˵rof82MSQ$Վ;{9nܸk=&ֶlQeږ-?>~mIb<422ݾ}[Gڽ{wFCd#r$"i-H(LZuI;vL`P}}}Vkkr[oT:|&~UHD_~N>fddD:t֯_ݼySǎ'عx&''n=cn őaΝ;~z˗/4M:tz+:6w"ֶlQeږ-xF3gΨx/V+W(ѣV#!lqD\2#*#X4-ks玪qFMiiiZK.C`P~_mmm B 2~f._+ 󩵵UDBwܑ[b1 ]@Vby,G.KV ۷O_|Egq8ZY{.#־lqtx^ݺuKvʸ񨸵F>O>OS$Q4Dd#r$"["GZb\qCCCy֯_[In[FL& ^W/(333F9)k֭9N4UYY&Lh4m:7Ǐ%)cz+WtUTTN Vˈ#<-Hڵk3#=zo61{eovz5==-I9N<p?"!>0g_OٳGGĄ:::$GϹ8FGGz3.L2ii_;v찾#a拣ȑͳipK,АnBSee8p8@1MS}ɤٓ[* ) ࠦ [ 2/0Gxڵktm߿]*-ȑg9ʡ`%Ю]lzUUUe݋rL&eFZX,e/mH$Ҏq+.rכƂ.4M]tIHD̺۔鴮Gk)2&''u]fmxT544δ[r$,Ƴh9r-F|(anݺkq?^EEN"&.ka_GiWfLȈw.SQQG]ԣGvg6)R]'I-qr.#0͛zWrZvvu>|xMIȑM8mCGs#-~V4^MMMׯTRB?IOq;FX vPl`#`;F(6B "?.0 ݕ%:~$e1ٳk}B;Z?^PHwﶎmܸQ]]]r:y<uuuW_ի̽(.pK\e @q`}}}qnܸO?TեiSi۶mڳgO{2 CW^x 3XnYHD`PRNOOg8ǏٳÇuiB!B!IbuA\.a:uJ|>_Ryy:;;Fuݽ{W/=p8g>xi7x IѨH$gꭷRGG?QT__/4uq3gΨNxb~vkzzZi>gl:.KNSG^W^*,͕L&"߯`0fE>Oڹs$)W |SCCFGGr555󩦦F7oV"P]]|>jkkr kKL&#B!|>w^jz ڻwz{{%I͛7uAy^UVVZ k.[o/vۭWQQIIҝ;wϾ53~~+v͊+++S0L[L>$kG}:a,z\(J+$f9|>E|\.Z[[u)ܹS۶mS(<::i3LǏe&'' 9p||\;vH;VUUni@ X/&$ܹSᰶo߮^z) r`1vf ;vXeSZZS򥥥E;vt=zT@@iúwnE.B>Ν;:u|MgF`\.d_wR3V./߯:;wN ںuѨ}S$Q,w]UUn߾zx,…TTTʕ+2 *.4ۭ( … a ;%| ÊJ$yۘ_ׅ ןȈ&&&;C<&''DqFIw}}}V,S,S8̶]pAHzH$"Ijhh1VKKK}ܲeԦXڵiÚ_XX ̰XW?~vKK***ݭH$"ϧW^y%vǏ3mBr:Rbg/ ?tE\.mٲEv^]:{*++g~=K.:::].:;;ӣ>ڸVáMLLvkǎS,D"Нq{M:qK,*411{RXa3`;F(6B vPl`#`;F(6B v nJIENDB`signal-estimator-0.0.9/doc/example_bluetooth.drawio000066400000000000000000000436621452044147100225130ustar00rootroot00000000000000 signal-estimator-0.0.9/doc/example_bluetooth.drawio.png000066400000000000000000002230601452044147100232660ustar00rootroot00000000000000PNG  IHDRbUsRGBp{tEXtmxfile%3Cmxfile%20host%3D%22Electron%22%20modified%3D%222023-09-19T11%3A47%3A09.622Z%22%20agent%3D%22Mozilla%2F5.0%20(X11%3B%20Linux%20x86_64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20draw.io%2F21.7.5%20Chrome%2F114.0.5735.289%20Electron%2F25.8.1%20Safari%2F537.36%22%20etag%3D%221W0R37BSvttXApUQUEo_%22%20version%3D%2221.7.5%22%20type%3D%22device%22%3E%0A%20%20%3Cdiagram%20name%3D%22Page-1%22%20id%3D%22zG4t0KIrfCX84SrJccn4%22%3E%0A%20%20%20%20%3CmxGraphModel%20dx%3D%221461%22%20dy%3D%221018%22%20grid%3D%221%22%20gridSize%3D%2210%22%20guides%3D%221%22%20tooltips%3D%221%22%20connect%3D%221%22%20arrows%3D%221%22%20fold%3D%221%22%20page%3D%221%22%20pageScale%3D%221%22%20pageWidth%3D%22850%22%20pageHeight%3D%221100%22%20math%3D%220%22%20shadow%3D%220%22%3E%0A%20%20%20%20%20%20%3Croot%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%220%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%221%22%20parent%3D%220%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-1%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%2260%22%20y%3D%22220%22%20width%3D%22310%22%20height%3D%22230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-2%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23fff2cc%3BstrokeColor%3D%23d6b656%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22410%22%20y%3D%22270%22%20width%3D%22120%22%20height%3D%22130%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-3%22%20value%3D%22%22%20style%3D%22ellipse%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Baspect%3Dfixed%3BfillColor%3D%23f5f5f5%3BfontColor%3D%23333333%3BstrokeColor%3D%23666666%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22510%22%20y%3D%22280%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-4%22%20value%3D%22signal-estimator%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23F7FFF5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%2280%22%20y%3D%22305%22%20width%3D%22120%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-5%22%20value%3D%22output%26lt%3Bbr%26gt%3BALSA%20device%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22230%22%20y%3D%22240%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-6%22%20value%3D%22input%26lt%3Bbr%26gt%3BALSA%20device%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22230%22%20y%3D%22380%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-7%22%20value%3D%22%22%20style%3D%22ellipse%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Baspect%3Dfixed%3BfillColor%3D%23f5f5f5%3BfontColor%3D%23333333%3BstrokeColor%3D%23666666%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22510%22%20y%3D%22350%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-8%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22dpNZ1pyAjNEpY7W1gUOE-4%22%20target%3D%22dpNZ1pyAjNEpY7W1gUOE-5%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22200%22%20y%3D%22220%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22250%22%20y%3D%22170%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-9%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22dpNZ1pyAjNEpY7W1gUOE-5%22%20target%3D%22dpNZ1pyAjNEpY7W1gUOE-3%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22160%22%20y%3D%22220%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22210%22%20y%3D%22170%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22390%22%20y%3D%22300%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FArray%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-10%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22dpNZ1pyAjNEpY7W1gUOE-7%22%20target%3D%22dpNZ1pyAjNEpY7W1gUOE-6%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22160%22%20y%3D%22220%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22210%22%20y%3D%22170%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22390%22%20y%3D%22370%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FArray%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-11%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22dpNZ1pyAjNEpY7W1gUOE-6%22%20target%3D%22dpNZ1pyAjNEpY7W1gUOE-4%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22200%22%20y%3D%22220%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22250%22%20y%3D%22170%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-12%22%20value%3D%22PC%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%2270%22%20y%3D%22230%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-13%22%20value%3D%22sound%26lt%3Bbr%20style%3D%26quot%3Bfont-size%3A%2016px%3B%26quot%3B%26gt%3Bcard%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22440%22%20y%3D%22320%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-14%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik0zNjAtMTIwSDIwMHEtMzMgMC01Ni41LTIzLjVUMTIwLTIwMHYtMjgwcTAtNzUgMjguNS0xNDAuNXQ3Ny0xMTRxNDguNS00OC41IDExNC03N1Q0ODAtODQwcTc1IDAgMTQwLjUgMjguNXQxMTQgNzdxNDguNSA0OC41IDc3IDExNFQ4NDAtNDgwdjI4MHEwIDMzLTIzLjUgNTYuNVQ3NjAtMTIwSDYwMHYtMzIwaDE2MHYtNDBxMC0xMTctODEuNS0xOTguNVQ0ODAtNzYwcS0xMTcgMC0xOTguNSA4MS41VDIwMC00ODB2NDBoMTYwdjMyMFptLTgwLTI0MGgtODB2MTYwaDgwdi0xNjBabTQwMCAwdjE2MGg4MHYtMTYwaC04MFptLTQwMCAwaC04MCA4MFptNDAwIDBoODAtODBaIi8%2BPC9zdmc%2B%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22520%22%20y%3D%22290%22%20width%3D%2220%22%20height%3D%2220%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-15%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik00ODAtNDAwcS01MCAwLTg1LTM1dC0zNS04NXYtMjQwcTAtNTAgMzUtODV0ODUtMzVxNTAgMCA4NSAzNXQzNSA4NXYyNDBxMCA1MC0zNSA4NXQtODUgMzVabTAtMjQwWm0tNDAgNTIwdi0xMjNxLTEwNC0xNC0xNzItOTN0LTY4LTE4NGg4MHEwIDgzIDU4LjUgMTQxLjVUNDgwLTMyMHE4MyAwIDE0MS41LTU4LjVUNjgwLTUyMGg4MHEwIDEwNS02OCAxODR0LTE3MiA5M3YxMjNoLTgwWm00MC0zNjBxMTcgMCAyOC41LTExLjVUNTIwLTUyMHYtMjQwcTAtMTctMTEuNS0yOC41VDQ4MC04MDBxLTE3IDAtMjguNSAxMS41VDQ0MC03NjB2MjQwcTAgMTcgMTEuNSAyOC41VDQ4MC00ODBaIi8%2BPC9zdmc%2B%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22520%22%20y%3D%22360%22%20width%3D%2220%22%20height%3D%2220%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-16%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22870%22%20y%3D%22220%22%20width%3D%22310%22%20height%3D%22230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-17%22%20value%3D%22loopback%26lt%3Bbr%26gt%3Bsoftware%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%221040%22%20y%3D%22300%22%20width%3D%22120%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-18%22%20value%3D%22bluetooth%26lt%3Bbr%26gt%3Bheadset%20output%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22890%22%20y%3D%22380%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-19%22%20value%3D%22bluetooth%26lt%3Bbr%26gt%3Bheadset%20input%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22890%22%20y%3D%22240%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-20%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BstrokeWidth%3D2%3BstrokeColor%3D%23CF0000%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22dpNZ1pyAjNEpY7W1gUOE-17%22%20target%3D%22dpNZ1pyAjNEpY7W1gUOE-18%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%221000%22%20y%3D%22220%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%221050%22%20y%3D%22170%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-21%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BstrokeWidth%3D2%3BstrokeColor%3D%23CF0000%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22dpNZ1pyAjNEpY7W1gUOE-19%22%20target%3D%22dpNZ1pyAjNEpY7W1gUOE-17%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%221000%22%20y%3D%22220%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%221050%22%20y%3D%22170%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-22%22%20value%3D%22mobile%20phone%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%221050%22%20y%3D%22230%22%20width%3D%22120%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-23%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23fff2cc%3BstrokeColor%3D%23d6b656%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22670%22%20y%3D%22250%22%20width%3D%22120%22%20height%3D%22170%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-26%22%20value%3D%22bluetooth%26lt%3Bbr%26gt%3Bheadset%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22700%22%20y%3D%22320%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-34%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik02ODAtODBIMjgwcS0zMyAwLTU2LjUtMjMuNVQyMDAtMTYwdi02NDBxMC0zMyAyMy41LTU2LjVUMjgwLTg4MGg0MDBxMzMgMCA1Ni41IDIzLjVUNzYwLTgwMHY2NDBxMCAzMy0yMy41IDU2LjVUNjgwLTgwWm0wLTgwdi02NDBIMjgwdjY0MGg0MDBaTTQ4MC02MDBxMzMgMCA1Ni41LTIzLjVUNTYwLTY4MHEwLTMzLTIzLjUtNTYuNVQ0ODAtNzYwcS0zMyAwLTU2LjUgMjMuNVQ0MDAtNjgwcTAgMzMgMjMuNSA1Ni41VDQ4MC02MDBabTAgNDAwcTY2IDAgMTEzLTQ3dDQ3LTExM3EwLTY2LTQ3LTExM3QtMTEzLTQ3cS02NiAwLTExMyA0N3QtNDcgMTEzcTAgNjYgNDcgMTEzdDExMyA0N1ptMC04MHEtMzMgMC01Ni41LTIzLjVUNDAwLTM2MHEwLTMzIDIzLjUtNTYuNVQ0ODAtNDQwcTMzIDAgNTYuNSAyMy41VDU2MC0zNjBxMCAzMy0yMy41IDU2LjVUNDgwLTI4MFpNMjgwLTgwMHY2NDAtNjQwWiIvPjwvc3ZnPg%3D%3D%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22580%22%20y%3D%22255%22%20width%3D%2250%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-35%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik00ODAtNDAwcS01MCAwLTg1LTM1dC0zNS04NXYtMjQwcTAtNTAgMzUtODV0ODUtMzVxNTAgMCA4NSAzNXQzNSA4NXYyNDBxMCA1MC0zNSA4NXQtODUgMzVabTAtMjQwWm0tNDAgNTIwdi0xMjNxLTEwNC0xNC0xNzItOTN0LTY4LTE4NGg4MHEwIDgzIDU4LjUgMTQxLjVUNDgwLTMyMHE4MyAwIDE0MS41LTU4LjVUNjgwLTUyMGg4MHEwIDEwNS02OCAxODR0LTE3MiA5M3YxMjNoLTgwWm00MC0zNjBxMTcgMCAyOC41LTExLjVUNTIwLTUyMHYtMjQwcTAtMTctMTEuNS0yOC41VDQ4MC04MDBxLTE3IDAtMjguNSAxMS41VDQ0MC03NjB2MjQwcTAgMTcgMTEuNSAyOC41VDQ4MC00ODBaIi8%2BPC9zdmc%2B%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22580%22%20y%3D%22365%22%20width%3D%2250%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-37%22%20value%3D%22%22%20style%3D%22endArrow%3Dnone%3Bhtml%3D1%3Brounded%3D0%3BstrokeWidth%3D2%3BstrokeColor%3D%23B20000%3B%22%20edge%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22660%22%20y%3D%22280%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22630%22%20y%3D%22280%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-41%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik00ODAtNDAwcS01MCAwLTg1LTM1dC0zNS04NXYtMjQwcTAtNTAgMzUtODV0ODUtMzVxNTAgMCA4NSAzNXQzNSA4NXYyNDBxMCA1MC0zNSA4NXQtODUgMzVabTAtMjQwWm0tNDAgNTIwdi0xMjNxLTEwNC0xNC0xNzItOTN0LTY4LTE4NGg4MHEwIDgzIDU4LjUgMTQxLjVUNDgwLTMyMHE4MyAwIDE0MS41LTU4LjVUNjgwLTUyMGg4MHEwIDEwNS02OCAxODR0LTE3MiA5M3YxMjNoLTgwWm00MC0zNjBxMTcgMCAyOC41LTExLjVUNTIwLTUyMHYtMjQwcTAtMTctMTEuNS0yOC41VDQ4MC04MDBxLTE3IDAtMjguNSAxMS41VDQ0MC03NjB2MjQwcTAgMTcgMTEuNSAyOC41VDQ4MC00ODBaIi8%2BPC9zdmc%2B%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22680%22%20y%3D%22260%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-44%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22dpNZ1pyAjNEpY7W1gUOE-3%22%20target%3D%22dpNZ1pyAjNEpY7W1gUOE-34%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22610%22%20y%3D%22230%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22640%22%20y%3D%22309%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-45%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3BentryX%3D1.1%3BentryY%3D0.495%3BentryDx%3D0%3BentryDy%3D0%3BentryPerimeter%3D0%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22dpNZ1pyAjNEpY7W1gUOE-35%22%20target%3D%22dpNZ1pyAjNEpY7W1gUOE-7%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22560%22%20y%3D%22307%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22660%22%20y%3D%22293%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-46%22%20value%3D%22%22%20style%3D%22endArrow%3Dnone%3Bhtml%3D1%3Brounded%3D0%3BstrokeWidth%3D2%3BstrokeColor%3D%23B20000%3B%22%20edge%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22660%22%20y%3D%22260%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22630%22%20y%3D%22270%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-47%22%20value%3D%22%22%20style%3D%22endArrow%3Dnone%3Bhtml%3D1%3Brounded%3D0%3BstrokeWidth%3D2%3BstrokeColor%3D%23B20000%3B%22%20edge%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22660%22%20y%3D%22300%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22630%22%20y%3D%22290%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-48%22%20value%3D%22%22%20style%3D%22endArrow%3Dnone%3Bhtml%3D1%3Brounded%3D0%3BstrokeWidth%3D2%3BstrokeColor%3D%23B20000%3B%22%20edge%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22660%22%20y%3D%22390%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22630%22%20y%3D%22390%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-49%22%20value%3D%22%22%20style%3D%22endArrow%3Dnone%3Bhtml%3D1%3Brounded%3D0%3BstrokeWidth%3D2%3BstrokeColor%3D%23B20000%3B%22%20edge%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22660%22%20y%3D%22380%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22630%22%20y%3D%22370%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-50%22%20value%3D%22%22%20style%3D%22endArrow%3Dnone%3Bhtml%3D1%3Brounded%3D0%3BstrokeWidth%3D2%3BstrokeColor%3D%23B20000%3B%22%20edge%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22660%22%20y%3D%22400%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22630%22%20y%3D%22410%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-52%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22dpNZ1pyAjNEpY7W1gUOE-23%22%20target%3D%22dpNZ1pyAjNEpY7W1gUOE-19%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22490%22%20y%3D%22307%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22590%22%20y%3D%22293%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-53%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22dpNZ1pyAjNEpY7W1gUOE-18%22%20target%3D%22dpNZ1pyAjNEpY7W1gUOE-23%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22800%22%20y%3D%22322%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22860%22%20y%3D%22298%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-54%22%20value%3D%22bluetooth%26lt%3Bbr%26gt%3Bconnection%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22800%22%20y%3D%22320%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22dpNZ1pyAjNEpY7W1gUOE-56%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik01NjAtMTMxdi04MnE5MC0yNiAxNDUtMTAwdDU1LTE2OHEwLTk0LTU1LTE2OFQ1NjAtNzQ5di04MnExMjQgMjggMjAyIDEyNS41VDg0MC00ODFxMCAxMjctNzggMjI0LjVUNTYwLTEzMVpNMTIwLTM2MHYtMjQwaDE2MGwyMDAtMjAwdjY0MEwyODAtMzYwSDEyMFptNDQwIDQwdi0zMjJxNDcgMjIgNzMuNSA2NnQyNi41IDk2cTAgNTEtMjYuNSA5NC41VDU2MC0zMjBaTTQwMC02MDZsLTg2IDg2SDIwMHY4MGgxMTRsODYgODZ2LTI1MlpNMzAwLTQ4MFoiLz48L3N2Zz4%3D%3Bdirection%3Dwest%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22681%22%20y%3D%22370.5%22%20width%3D%2239%22%20height%3D%2239%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%3C%2Froot%3E%0A%20%20%20%20%3C%2FmxGraphModel%3E%0A%20%20%3C%2Fdiagram%3E%0A%3C%2Fmxfile%3E%0A=z IDATx^X]bwwvk vwww'vwwcwwkE(|Ϲ~. .;Μ<<޹?̝ߜsMGC`X)0gi͈ + Kӎk<[VPbC [0O`ԡ̵' FY+ (W1\X5* =0Qyά`pXV`TU' J127OP beo-+ 2`LX5+ F繳 WA cXVP bTaf$+*Ĩq̝N# [h޶;JWPx+ b aXV`_1oCe)PP|smA*5܋OPPF٥{[aۆh޶jI׿I;4sb$A ^kPbȘih֦yUԳ ~ 8%L_;&uf3u2gwW4(g\ze#+ +m bx=m4[r'6h3vh#F5}:čA63aԮ\Lׯӥ 4gnQ-Lj5i&Ǘ/X0s"M[[[;u i"w\8M={7N1|b+ ֯)@ 'hr'> &yG|gE3Ѵv91S1V,ɣˏkv7vH:| qK2샑 Fvq+ `cvɭCד!?9\ĈaC gNKW?7дKL0'쇟'$N +'p};*;XX0k"Pd9򜇄\D=Y4-Wϑ$i24nm:TXC"WILޮN;jc5Y bVQ7N1Q + X b,>ד1R҉,x߿# qMi~Rr d|-(+~޼  W,$J)+r+'L|̊3&umM8}>}@BEaCyi'X*:jPw^:R`{f\r bD!budȜ {ODrpu}k܎) fpq21\`XV@XQ,xHr'cJjdS("AG[1K3=[8~ 'qx/UK2a| ٻzK朼L䑡"]C50wpWf=L_Vԙ=e4fNn[v3K2&-;a?c8n瑫co/ L"ؙh*WqNCg1]>#t7KDI woP@:YsKb@&+A脠BZY w :€r̝۰BX 7N1UYV`X UAB%z2:)ãA 1 A!%B%gx6luYAN ;5A{q\P z;u!6j%:{(ש o> vM0Λ`_OQ6޹'RC^(.G3AJq^t>FݪqyṂ<Ν>&6 654Ƥ+D[7b_??©cоiM]tyChہ ȑ;,ŀEѱ@ BRsegg'(܈* rm#q2*+ + 0^wד1˕޿⵻QY)/gDXTH&z$"?VWTZ Oxo߾1{æBz+ヌ_ڿv;=7ž52fwxWW wfH%DJ☛O>c߮-B dqNX 5)i#FFG/z82ҮI ׀Q"2`LJ F ώ`XV@ 0Q嚥IeH;Q1sCyĐ'LG QȐԾ3A#훗:AQdd˙W$/Ybǎh{>~-W(O bT)W/C@-u 1gOq ?l_&)gj@ %X,+|}Pԭ M[҈& h$am/"[ gMAD9e}ܸVbhC6u5c&I*RgYF,R1i%AlXV`XhSALIo˽ b.=!v9m"L~#й1i"rl-)|ҮI#&FJKxT."6ɚ# *oDif3P9 @̧QBA7k"ˉ#D]ښzن}"> @%$ԸbUwc P1Wª@ M͞r9GGg!v=\eW'e/<;V@I +"*N3ccbּ' JЀ"F_>Ȑ)IKuL.v"o-cʼnMڢQ6Cm=@xL%)SEƭvA i~g.w܍:hEd)EB./*?bqغa%޾~.IPR h$J&C1ʶ7N1>_xv ͭsR)O0) &کHדjs4OKkAY b}}dg (I1Jsac}ڎ{=61_1si܇l \pWhQu۹s'r̉tݖ9 V>XV@ȡ 8(xyyaԩ={6rFOiӦhݺ57x+]]>.]:?^5>F(D1 bPiӦ rSQV- :eʔ1)+AL 01R@ ?Aqb5ΝcŊQk@()XsG̜9W\nܹ3ǏKbXv-RL 1i$|R%{ӧZjzãGPP! <qEɒ%QB[ԬYiҤ!CPNq5j:XXx+`"ĘHX iAqP2ԩv???k׮hIeݺuضm|}}QD 3fݻ5YdA׮]#\Rߴn-[,UիW͛›& xwm8qBO]^OF|e* FvU쬬ĐG 9ݐw(6bٲezd͚+WtވHS*Uo| 0@$KXV@! 0Q!#dC^:^Q^ҥK bF#G˓'O@p`رcE۷o/o^K[~P[n[ "7arĘ\b@N\zݻwIe̘1Fslb0NF7C'''tD~vG}+ R1T7fc bf͚ek>Z 0Qnbh$VO&{(٠7 tc%Q U"#d.D7IOOO:tH@ҍlfc jn'ND``G9h$ެ+A-ZXXx@ PNR9J p-JE؇z`}|4u휝د12)UW`cbAz]2 kRdPK:LdɒaϞ=b ~5S떎W: b*j bOmG˽T~<_( <:s/2) F&!-o b,<,E*`Hȑ#1bĈpu=z4 gKdK/1s煩WVemb#LRխ TAQAqhדjӏkĘGgE&b8 ;^3n:}b?߱h";v >}mZX15!m7-ڏH*i%چUVQR SN=o b,<%+/$ AtKGD:[|98tqu//~_y?,~AE%271n -qGK8J\.m+mh?ϟ?mסZ'RXϟ?QhQCW}דzuʕX`c`\=z08p pm <ʕL<2`YC̙qU޽ 4=@H%#RXKܿ僓S3q28$1t-K6mJx)RD>kq<>>휝6<5kmW9"ZU^*޽{ B/|޽{&MdϞ]}m WQ֭[WxH1Ƙ<[N:Pԯ_M4A۶m;q74KǎgG̕+WDrgϞ!UT)n:l۶ (Qƫ'7NK1E dAԚ*CՈ^Lsg<8\\.Kٲ _O1Wac} Z~xEMcʔ)uѣG)RDC׫Vdɂ G$I… covZlݺUpvd3fR9xGLܸqv ROjՐ3gNP=Z:rbͻtR,_\/eʔaҤIThmqg 3wxcYS( r&S f߾}?~=zYx1V\)n,˗7 2CWRW^aÆ-ҍŋC7S%B `y… 5kV} @ L2y"n7o :T0h 4j͚53maob3x)/}A Y@^ӧh^1?@oh|d}Ym5&:u'NW^_֭Q8y$lقׯ_]  C;K@Z37իW/}V ڵҮsOǏwGkXzF AziqttDӦMAu֝ґC_(W„ ѿh!ӡC)SFo ]^O=>n y`U  Ɛg -f%'EbF,C7V*tP$#FWAv)FƎ+ngC7dɒi$K7ƍ3͚ nϓ'O 0iYxnr@r8iO IDATnPeH=*UJ\״ m7y?7CDLۿڮriM r[eFÄTre(jb|W0Vȋ< -[&H@ֈjɣvJD8j?8885:Q14v/6!;KkCC&"zIHQM?۳&Xx05†]A O hDa1J׮]EF/iyL/i#g 0V˩tܦ16n"A -bȿD 5f] J_5yPzkAq/I +yP2 PЮ]+nDž-qppIҤDh1ɓ'rP.Oт\Kih(XxAd&k ƔrV@m^$RtT31Ѯڮrn #JK0?zI}CkfС:v>)7! Ei.rדrc9`u X 7N1 ;f&QHT~1Sg*\]>Mʷ 7fŢC`c87{ V4/N_95c%}Q>u|O F1éAT41r+j|{ bא[P bm=3Afc\\قy=y/??~_CE=}IFqS%%][KS`>vڻ#v{#FӵuÇlS.YT;[H88bvc4;tk*!#C;\:VAqgSr'զ< 01܋L 0IH mF'{X2ԅq1e͈| "^" #%A/ח/_XmF)A!m+W.K~-TRLTҐB;kVmFGdm#˷HW1C;bpU>=xT9gSk3fL艋1l|M7#iD_1Ɲ bOmG˽T~<_( <:s/2) F&!-o b,V>^cpIr[K35匶.y&|||DN Fi"B[j"eܹر11\14Zbqk^"L>1` nDoR=J+7Ȕ6}.~/S e,]OK, BMKgB̤IaG˽S1i7Վo67N1>_cv6ëz %ѣGعs'RJ&M\$ɔ)>|_q9=]ȃl%!d˖MlJA~&| ^DaJXdl)iGE R$ڥ^شO7ήGK1Ɲy߉?3gG4a!3b̀X3"VLuI'-zNXT;jq*r8(|1|1rV4o3gcժU>|i2E o?kV$Ȗ Cn"шB O/ ϣH"a> B8q "03{v9Od #FV~͈G lA}ZWQD—N^j4mP+24l+4/h[_J G'dl1K7(>b{=iY b|<e|P6hJe bdQ< 3G~ rI&GapJĈN ©P!8+~&@#Љb(G̟`%nܸ rx%$$WH ˗/DDqq WȜ #lYa1ț;Ksv;k>'pH"tA01r@ .`Lz@HPtU ;`?v8hI1|.X bJ{h;k UxU<|0,`Ȑ>!q`cܩ! W{w~?{t5.~maIaG3t 9`u LfЀ{t .~ Ҵ;Gn8na<ζ蔈+D@a0h`#EԽ4yd(w\inҡȁQ ! #vC iKr7yⅨʡIQ;?as^ T*_[Vy"^<{s% 0ѭQd5A rlCկCml'_!D3a‘Dg^OgK?A[G G V8\g@-xYl*&?ZyZ'P#Ⱦ}.#ʰa0z0M̘1ݺu 9r$x*x|F7\ʕssĄ7EH?~Jl3-΍93}JAq1q?' B/؅CeP+TCLx^Ottl8f4ztٳK }LAQ~K;K} 0QͭrUJ患3޼|1cV|/J/_>7.֯@D7O߹[˹cDXTx5"0!:fklw]C  ??]?xAep#z0m'XlmKt$]h)ɳEjvG*T~ I… aJ& ޽+vLb 3`NX..puwGuR@smq6^ş꺗13׉ b aovmr~&aqKWCZ_:b88ia4u-pn pQulAO8mZ䜶1P$yFQAbL쉴oV gN70{We+#~y ۺn\шb*TGC+W6Ǭ-V4s?xY6 vzͺH.]C_=TpA_|jhmj/*$*` 풴 #duuQ†6o,RmۆZjiGdm?7'GSYd)cCD2OoͶm|8r  %^ƄW~~"L)epD+9_-i#kNu acggs (K1ʲgv|x/wB=w\ |썀ku::Y;7\ʔbİ8eqXn~ 7ޡQwg>>>qܹ#gϞs熓>[g(Z(r__۽{<__ull'._!FXϿqbǩ +Y2vX 4(L5}]Upj&M1A3PD' ϗ[ӱ'GZۘk@et%yqKV@^:?,F=!cFLk1r#~V) ڢ`cQ'X8{ފ]"a5;BBBPruLEcV 4ANĩxL޴KѰ2y3~2, isJp:]ک(T=B*UDiRR%?;<ߏgϞvmpӏ?0U+T{Ξ nD"9ͫyp5黃I(i\kU]z<RBbқK,Y2e%ڇA%@s_{vSO &$>k yHx!ϗٳ+ &7Ď-Ѹe(V!xlܿS%MWؒy&,m32tYD b<y~}0hm݊;\ġsa nfW7ux兟jQ#fS[n%-=17{OD sc@g8|1ڵ Fd|@M3͛7IĵKpp0-[Ç#A8}4dH˒E^(6ntR: QVh<# _8 - 5!fv|b@b|L8\Wj?W?AyFTi`ע#b6iLjÈ7BA?p6I[H, 0EFnD.N?=9m;E楲bL_#(I!_Νʼ۳!~@ @&EKvr+^r+G{!!8R6A\d(R *fAX6mn:̛7͚5˗]6mU݄mCž}'C z\VٵkW̞=[3J۽{wCӱ}vM=ꓶ6U1'끩h]dGQyN 01H.CqWmY)vCYj11ޞufRAQr)g&9!vb%ʆ7^|8:95`"۾G@^oقk#p1E 2`4t _C/CԊZvjᚃ#23[& w___NZ$ҥ#}Jٲe6/_1[nܹs ` IϞ=:YfK.fPf1cud- %'CIV%i*viC  ^>ϟ^+*/m8yVǬ؋6 cUA Ѫ Ey $(Z͡#1ړS^_/= 64Gv#[n-'NL6 C ^45j迣Sٴi8RǏ#Ge۷* Mez`&:QBQq)Kի BbȔALOܷCrf12g].Y)BDPbGCա$ 01ܨ.̚(<`֬'LtŸ+/n8SXFb:8 Y:rS@/n=Vt ]#}0m;%cϞ=(gÇ 3~xtM~uiҤIzi(!B Y2 ;;sC32AN@w5L^yia& \k^r`cQ|}pH۾k`"I8xBfW * F{P<1Cy _?k'yn mԻӱcbܸqXp+vF/Sli׮ $ !eܹӧ!DKݛ7o8>~%[[iVY @v}E6 k1ES&~, ]A.s1!!x䯝@^RĘ01ܗes}~z+ء^MWb(2f'qdS) zmݱYxp j X)g !!8R!FHzD,pfE9Aŋgi+%,|{o_(Ԗ`oR GD߾}f=iA**#=ӣv5;/.NԩҬjaS[DXtAN9`cc`c|@FMيM"K, Cy7l؀aÆ!~ Z b,FƌLYw+T^/I$1IU FU2Z5p1zĕLS+ˡ9T6Xk"C FCܹSlOMTsQ bm["k啰e%C3l|`cf3 ݅>3A1`%غ#Wȑ#bƌD͛3<<<n(vMR썟5L///ٳ;wnLӧhڴ)Zn͛҇9m@+ bd2 bL(4T膤Ifwԅy12dH !nܸpppB__|˗#0rss +@ ,_-;D\qEoaV݅bފ0Γ.W 1gGd-w*11N?>< 01Ng19N 7ci 04xSAϋ1޾|?pv Pe:ujd̘yGeQZ@LΣe>?Et1o-̖^릈 btkf5Xx|CG10aBT^ 6 >~3gʕ+EѢEѹsgnⳎ;b۶m D͚5Ѯ];H1uR Đ!CK7n`ƌx&MݻPBDΝ+>K*^Pi С87oĉ'{D x>A1`ђ@Lx7QT +"$$d ҕ(TjV+ FAH bdLOA tCl={[nQJtիܝ6m*VAiH|@bʕ8t̙#~)4]vŽ{ĦmڴA&MPvmKaR|oߎO> )S&Ҵh"|R@hB6mڄׯcH,E5 b, <1|X b қ0t|?| i], x5 Z3-ɊA[RαQZ{8:Ul M=0gFtZF΍Эd<~&fϟ>d텆bEx3rQZ$]2ѥ@L~HZJcpp>cʬaعqHIo@Sp&Mу;aJ&?z` bӏ6b#GD2e@yU\r HBPVZg*Y<( A[n  StibȻo߾;rM0BcŊ%ce«̙34iƎ%JիWx r̉#G(tԩS?c =D*WA5WAg_GՊA箣Nrشrhs 6Kz+;\\,UѺhdϚ_T8v2>{ S-uhe߽z|" =EW].1S"$$ŋ$qB<qĎ2y%5:b-vܾ/^È i!ĊelQ=N%*/pvvՓk&u2|%T@>~Q\6&L]n }^$ڵtG\8Sta>xpŧL LzB{=FJ2e0vԩ#BZ/_-ZDpFo7n,Xrex"w YL%Ml2CvPkF Э[7DFBe̘13vtRJ #yӐ yP O>"UVw sa,YRx,"/ F޽{EhڵkE^K( b, <U( 03ۊYۏȔ!5% lB?hLB?~}RtN0nzWhbRHwvk쐢qkxRT<>>"`>.,YDŋR%¿#Ɣg'-b1?K'N;4F#vsk ӵ]"ydɒEu C!{{{M qFt ɓ'I{Bי)Skψ#!Cx PQCK%/'46K( b, <1|X b 7SyHrc͆hv(cӚ:>B¿(?/bR5c%~`N$LSV}R-[|9Tr1@b͊'~Q٠v9jcAQ1SQ$GLۮcxT(=[fj,3w&t=8ʔ=Q]ѯGsMzp&bբQ:A̧GD-aÖ߳9&jҳBC! %ǤėRhRd &"C۶mqEN_~@oAAC=$QO Mci7ϋ[$9prb >~DE5> X"khDEtpqqBItiw#,vvvӅ X uͷoP~}Dׅ-[DzRxqOx8u<]2g,!o ypMP'Pb`)W :O?1n)I|X bn"GMrHܼUt 9qm'xe^@o)ۇHkR^#&2S\C?=bVo؃m1H R\ Dv'pCoɃA ڠBI?6mukLacz|#|#rk0V)l bfPNAaٴk DҺYM9[wqrdɘɳTFP7,; -w˶@lt|(skׂ@˷D*ACu1gJFs 1k[14}!:K_| I/K9bjT- )TX(.]Nm;v,9)JmIsi<DWYi9?e؁rP;sb;ҿK`%2z()rPBbi$k1%]UU&Z1RPH0~iD1r;hC%At]" 6\h'+y/ p( F'ejf jL21PF5_ѰN%Hޏ_`aV = C=y,+vmQT!N wi{\z_?8pď'ܩD_}}>ӗx&kƆ"a܅)`j#PFюKƉ3W?vv11/?zy7%mJLKWƭ1u|OXoO<A6om%Axyɚ1&Xa͛[zM@Eb[ڂȗ; O(xXyfL 5T=[6nU fș;gS1N Q1n[#׀S qJ>㜉8vz1{UoܸZԩr)1N> &`WU0"B ŋ?:^2bRAnQ ,^vmԛ_.](g2e _|5:3f o/ҥS%I!`p4=|L3af1}{ f*%03")T~lIԸy#%%)$n[URq_DW93әg1Y ,_gN #ӬA ܼ~Tl1NL?hS'NaVgOmہ!$Ą|J˕ꚯn1泩~}8vz1t4 i<@dÆ *wĈg $Pك%K{*?#3B:W9HǏ+zjOƎGaΜ9jI֭gW\Q1xȑyZ[ʕUPq:T6F̙M6Uۢx A Zއ}*1 Dl=bV.[Fo)!|g^gc;`~H.M1bX[k^8< &M /W(;sY5ljի#~#SFܾuƍku6ːGDNp_}j҅K>Rp*iu|=/A) FT@^R}- x6sr?pD qN?)b$@(Q"9rʥg#n?߿?-f͚UA!CoI&*̙3qYK~gl߾]F'8`V2ԩ1Ypϲet5jN/z%ܽ{#'Ԗ!mI&0tpCRLΙ1WmI-Flݚӂzu"}*f 7o1 A^iӦ|=:gVۜ_z)y_ iРܹ*m۶Mł8p ׯ7s=(8O<_¤$ _K#W-[/^mF<:]z! 5Ô|aFiÆK3jlt5? hs-2~$KLH(P@dϞ]L6-L O4'\>q {{|a@ u2=U߿(OF" aIܶD¿Qӧ `,C(A(C[x/=s@A~ܻ F%bԛ񢨺xsVH0.Z7>)\`gv~եG ]@LF^^.]^t%J7Zˌ7Tx" w|Qܲ\^$| c@Lݺu$b N&Ǝ֭)S?DǕ ĸrXO, FF.}m/ѿ'ʕ*GN(m~[u`Ɋ-ȓ +_'Ochְʓ4ciܼu_ɂgn>`:g3WbhkKM /ýEH&._k ĉN[~O>>8t Pllդ*^ u$8O۬hf2@Eߢx%Nmc1v;@) (T(m;"Y_EtPw̄y<i ȅ2`AN0ӳ6HWpѣCe޽ 0C;AO/&<^41^x,W7nwrkmWL` Dj%?v4Ao=cJ'pmb\nbJb'H$޾Ò# Klժӑ9SjkWRZeWXtP,z53A$8}IΗ,l|rWƍwhgJI ĴnV Fum?|D<'/Ea@ektVȚ4ƫW;Eq~7MG|ِ@-=~Nɺ,bY=q!Lo$I-T$C)uصa |IEYDrZaښDmDVٰa2d21VaGA |TmK6"PV"gG 䧗M^獀t[+ FsIuU]s;# smo Zk7Uک (e̜ -E/@̸ѶEuٮ=GM&/BԨ7o7S~_" F;SJM:U@ )"eÚ GFܧuOֵ ߷oBX`Le@L]4{8*+qV/]/\`kܹҥI% 7QP^붢Uv·ZuJǥc^Uܷ]; W1[i;wnw\$ iCaƅaMzp5AK Iod0N?=vXxV^]=GbTO5 ѓ5yxu bQh o@1[Q/TlYv:t-;V1l=݊΋)-2{Qb[?ƭ폖0iPWmc=)d3G DAgϞoDn')Gɓ'W{24 0rjkfw , 'a\Թsgu tГ&SPB*'=v#F ^S=( FO`hb3e5[m'b▥~~9|Wn☮je}*f` fQPg(TG cI0l)5S=G׶"fJOAL"p)ԭQ*}@DhQJ8.%m٪UpnJ*BZ[ Tci-AoQ0WOU"xOS8Qƀ::zshK=՛<~ظ{qf窄/^fH8.^n$ puS1R&QyA7xt̘Jfz ZD z(0$q|uR!~R= qaՊR^#׀c8N]Ůqedʘ9sAhUKce-? y!={ٲeS1yb$Q ݣt~R= qaՊR^#׀c8/7^d͖S3˭W&+ Ƴ_}c,n ]}ڰo%KpgR<ؾx^1N$UP&~u;.2 |8L_ ~HS@@봕P@@bI0S@@LIo_%뎡ma>cǢZjH&ME:ZĸV߰=0>ݘ=S݋"r%@W>իq{R__T{y{#A $(U b!}1.W*wB78;7vBIUӀ͘?F5vO'K1&pȕ_ U*UWe]p!Yd/^u֡sN#șbX pV-~^AFsoZeZwO.qC?3]eY14GwÉ#x;jޯ[a!Bzxhcv h|?4k/VMkKz_›ׯ+0eʣM.T+ 58cr+jAӰaCm0af͚ʕ+ZG?-ZuRP ѿaH us ϑzuǚǣ{U\z˼xZ>z֬S`'{vQn1:2vEޅBq\5=bN=;ݻwJw:Is726+ 'փeȐ!R$gӣGPֺc2Pb q꒐N(iK<`PKAnnTtz`""K,X܃B10n:y5l}͚0={tj&MBɒ%_8U֯bk-zf/Ѣ-:sg fޭШ؅ 83zNblsM1~BߍlA2jT.1a5 i dH >1b"s\h޶+.TEFێ A*~<}ʕsdH@ 1Bհ1]}sǘ2<{0 O\JP_F ][D@kS 0U"u)1`BT1陕>qu*dzgOqc0e?zvAMM7now,Cu4iPwU Xp!zIA}+ Fqwz1 _̝+?B…Ց ĉ!ĄZ:)0~co\7lܡw!m_wo Ȭ]vQ^2Dw(%yooOS;3!^򯝩BjKd88T?;w`ܹ7n xb(UbذaʓGY'IDv4q[ѣ1rϋ~7{xs>x7w޿ΐfFh)_ƌGRp2VƋxq򲧋n# ƭr1=[1߿ÿR1e,[WW~:\8̗Oĕ+Xl1nd ##]}cLɅ qV5_:^:d) B L0Bm:#FX&׍ 8 b>s窟WW>zzI2-W:hĉԩ/Ο%/J \=>G,st @miU[VluÅ)n\ŸjU-VL7PF@]eF1 PfRy¥L{x3f]YL:Cu ֮XT_sے} sem֭"FDSIh\xLPUW6w ?)[o,[q"'Ld  yƈ6mL"NܢĘ:LڶdbĈLv]2l&3[l>_oXUcC(N`P笀^.7YY#pӥ¥IH墀# qD-6N=bȜ8vHŐ&"Q'̓Wx!7ƽu|b޿|i-#W.V09S^B4[38s v]D歜n7w 8pXDuwϏgǏ[5w.umTߴI2)\Xy0>[𧠅6E kIF!$0x 5Y\覒ͱ ˕CC% x]$أF]Sy%CfE*}W[ܬU/A+ȇx63Rݍw6/{ҧW%i:a`_yܲT1^No%֦=zuޑ;7^߼2nRm@צOW?oPECV\E=^xgy1S~&n֭[QH0P ey?x5޽{o 3aO1LٵcpQ~4;c@-, Ơ (…W,ƅKZ( F +#!c9Y.*$P;lX7F j@^<]:OW.{wy4)T<_8Kr狗^Ƭ~:cr-lٲ9ɓ'+ml:|à$@%)}>пb wW)S%ȦK/D^QӔCyblj(k0z"H|.b'2{}R%̝[mfg¢+BW!"Rۮ& L 15=d,1SƏ@rUA ,y*gSAU|J%wetroN—e+NJF?"NBɜTtNjk?} {C:uuYf)YdOcx ˗U1c"iK&z(՘A+,Z}-9o΋I}IF^//^ĭ~u eĉU<GãmŽ.MgxU$o\ v|^K"Y+)uA_1ƷǎG_O?YF= V=VH+7UBv5fֈӢ,K R x܃n[CHҺ+*.[Ssx҆ >ٶ<9Ȼxq puTˁ)W_!UvHRFuL 3(y:b[#3% it Q?WZӗ|5QGC`ƼUعn- b[rQ36╭+ Z.Rd*\RqaW WĈ2}!ҾKpb(4|DǛ>}eʔq!4`!ut}$[~}YĨRѾ/oKEpW@Kc3r.^?WAv|?jժrMzgb{*ܻf)(9 x blLC*Rr|XfgMlR{@:EticǺ)H nHݕT@@%tH(ssxx,Zt)^JAb%O:C)nb<~/E}/B.f,I&Q] qҎ& ITCP nOQ9/w‡GEbMD/[)Is^'%{9{OvG]09skvǐm֭Nlc27;CDI"D1]zȱz{GŏmMj'`5 af1!*TĄJ6kף^xz^lZO?@QR!n|]26u>iH=A1`eQ&2f CQvxnj eG;"D1Ą(dFA.#ݝk!e=}d;D &Kh@mutRk+NɃ6mrSRZ 8:@cV@@k 1MmGS@{q#-4i{ m_.\+WyL׃z`kTC9gs41we=5XS`n[2;`!^@FCA@L(D),m'. #'LpSRZ h=@cV@@ycnkc%Fw],Ys1bC֬99sfDĉ8~8?ʕ++cԵkWʒT Z?wgD^?ŋy={6*UҥKuaÆ]:-O5Ho0u|/6VmCZo[3.Lz]2_Ae{JcFR q İ'2tz/|RS1ƴZ6N1^zt'\ǮqeIEԨQ1b>} ~˗/qA\t ٲeC1KQ]tCMѢES:XRLM4ofy lSԩqeGGFǎ϶mv2S"Ept0>LdEL -T޸L{P[gicL~?~η.1!VecNA~VZ'ubܣb4RhSC[+xR'=WP&f̘H<9ҦM/„ 3f@Æ ^.S?b̘cAm=lm={6ԩc~ʫe !}U {H[g"o@_2ͱmA!yϫn#e_c" >8IUpb\2ĸLZ]TS@.걝#G gΜc|7ϸ)}qFEʔ)q)D ½uV+V,@9n׫1<&Ys+GFʶĄZ,1Z+jO[-]X) &vCPfBZ?8'x%M7o޴ڳB bGf͚IQYbΜ9jm*S ֬)Erig=b(D8*|Rt\W*uL˃ ~'iÊyJ,Y S^nRy xW߾}1`L6 7Lc޼yػw.]6ZnY)SdlݻiC-@LE.L7Cͬh}b֤G`?X&w z>eeFl2Us„ WnݺY~}D $qTX1uX ߿߿Wjt@)zb<QAݻٳgw g-Zebb\i-;$<b^~m1b8%zD #G[n!VX!0kbl^1|)$SQhC Q")c_.1i'b߾}9sf*)ŀ ʹ DP z,ZƍWw<|PT4mT0ҨQ#TVMoU͋={ w}g]ftիxT%ժU -Z0mY13t8<ŋ+ k2eʤ7,<6h׮?-@CGG!^`AmM*oV$LkOI$ >efӪU+XBy]f>A8d?cǎիW[Eݸq:e:///B/Dooooݺu;w.޽:m 8߽{w`W3FXAPIdXG7biWӎ 8 4PǎO`⃍CUs5B~ԃ/>K,Q05A.)1z _Qz!֭‡;u8p }p1ߒ(]I6o ѦY4Eɭ7t 1cFU#[iy@+ b uFĹO۳ݚЬ0G 識fȐm۶ŋѱcGe-2l͘\uq5O}왚_ jܸqB 38;;;ɰoNĘӮ@ ŋdž 0h C>x!Ç*UJwF֤bL{+0<ŋ"˗oV+AmU:{ZeK+S(Q"C\tR i3Y޽i: ,i`ALX1V<='A ! и֦MH"v~a˖-j>Io/Ȝۉzг]z bƌ1 q:^[[<ŋ0+t[,WP`ƻ ,q5wӦM]ތI+s]U ^Q2Ŋ-+ ֣0MqT&s4fc0p9c2.fp1ܦya zDׯby/1 !]-S@T.3zp~wMB/… 1x͛=q_,:05o^m+=SK%^4b(b0b7\arQ6lN +T\M僒R2mYW0b g$C d*fLX̠3H⽐/iH=ʫ˖-p!,] СHۭ[]İ5:bŚڡ>zvj&1S>m(AIb b ԩSwGLp[Hrɓ'f̘<[x}b@+`'IDAT/ܒAkѣGj!7jmRKJgBp ӫzm?qҞϴaG) +|]| T1|(=|pxB=0'MW^0ђG+ 8QsrOurR+z8#q[<_n/^ߣGcR&m.!J5aߕoM[h(-wҞ#&Iرv R2 b׌ r&n0)q*yo%K5od,5k֨ӓtڴi*p/IܾDzX&1na˖-iĈj{hl5-E1r J{E İ?G~pXm]=z|oXIQ%a(bwgϞԩSٳ'/n̜99#|RZz4i̙3@-I-$u* F C)s/_ڵÖ-[W1?/x!*vZH_|=m •˃jժ Kٲk.zS6mN#ap©p,-[T=1׮]CdT>tRpoAΝx) V:Ec*p[7\>EŠ[X[%󺲷bU*|z1{?GU ]W%.~='ODXо}{|Wj={6we˖g?RJȒ% F榜WẂO3f [O#G*8WѫGK~Qأэ1| :T=n znO nkҴi0k, o9M4=ߒ֭[Y[ ■ Wnz?~\yʔ)Ș1#~,X@pEbgҥCՖ*>-ZݻcѣjժzZ) ƥEC)Ex1=_M@.';+ a37.Tw؁;ƍ+(sN,^oVseʔQ/T~2j Yf޼yy۫Wؾ}{6YFC(BE:K%Xb/s\$l Ĕ.]zՔW^;6v B-ZhѢjKplz>l(b01| CXBn)˲=)8^ზnExĄT +WW G %"E@ڵՃ nݺM8c#+\rEfHiŧS@G+ } bJ,8w2aqXY)X ^xf"E~ZAzЋٿ! jgnaد_ m/98c|.z;v mڴQ}Δ)S z9fn{%N͛7+o<Æ SЃs79-GQ٣FR ʜsI8/$ na9zp񍉞ќ7V\Y-I*+-TZp cByH1P ()7mڤe{RP S^r51KK(t9 ~K9cqxp ^xӧ-g|PsE@~ß 1\Ý! R5'Wj=r~ueJunQ@гbl& 9 bxh! Cƒ­\駟;wn9/nccnÓΞ=hwVԹ =y#1@;íBVDpdYF:un#[m۶*>ϸ0 x8!#{j|h^ilyX'xU>\m?k(1W cp|R'K+aT&(nZjre_@fŋ f |f8qbÆ+,r Е$"O0"t/4q]K eP\F§w #3|o[eՄ.+|Y|ٳ\!V%Z3ae%ڂ>@e>y Rг1i\~pJWZKD-K@s61!|a,>z0/=a?2sћƍj;9_$L\&yx%m6c6z57o[f x=RhlOMb\CӝE` E?z|Z/H0x1I=~8p.>1V!Lܔcu6i=t?R^#׀p%18&N1&(d( ܆}bJ3X/IdXG7cNvTbLkZ50b}D3) L|,bsGiz (ɰoNĘӮӚV@M+DcKD@s~(- *KfR@@ccn#k!1^dt dn2Z`ptb\( z>iBdH:P@@ ]_1keĜZ?8*>( #W# h=tm+ ث{|P@@.Nh2SIŢ( 6MѐIS"НbtgPp 1S@( g( 3(Oj/GU@@\R@@pg~p qR@DQ@Нbtg]wH+3b k:츀s]s_/2:Q@DP@@gYQj=Ԫ_R(` Cj ( (;$I]V:gXtq1涻N1^dt( ϰVz>UQV1r=J12Ý) aHQ@DQ@w ѝIt!瓺tΰ 1<bmwb}DQ@Q@0bb)( 8%( ;HDQI8)D* F( * ^$( E1FSV@@ÒIQ@DQ@w ѝIC(bP~_HDQ@D{cROXJ) + aɤ( (;$!Q@pR1N (EQ@ ѯmg(  W)' FQ@@Q,%DdR@DQ@Нbtg( 8'⢀(_63Q@DQ^ثD(OQ@U`|"f|( (Cb$(`6i1( IENDB`signal-estimator-0.0.9/doc/example_dut_loopback.drawio000066400000000000000000000353521452044147100231510ustar00rootroot00000000000000 signal-estimator-0.0.9/doc/example_dut_loopback.drawio.png000066400000000000000000001675531452044147100237450ustar00rootroot00000000000000PNG  IHDRH|sRGB]tEXtmxfile%3Cmxfile%20host%3D%22Electron%22%20modified%3D%222023-10-25T11%3A45%3A21.205Z%22%20agent%3D%22Mozilla%2F5.0%20(X11%3B%20Linux%20x86_64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20draw.io%2F22.0.2%20Chrome%2F114.0.5735.289%20Electron%2F25.8.4%20Safari%2F537.36%22%20etag%3D%22zo_np2t7ZqR1qbg-3wiS%22%20version%3D%2222.0.2%22%20type%3D%22device%22%3E%0A%20%20%3Cdiagram%20name%3D%22Page-1%22%20id%3D%22rW4sjYkNgKiI6jQHrd_K%22%3E%0A%20%20%20%20%3CmxGraphModel%20dx%3D%221242%22%20dy%3D%22865%22%20grid%3D%221%22%20gridSize%3D%2210%22%20guides%3D%221%22%20tooltips%3D%221%22%20connect%3D%221%22%20arrows%3D%221%22%20fold%3D%221%22%20page%3D%221%22%20pageScale%3D%221%22%20pageWidth%3D%22850%22%20pageHeight%3D%221100%22%20math%3D%220%22%20shadow%3D%220%22%3E%0A%20%20%20%20%20%20%3Croot%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%220%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%221%22%20parent%3D%220%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-1%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%2260%22%20y%3D%22220%22%20width%3D%22310%22%20height%3D%22230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-2%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23fff2cc%3BstrokeColor%3D%23d6b656%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22410%22%20y%3D%22270%22%20width%3D%22120%22%20height%3D%22130%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-3%22%20value%3D%22%22%20style%3D%22ellipse%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Baspect%3Dfixed%3BfillColor%3D%23f5f5f5%3BfontColor%3D%23333333%3BstrokeColor%3D%23666666%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22510%22%20y%3D%22280%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-4%22%20value%3D%22signal-estimator%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23F7FFF5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%2280%22%20y%3D%22305%22%20width%3D%22120%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-5%22%20value%3D%22output%26lt%3Bbr%26gt%3BALSA%20device%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22230%22%20y%3D%22240%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-6%22%20value%3D%22input%26lt%3Bbr%26gt%3BALSA%20device%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22230%22%20y%3D%22380%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-7%22%20value%3D%22%22%20style%3D%22ellipse%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Baspect%3Dfixed%3BfillColor%3D%23f5f5f5%3BfontColor%3D%23333333%3BstrokeColor%3D%23666666%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22510%22%20y%3D%22350%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-8%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3B%22%20parent%3D%221%22%20source%3D%22oq4RC59p99LL9JI8eV2d-4%22%20target%3D%22oq4RC59p99LL9JI8eV2d-5%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22200%22%20y%3D%22220%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22250%22%20y%3D%22170%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-9%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20parent%3D%221%22%20source%3D%22oq4RC59p99LL9JI8eV2d-5%22%20target%3D%22oq4RC59p99LL9JI8eV2d-3%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22160%22%20y%3D%22220%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22210%22%20y%3D%22170%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22390%22%20y%3D%22300%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FArray%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-10%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20parent%3D%221%22%20source%3D%22oq4RC59p99LL9JI8eV2d-7%22%20target%3D%22oq4RC59p99LL9JI8eV2d-6%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22160%22%20y%3D%22220%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22210%22%20y%3D%22170%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22390%22%20y%3D%22370%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FArray%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-11%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3B%22%20parent%3D%221%22%20source%3D%22oq4RC59p99LL9JI8eV2d-6%22%20target%3D%22oq4RC59p99LL9JI8eV2d-4%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22200%22%20y%3D%22220%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22250%22%20y%3D%22170%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-12%22%20value%3D%22PC%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%2270%22%20y%3D%22230%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-13%22%20value%3D%22sound%26lt%3Bbr%20style%3D%26quot%3Bfont-size%3A%2016px%3B%26quot%3B%26gt%3Bcard%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22440%22%20y%3D%22320%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-15%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik0zNjAtMTIwSDIwMHEtMzMgMC01Ni41LTIzLjVUMTIwLTIwMHYtMjgwcTAtNzUgMjguNS0xNDAuNXQ3Ny0xMTRxNDguNS00OC41IDExNC03N1Q0ODAtODQwcTc1IDAgMTQwLjUgMjguNXQxMTQgNzdxNDguNSA0OC41IDc3IDExNFQ4NDAtNDgwdjI4MHEwIDMzLTIzLjUgNTYuNVQ3NjAtMTIwSDYwMHYtMzIwaDE2MHYtNDBxMC0xMTctODEuNS0xOTguNVQ0ODAtNzYwcS0xMTcgMC0xOTguNSA4MS41VDIwMC00ODB2NDBoMTYwdjMyMFptLTgwLTI0MGgtODB2MTYwaDgwdi0xNjBabTQwMCAwdjE2MGg4MHYtMTYwaC04MFptLTQwMCAwaC04MCA4MFptNDAwIDBoODAtODBaIi8%2BPC9zdmc%2B%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22520%22%20y%3D%22290%22%20width%3D%2220%22%20height%3D%2220%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-16%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik00ODAtNDAwcS01MCAwLTg1LTM1dC0zNS04NXYtMjQwcTAtNTAgMzUtODV0ODUtMzVxNTAgMCA4NSAzNXQzNSA4NXYyNDBxMCA1MC0zNSA4NXQtODUgMzVabTAtMjQwWm0tNDAgNTIwdi0xMjNxLTEwNC0xNC0xNzItOTN0LTY4LTE4NGg4MHEwIDgzIDU4LjUgMTQxLjVUNDgwLTMyMHE4MyAwIDE0MS41LTU4LjVUNjgwLTUyMGg4MHEwIDEwNS02OCAxODR0LTE3MiA5M3YxMjNoLTgwWm00MC0zNjBxMTcgMCAyOC41LTExLjVUNTIwLTUyMHYtMjQwcTAtMTctMTEuNS0yOC41VDQ4MC04MDBxLTE3IDAtMjguNSAxMS41VDQ0MC03NjB2MjQwcTAgMTcgMTEuNSAyOC41VDQ4MC00ODBaIi8%2BPC9zdmc%2B%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22520%22%20y%3D%22360%22%20width%3D%2220%22%20height%3D%2220%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-18%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22790%22%20y%3D%22220%22%20width%3D%22310%22%20height%3D%22230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-19%22%20value%3D%22loopback%26lt%3Bbr%26gt%3Bsoftware%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22960%22%20y%3D%22300%22%20width%3D%22120%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-20%22%20value%3D%22output%26lt%3Bbr%26gt%3BALSA%20device%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22810%22%20y%3D%22380%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-21%22%20value%3D%22input%26lt%3Bbr%26gt%3BALSA%20device%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22810%22%20y%3D%22240%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-22%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BstrokeWidth%3D2%3BstrokeColor%3D%23CF0000%3B%22%20parent%3D%221%22%20source%3D%22oq4RC59p99LL9JI8eV2d-19%22%20target%3D%22oq4RC59p99LL9JI8eV2d-20%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22920%22%20y%3D%22220%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22970%22%20y%3D%22170%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-23%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BstrokeWidth%3D2%3BstrokeColor%3D%23CF0000%3B%22%20parent%3D%221%22%20source%3D%22oq4RC59p99LL9JI8eV2d-21%22%20target%3D%22oq4RC59p99LL9JI8eV2d-19%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22920%22%20y%3D%22220%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22970%22%20y%3D%22170%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-24%22%20value%3D%22%26lt%3Bp%20style%3D%26quot%3Bline-height%3A%2090%25%3B%26quot%3B%26gt%3BDUT%26lt%3Bbr%26gt%3B%26lt%3Bfont%20style%3D%26quot%3Bfont-size%3A%2011px%3B%20font-weight%3A%20normal%3B%26quot%3B%26gt%3B(Device%20Under%20Test%2C%26lt%3Bbr%26gt%3Be.g.%20another%20PC)%26lt%3B%2Ffont%26gt%3B%26lt%3B%2Fp%26gt%3B%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22960%22%20y%3D%22230%22%20width%3D%22120%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-33%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23fff2cc%3BstrokeColor%3D%23d6b656%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22630%22%20y%3D%22270%22%20width%3D%22120%22%20height%3D%22130%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-34%22%20value%3D%22%22%20style%3D%22ellipse%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Baspect%3Dfixed%3BfillColor%3D%23f5f5f5%3BfontColor%3D%23333333%3BstrokeColor%3D%23666666%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22610%22%20y%3D%22350%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-35%22%20value%3D%22%22%20style%3D%22ellipse%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Baspect%3Dfixed%3BfillColor%3D%23f5f5f5%3BfontColor%3D%23333333%3BstrokeColor%3D%23666666%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22610%22%20y%3D%22280%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-36%22%20value%3D%22sound%26lt%3Bbr%20style%3D%26quot%3Bfont-size%3A%2016px%3B%26quot%3B%26gt%3Bcard%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22660%22%20y%3D%22320%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-37%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik0zNjAtMTIwSDIwMHEtMzMgMC01Ni41LTIzLjVUMTIwLTIwMHYtMjgwcTAtNzUgMjguNS0xNDAuNXQ3Ny0xMTRxNDguNS00OC41IDExNC03N1Q0ODAtODQwcTc1IDAgMTQwLjUgMjguNXQxMTQgNzdxNDguNSA0OC41IDc3IDExNFQ4NDAtNDgwdjI4MHEwIDMzLTIzLjUgNTYuNVQ3NjAtMTIwSDYwMHYtMzIwaDE2MHYtNDBxMC0xMTctODEuNS0xOTguNVQ0ODAtNzYwcS0xMTcgMC0xOTguNSA4MS41VDIwMC00ODB2NDBoMTYwdjMyMFptLTgwLTI0MGgtODB2MTYwaDgwdi0xNjBabTQwMCAwdjE2MGg4MHYtMTYwaC04MFptLTQwMCAwaC04MCA4MFptNDAwIDBoODAtODBaIi8%2BPC9zdmc%2B%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22620%22%20y%3D%22360%22%20width%3D%2220%22%20height%3D%2220%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-38%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik00ODAtNDAwcS01MCAwLTg1LTM1dC0zNS04NXYtMjQwcTAtNTAgMzUtODV0ODUtMzVxNTAgMCA4NSAzNXQzNSA4NXYyNDBxMCA1MC0zNSA4NXQtODUgMzVabTAtMjQwWm0tNDAgNTIwdi0xMjNxLTEwNC0xNC0xNzItOTN0LTY4LTE4NGg4MHEwIDgzIDU4LjUgMTQxLjVUNDgwLTMyMHE4MyAwIDE0MS41LTU4LjVUNjgwLTUyMGg4MHEwIDEwNS02OCAxODR0LTE3MiA5M3YxMjNoLTgwWm00MC0zNjBxMTcgMCAyOC41LTExLjVUNTIwLTUyMHYtMjQwcTAtMTctMTEuNS0yOC41VDQ4MC04MDBxLTE3IDAtMjguNSAxMS41VDQ0MC03NjB2MjQwcTAgMTcgMTEuNSAyOC41VDQ4MC00ODBaIi8%2BPC9zdmc%2B%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22620%22%20y%3D%22290%22%20width%3D%2220%22%20height%3D%2220%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-39%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20parent%3D%221%22%20source%3D%22oq4RC59p99LL9JI8eV2d-35%22%20target%3D%22oq4RC59p99LL9JI8eV2d-21%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22400%22%20y%3D%22190%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22560%22%20y%3D%22204%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22770%22%20y%3D%22300%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FArray%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-40%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20parent%3D%221%22%20source%3D%22oq4RC59p99LL9JI8eV2d-20%22%20target%3D%22oq4RC59p99LL9JI8eV2d-34%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22410%22%20y%3D%22200%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22570%22%20y%3D%22214%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22770%22%20y%3D%22370%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FArray%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-41%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20parent%3D%221%22%20source%3D%22oq4RC59p99LL9JI8eV2d-34%22%20target%3D%22oq4RC59p99LL9JI8eV2d-7%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22420%22%20y%3D%22210%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22580%22%20y%3D%22224%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-42%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3BentryX%3D0%3BentryY%3D0.5%3BentryDx%3D0%3BentryDy%3D0%3BexitX%3D1%3BexitY%3D0.5%3BexitDx%3D0%3BexitDy%3D0%3B%22%20parent%3D%221%22%20source%3D%22oq4RC59p99LL9JI8eV2d-3%22%20target%3D%22oq4RC59p99LL9JI8eV2d-35%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22430%22%20y%3D%22220%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22590%22%20y%3D%22234%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22oq4RC59p99LL9JI8eV2d-44%22%20value%3D%22jack%26lt%3Bbr%26gt%3Bcables%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22550%22%20y%3D%22320%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%3C%2Froot%3E%0A%20%20%20%20%3C%2FmxGraphModel%3E%0A%20%20%3C%2Fdiagram%3E%0A%3C%2Fmxfile%3E%0AG6 IDATx^X] *aݭݭb݊݁X(~Ϲ~/*.Ã޹s039\n7V`TU6#+ >Lf{YVV =\Eۑ;+: J z /ό0G>!9z \*w0O`X(A!b3YV@g",wdX%)AIb[YVP [+` 0D0WY+A+"(Ql&+ C⎬+$"([l++ U!z}3cUy7+r"<=V`C8dX`Tܑ`C%ymeXV@ 0DPoyf*\=fTC; B`G+ t;`$o+ W-ό0W"yެ`rXVP (6`tV!RqGVP -`X*A噱Cs<ϛP T`+  Q!Bf 0DY* JR!Ŷ+^"׷<3V\``y*W!cXV@! 0DPLVY:KYV@I 0DPVV`ԫCg  ]af=G%?CɤXV`bb l*B.  ~k`Ġ^ n{`zA!cGeX̙: z۩ dN[(BN) ‰`< Byw s*uZ~c)\eױkpȜM2yEsʔ)fZݻ7h2DPbXV@Y "}~H}+ #c " Եgcs:CݎA2hW AKb"Z4>Fܐ!cffνCŹL/h2DK~ +`$"IX+JeҦ3DD5}T)]w醽(R4CYBGuboFp^iS|WJ,"(S)E!a~XV`U!z}4ԪWT^ Sb ֬AAvah@HW).C7/x-^xv+ (EJ<~Hފ Al $I/?-Y"wJ y>FSoA|݀кCO:K! yќ; upޣp/]^is%*A^f/ tמ{+ OV#K}?FhNv)|vѫ0t=PHлS l_+#؂z`]#|)"yer.[ ,U$Ӫ %6=y \1y1DP! E!+ JQ!R<%;ǬB( mz7;oJYhB]8.#"%IL%@-"ph-CC2]Y[/C'mh2DP³cXV@) 0DPaC[6LΠ61y>U!q5R_4"ڣV`XR!( >澬 0DU)gr"F5@&CgXVQ: ݄R1`` UyL(`̙3J.c n݊|!s1+6!6`XVNjРdɂ)SD'YW~(FbƬ_`b0Ю];͛WP蘴ߣaÆ}:.\ ֜]"qXh,YUV!}ɓ1uTL0»y䁧'ڶm&Mիw/"a„(_Μ8UKbUzoq2aݎH!횠f]'iTő1n"Gѥ%._8M nZuy~QQsFG2C(y" 5Mƽ{ H\rf͚Ç,j%ԪUKD)P } ưa8AaXV` S!!E"TR{ȑ#EU!=;5kUkǫ r ׶]ŔN8 ή4gJ`íb"?V޹v.upl3 i5 .-J/^DϞ=ѡC.TgƍzCwww( !Ëk"Hz`+ *& (}ٳ `.?JS+G8rELw@]>vm] Wϡl ,ZSq1>G`ɼib oPn;'H!yT>텅ǧag#nܸ "HfGx9^|+"Q¦ !sV'Io߾Hwmŋ'R3¥a%/T A!Ÿ вz\]&d0!&YCb߮-V!O_l_!7c <PDD"hH^zؽ{7V\yaȑ#+Dd"ի}?k(er(QƎ/_( H_ C#<,+ ^ 0D0 "R!=޻{ GL+D}*ڹő ָ<B%i0ׯ='obv2$=%[dɖK Z6νL*Xx6,`ycq2~]@4i3DH&q5:TJU.ĉm@) Vqbih\6<6ؾy&su+Y=}w'- ])!'O`ޝZ`z1vgVǗL%@,D"T1$$DBZ"!bk$BH:-~&A칐=W^LkoXgOEV޼r+$>;X[c]"tO?ϟՂ+N;uZȚ#7h[2Φ(O@Zaڴibu P(pH)f=L2Cɒ%1~x۷O ۷q}-[VD%X ƍO>~TsѣpEro !`XV"GaAH,9tWb,;}\H,'>o#gwwb)[x D|%R4R ޼~!<%-RRhE@t3Hc=Z%[N&kW,''ABh }7-軠Gqd.,_4 }G +rbvЪU+8 d6`XV  0DOJXXy#yή"A'-yV (Ϟk;tn^SZI&~'Ľ9AbAy8)`!ba!k"l+  0DOS D0Bzڦ1vo}RIǀڷTLR~nQJM-F^cD"h +?/~|L\V;6Ҧˀ肈/0;aaiic)ȝ(Hn`D_t)k~3p0sX[[ 1z|dpȢ7DSءH(wyH"5V/Sb~Pf}N,{3DXPx 0D0r!6+ HCeg'z.(_,0n۴3fBL:y&wF }"<V`X`DŽ> H}?Ͼstk9K7!Idn P{TXbҔ!)}CR\g/ģ6`XU*An5ڤ2Rj"_㒭[b„ 5jDh"(Z"M4 +qhѢhٲ%&L(BĚTc!-C/_^De˖Q d/fĉG;~z@J}d`Tw u 0DP6!ޒE~HڣCBC?ahx|ZUx tvyc1kzdpCGB0xTѷLtpmŝ0zSDA20mP|ׯ^ˆ s@B^=e>Μ8[7bőuxTi҉Ϻ;QS7T^WwMГ! D]!B~p5 4̙3Ԧ4DCFB4>:t(._ue )j+P]I&A5B @!_@)۶m Vz৺dG``Y2b$Bڴi젚 Ts\|(V,Y"j'ta^V V3r167CS{H]W~xǷCƳ4gMx}׾FK`5Ȝ5v1C"qb~alTE 8ϱeJG|_JQPcC(\4V- c(T/[\@z\;} f/G.Ӱ6@Gq5Y%i0ׯ =eN=eEB ~Dڷ'n`^(T$W.[7g4SN2DI&$ (t~aô%HPdɒ=]4|9(퀊;0|J(Q:t t?@Oia@PR,tQFL>'OQYJo4KФ2g!@~HҔEShT'"*1MD0xCMt{jh|SD!wo^/_<~ǢbZZZ7=Ql%YɼqשBxŋ'`̥(S fLet] IDAT5>رywhO~L-tvs:RTwoQ\>Yl@дgOcΓXdL=?D8w;$MᰵOXrMPw8zpMrNeLI "a~nCs?5?ԨKg!zC盒 .tiR-tAjuj4{HF) v+DXr!eEmӺDA|p'1AkD3"޹mcѫŠj͋('>ED#́"#"~p$\xG^(Z 'Hb?SN2DI&$" ƳA&G"W]ǣŠTqC| CZ,ġzt: q[(ێkv"uȑ Fx:> rʇTӊ n؋E0u*۵ fMu„"bD_LkW,0g֭X]1"DŠY@i ?F7PC'@|1pdIAH۫CssrAt$"Dvީ! 0D0D5l#E!r|tKn<½05޽wB6޼) ҏ(dJ5FWܻw>u]'޼;CdȚ9h\cxXQ!B;%% WKQmԩPG.>:A+tGͽ /P2U!L#YR_4"H \k;W6.R FB?߿Onݺ*lJ˩ϟՕH+Wرc߹s$J.íwQ o-s3P> CXwhD21G۽T]=QSUaaa:CƋ&8Ab 0DP E!SνظX**bV͒DR<$$NNN"Ba ܹs7nD1/"$CL 32 L&= H}?dyHV  P *  7FQ(|)߉w~kq6Y}`6M7mheD! z,ǀ2kR&N>a8_TD mx d4!sDpݾ;RO!]"`.C]Fw  RR~ vmƻ> ,.^FD(6lKCyY V-p Gv#QunѢE ]7Qm?*:Y@dϞdsr-6 +d>l;U=q?õQamVH;e`i RI͐}'M$J5 0DP+;Z. ?ĉ#~ӏ5 .,>|v n{=uIhXY!Qk 6"Qb }G#1i$J˗A?:u6ٳQhQ&6mڈT?b̙Xl VB1tjU1xCDxwzy3'`v?I=Ao֬)N gvz(a֬H׼ sa0ua``?1kc+ m<^JYa2( mdܭLL[ '?`&o_ZoY<85:\82_!)T2u9p霈:pIŨ}:mz;u˜%q޽,^+nLJ-m D:c+9t߆ B8dY&x'Cxe˖-8rH[XX/^!CǏG)t___ԬYSG(DYzD>} ؿ?:t` Hhȁ<&m;5gGc4o,_̛9?G}Q^ӥc`\?7,&+ m*‹;M,,^f7韗ZaR+x8P1>>B%J")umڵի1gj*͖,Y]e˖ Ө.Q~}}6W_G\t k^QJ I,^}Ƃ~ #,6!B؛7xn^7G]-BS֨!%GDtrH75,Z.Ҳ2T -[|euBX5i{2[X}f|m˂EacLUI /UZczQ>IR2k48 %}UVxn( &d +_hd4m' ƍnݺ4)S`РA"zA _^l&#Bߏ4 MdBVXLjhJQuGlBu+1W%CU"&@Ql?k5KRi5C)Ւ!Bq(~"Vu?yD;e<ۮ["f>*.n!18&{m\f~bsg4 CFӯn xU@Wъʕ*|~eek4KZ; H q0];mbdY4􂭭NbM:Uر*Ti'x0fCm2, syv|w"oG dYz=<<3\ӧOE)7n( :;;cر"{L.(ܨotQ+ X2> vL|~mz!^rq(~#as6- NFja,\8uc7Ԝ``ޏŹ{y3Ƌ60hJ "J *UIӢO3#vӤ6mހ/Z5ݻw"˗/Bkkk0aBdϞ[6xՋ "rHL4"61(lA"0:+ m/ xێ2a1D.:ْA2)y?)6Cw/Q0+ "D1iʃ6V p$"0x{ƉV s@ ݭW$"DOp@~QMEM/]³͛ww6 'N4(СCSWZ5"B&Mr{?Q G"-7:AS'IɒAygAߔ TE"P7u*лwo0DPoU5ϋ](fFUM'#kƘ(D0S"^\8vDnH.Hߚ8Y"J D#[D#7BLj"4jHW,X/J ;v֭[WMԫ!6FP54!jX(Y|iP6}"#2DPGj|xygFsӃk:"N{,ǃC['N LjȣcȲuf6Ե\ݎ˗b0-LJCNޯ(!b2e쏈w^ċ9r?p]FXh i qr?U霛``zSZ|%01NæҎ!(E $R[6Z~C~]Q}X@T 0D0#<6ƧGLܝݣ %l;!i\(VN tNϞ=+YAIf'G\t,$@ΝKV#iҤ(VAVS3,]ǎc/_nnnb M ?{4޽51oa"EVT |?aG;oK,,-m ]%`S@ sԬ]>_<_H[e{̐!RkL[ѢE48w\LΙs"OݖdƏ8qDk7k,R?] +[jժE@4Yt/NRծ-<Ν1~xռƺUj!Y'- $Tf1DCќʣh*2x(c '9Y9g>.^ ɬ'Oyjʕ!ۑ#GpQ \2J*ŋb*hnmΜ9(\>sK q:ln|"=lB`Gh&CͤS"\"D:x$V_"Ѡ7pumFl2-[3>:p@@ԸeKlȗ3llbC|1W!B5 3!8Zdp񳶡v]'dɒD[ZM`Ϟ=4-2j׮- εM%/ 0DC bG` gm  &C;D>xu.g&N2...Ȝ9m1Xnzi*2y\!sƔ& C>"X+!yrLi2DPMhJS[ȑdVܸq7oD-Lf\vrJ͛v -ug!e``lM;>C{%(A ^CW666nw0ydL0!-zxx˄ >.rb`  $QC0Ds4ieϓ!gj}ňI0|X7e>|Ic}:ʈ#.a(Al tQ(A݇CuWc7 mѱSh֬ҦM&fX~}.w;FTf'A^cCyDZ{"H'f  7u"ĺ!2w52޴J}eőD N;?ơoz pf3DPD+A. b$o, P0 g -3gN'NE׮] $NX6EZ4?֬G#$E> &6R 0DbhC ț\1אG0 aSx$u5@֬Yc|-[nnn#6쎉 bo+ $1Ӵ7 IDAT ,ߵj9@X ;s#k,(Z8&L[[[@K)r'44ϟǽ{MQٲe/7i 0s1g(JhѢ:/͂%!o QL}E')CY`FQ`3tN;Ex9*A^a~W! 9=\w/'{Il Ș1#eˆ}DSzu 0@P_pae˰o>̚5KD DH$ w[nڵ+5j$q)`͛0g. ϟ`,٣Mà/_s"M4Fn3DM'eD"Q\Z2"/0x/v?/C*eR4W#wFDَW"saGԨݡQNGm!v*sW1gJtrw¬ys<֭]]k">BY;? %'9 6SgԬZN}SWoF_m"&Q&!t摌!叇 J* թSG|zoذ75MQ{4^vMD%P+ @Q 4C/^<@Qk֬ 'N 0j(+WO</_>8p@),Yxsdz ݥW!+AM/v+G&e4nX뗍|fxРN| zKIaVM - #'W~ cSd͒7m mFn#UO`?yA7-(͛H^pS ,0pﱿ!o ӒG2_ŋŃ<=Skܸ1lllУGJ@ =@mȑ""V>:xx1c , 40mOi Vttt釋-q>|pC۷oPu4 tBP"]r8" fnC3?2}9Pؤ-xÓ#7]tiRsx媅/?cڹ5;h*ț;+^3DXr+t&8g)U7nG3, .FM0s⯐t'W/m9A?7k{xɓ'#0D[l[58CiS9B#}&" *^zHzdjٽ{6aVe@SB DD1PE"Pmf͚S+mVj p)L8Qˋ(}@wعsHgXj A^0s"3DQD嬅g_#{֌[,*+#qb0M^4ӣ#/Bq]4!}T]km BJ%?yi} Dws:~.;b$Rh&DQE(J#+!Ǐ?>)&H>ߤ=R"H'f "hj"NZD8rl٢MQ=􇄄Be@i Ȁ9s pzj͛kkkmMzu֡K.H6(HpL24i={C @ '`'dtML(%694rL!:yH/hMZuzXv'\u|>?s=-D%? "̟Ҏ:[ <;7NGbԡľE(]ך{B n@ҥfɒ;v)ظqϟ?'͛QfGJj9FLn&tng <* G@Z97E999jTVQ 87n\a@VC@ W4mT4Ѓ6mDK.{yy=^9r‹( $Μ9#(=R#}GT#j!JP!^}!NmbV\ڍ{?=; -YtyTQ;A\5ۋNj V!=VD"DW)%")ahއ!n@9_JP' iD߿/ޮAZ.79Bf|as yV@.A*OP/ոJ!R=""ș* CK7Fުv|%ڍ@:99 mΚ+A_Ǟ1o΍srn$g_CJn3 @@cCΘ5~>غCܬIG ) R* 3PkzC@*]˽ "&AZ=y4T!AU"(Mfo$CJQ>}k ]jܹ c̤0lǏU8-Vkؽi&*W(.Sq[w!cTT{MDH̞- 5 AObBϷ>`ܻ)y& PGѣA*56Xdr-;QJP eVg!T5|r|?m)xeT۽RB1L9I%Emѩ[GZ5-^ :\Gb^}{D"8f^$IW/8V.]6-2gɄ=*Mj8i=[ uH ;;tiG@8:;P0jx:z&4f`mPre= M.^|&NDžDxq鲥ѭwWQ{ ;o":֠#1DP'9?D,L!~z)7J;^!1g\4 0jTR{wvnۅQCGVݚ?;ɒ'i )R$GϾ=ôMX$g>غw3=|tzӶ;޿?5jWٲgE([IA_Ÿ)`` yP;$MT,%UT=A}r>hf b_:vP D8wkݤI>st~{Q5D7sfڗXB8qB# b߅X`i$Щ/^DNpn=<*^x8Y6ǏZPjEo,6}Z@[չ&:ˡc=I`mm-~E?JgXA4Q Y0~8)[Z6Z`ڂ5O÷oa"%6l GЫK}AQ 7 uȋЛ!񆱨CXwP ZzXnx!]-M:CujZ m6;V,SLŀҥ~G[è5z;1a69E 6|2ZPt ;H,HQgOaȚ=k5"x )ZbAsƎ/ Ϙ7no­D:npi.\OM] [x&N[vCȞ3;FMp] >ʔw͛ vPzTKL2Dӟo 0DcÔ Ɣژb LzSC;xO+ '@/h "IF<)Rɒ%TJY6l*U$o@=z4v%EkNt[nSxf}sٳc6b*9E(P@ S L8QD(hO  j 94*,ثod͖5DaqA!SFQpŒ"LVgФ%PDAtZ``;s9r5*| +D No)kS4ui"J`'ϐ:B`ޡ= B` pQL3 aa֮>~(j(t%ivXr3m4?{A^rtI8r9َP!BlrիbLjҥKhܸRbcDn7{N9ARȑ#"j簰@Ŋ1`Z /F|D 8Qvm{nn߾-Ƨg`1͛7M*9ׯ2e hC/5PT3gN9="W8q"pLw\Q\0s } P# 7u"ĺ{ McђoPW|o -,r @?Tg`ΝXr%*^GDvz/T&L%D #O8 脵k׊zJO !@ dNd"RmٲED! 8y:$y9U.!Cz Zͪ0zuYR[P.S U͉!}51!\OzBↈn(Ԓ޼ODPł)t0j(,_\uPzcCt#5w\1nԩE2uH=[ڃ!v =S@Æ Qre\vM7nr-C@#u&! -k=SjDPPZj%$nϞ=:$j1nnn⺦/^E+&1_z%l\C@ѲӧP@$fϑM.~R T^L!2\IXCM|qFV"ڰa^| ooo?^@ᤂT͚5Y@m-͛7o ($NX|Nyt#G<|P.YD1Tn ~y7 L;U?r*Ht͢=S(ՁSƟ !AT9mCIR>~=zTWܹ"t=$N#C Wxq` ,0 ׈{^9p#~ (_m=/ CTضtk!V%T߼s0d\9 __۷c,8wU]~C `PQZЫ(*E:H,TEEH1Wj 1@-{{>9{?{.g{y(3~#T}{>j|ngp3-pK::)5|Dcǎ(TDD}RJ*Xb"›oyPʵd B-_|2"Xni7~oZ<7&"uJ5gL*[JA4΁6ԯ];?C՗_'4j ᫾GŧKz>'0}BthP ,Y\sԙ Jy{.V aמ?p9j˚RoJ I/VgϞwp{6vލ…1$TQqVWn!bcWD׫Nhp2ϛkq/&PD`;퍤t)yjXFhKJ(R߸-gEzǁ*{`T4IDyIufA5("+ކ"!B(": &TW'/<[ŠGӶU{NWIDE_SYrGŧMVDe;lkC뽤D[y46%sփFk>Daϛk37Z<7XX7ܽuW"H"'&Qc&.̹+qY<;@4گr̡7ASu;!+c^4̚yGJQDl:ņMۑ3 ;:oF9BjW%uH:cq?rWo z\SP!-ZT*/}!22ǏGttKW#+PQc(SƸ9:?o/&PD`;퍤`)+c#{(,Y 埮lr ϕ+Wnܸ]v(WQlY]mr͛Ցre-[qvځr (1;]_)"KH?=("X;")d{#)"~ HYf'ʖ+ҥK^Ro/_F ^8r: GQس/_@Q3|F""@BL֎)`0HXW9Bp/)WFкukdzrt3gP^=  ˅ NSK!@ :<+co;GE_Ǡh iޟ y!8p+uQQQ4hڶmc}2 cƌ+uO>}|Q#04Ꜣ`.3`hn+Eי("h B".Xm1忠\*(CEg>|DVbvRt\r(^|T Z5|g6)As,Sz6{EÆ>QDO)E3Gw<5{ѥK7'LMhѢ>W9rҥLH4i}1B%@3# 1q燵Q~Pz <[VlPI03@"@X5FH&(\;U) =t5kгgO1s#F $$ģxh忊7_{uhD"F 9m;n5}ud86 g("xϖ)"2s"Bs<{/e6nroK.U[h3f ]tn'.\^xe˖u{ vܻw/oߎ-[c1:*UJmș3[x,΋% =;jO"L95 (`쐻ABr2]W!Hu}WK~nxװi÷y7o@LM܊`m4:gl#Z7eTx/"kN'$$`ҤI?>5j䶻{;na֎SLA \bʕɺc\ߖk3yYZn +Ґ ar(E"'$Бcf~!|{a@IPDtp;=gBNDp7s@ Oc%"<3{)؏?'Ovzب(_ t#6xDFFv8u *W_}>ro۶mXvn"o\&ѻ7&l4ب8OlmNCs!EmnD{&"x0G*eyXKăRe%_oI' C"'+:[CA"Kطo_WLyiPV-{cSӑmQ}aƍС#^p*nСh۶-2dpOX̙3D9/ OߴKac PDp[ڃ Ee;in[G."}|ODLHH@N.4:vq(":.;rn u\'kڭרQJ<lAA.u<.V~إx[Xx1N˜;w.{=i"Ҹrx\<>|<.W[VXfxm)":iDɉkGfb("8xF0:^F'`iHDG]FνP~c#IlH" fCpWO=^"믿>p᭳gqd6 o']~nF([JV񈊊BUJٲUzu5riFti_.]đqsql $܎/3#Ygg;7PDpX=r="dh0,c)_1PD0FLmE؜i;O)_݅¾=;ѱK/4k}#@|1CƭDmzzj6%"|8}H#10S->L9u¿lc{>yk!}({V׫g~ʞ'_Ex&6ґEihY0<O}ZtEG)1aƤQJHxsOe'D<:Saa汻6K.;(D@SU:}LL'K,jB֬YQxq.ԘCܹ- +x ]v@.֬f)ј,3f@' :~8G.(Sr(5od aUS<[R?=Da3ΜBLPdY['>ۣ1QOSx#BIQ+1:tni.7WŋquD3#oˉ$Ep7aӦM[F[߯2T@=M6U [/F;2qOիjpCC_0ZW3"BR?mG& b"DLZ7Gj/Shx-g֙7OwJ"+\ɉ'곀"妜ݹuȺHc+`H-ޭm چF"kZCKČIQ*3SWE,eΊ.\P/_M>],x<$[u ]L9]3<=B`0Oj"4lP Y={ved&tWN1QQ1aD11nQ?L5HHHHMDH]jq[a!u{M5a(QLHGтsμf=j"ܹ}-Ɲ7\*!E k y$MW)" nDQd,ΟŭqC)zyƌnr̜30q@B /Aăc7sS C#s>oR:A@Ąc9aL^$^:p~\sFŊsVp]jQm6D_ _}:f"&ȩUfB'ֻ=zsEYT lQ/r{!&ϒS("xw>nwVQ"꟒z},jNv|ܿg.U3C,:+©!7m?'ͻ?nޫ k(Uqw߲\O?2Ks<PDКg6l@z6 *(`ǎ%L6 jJ[yGf OG5/o7lؠ :s Clc+I 0:1r״PZ J8PGf AƯ:{ s7EIӋg̕={>G&n{<ŘZyBbBOs5GzI3(X~*Af >yJy^31jhO#d;0E(ώs73UQ O2=5wV5@ݮS|Nc֭ [K\R駟?_IWi*{cNaC ADHmTl{uQA4j̥ `Hwvm͐*@|KA.vE8LE@BM bBMe?u7U5"pW:"\.8^ %€PDpm.xC' hݺ7n=ϟ`)SƩVjo>0кukø5\?eJ0M40;wcyq(ܹLJ a mL26!p*nVNO5j!:M6O75$@AC{x韏B٧*}PE=s)!>l( 9|JbP3~ٲ#а9W{nT3QFzPH(;[=z-2@3ԩS8Xzt+o  +"kV9\-¿ A{e~4Eǽ_KBPįڹ>Yf/Cs=[ PD"l3c7>C˖-Q}3"""tRt7-C+pG}n D[VN4:5\n%V,ƍ7qqw.> F-r%C' ҿ鑡ݻ˙\pj06"PD*ԇ<4eQ˚>(&-+(."jm"@@("Xsxë_QD?ЪU+ol{tҾǁ_* j1&"$"Zck⑑Ș٪Tu9j5_lݸϝݤw&'@|hZ;9h2~6wyJE4A*zF9)::ƍѣ~oް{ի14*ef!ibϜ/Ԗ=eɪB#[Z;T𬧈`Z5 ]`Cu\FD;(2<ܭ*֞/z{} V߷o_ <'/^w2dW߾}0&ȑ!oߚsUD>!:|񽅃sPxw&'鰙PD0[i/E{ݔ^SD0e؜6_vḧ=y'"i!+wh* Fφ)8u6 ˾ލq wnxtИdG0}NϦ^>53@izI!Y(B{kxDB( _ICpr͜iDwPDpxEo&@mtCۈ=2,tY;,ESF^zdžU6(Q6K%K`Ȟ=[m+Wm RtRx|7Dvna0 zm#]]}#v$PDziФZ~a+~ʼn3Q/-V^pyF@Nm8qի]C@@&rH9`+w,I(qGQhT f B++i^~nܸ;w"22ʕCppz f6oެPq7 b(]6pu伡^h*1f"8fs""暽Z?4)"Ɵ'p)u?7^Gt5πW3gN,XŊCRܿ{:E"ǏOqr+qȎP0{ tjL626Ǝs!$qb+` hM:CI/5i:`k'{Y+ `[65 C4@Z $2=}CڱI"D5?o5_n!KI"9fK*"4hEQgyI2eʘHMz6ԤeNj(">oߎx'm}zuAi6#0[lAlSOFR k߿?^z%Z?4)"-ԤeNj1o*>+kO.3^y}I %87LC"BL˗cĉ8p ̙K.!44o*oiӦ83Ϡo߾x*UPfM%%tq`IDAT*TCƍ(Ϳ;PL7,e0Ec"⡵5F5Qk]v!}*C1{l̝;-B`` V\qa=z4N>ѣGZq<8LC "!)癿7o݋ 8irL}J"CṷdO+ӧO"C=3Y)_m}D^Y;V 5ju0tP#Y"Hf<@d/`ڵ /|J"ew4h3Y`& Q0F10:]L V jϛE$hѢj)"\U6fJ%KDZCr\G O IEN YʕK|0`/۷G۶mU\DP3aKJ5^l-hG`yb?ovvލ]Chݺ |a"_H+V,"e}D [("x41!!!ٳ'nݺ:uꨂezxg1bĨ,LE?rF5Sv`ʰ9m?ovJ fnpA]aaa1cf͚ .\2/SD"}6!>[F."B@@J۷oヒ͛]v8s*(GY%J;v>'郅 v Zk4`4AGO^""6#("lR$Z #^|Y}!Ee?H7DDLMDą.]LԴH?W("<2?ѣGȐ#GTfʔ ӦM͛7ɓJpf~h]D0[|h/ {*" &LP3d̘UVUeM7HM'Ci+'3?˗GΜ9 73~hRD0\i ؒYE|3]^ ("X="µkРAt&2dS"Bݕp } T BR5~pIyԯ4i7nP7oFBB5k֭[ƅ  }=KNTFEL]vaʔ)8q (92/^/QQQ\2zyO6J&E=1IH\%`F!Jj\:Cmz3k؛'@34!"YÇGxx8~HvA- =4g͚+_V-Zih|hB% o"„ Klxb8o>e3PdIL<K,Q?۶mKl?~5~Ѷm[ C2/_ӿ{O>hٲ%^u]M 8I"BZ ʹ^a@(" B"B޽+!AїmLҐC3..NeH&ٳg6Bt@G&BZ;X^GƧ~2Lɖț7obmjժqhժڷoD6m k֬JXHZAj,$_DcǎL2Jh, Cj97GV^A&E"qIH\!`F! CjrlM'2EG^ll=VZ5qKCjͤΝ;Ye<裪V3;Xp;uT.]Zm9 ""kN ]!SL˭[cȑ߯_?m BeH*"ܹsI?AD G1HG2f̈k: ~hRD5\HHIfYp=dhz ؅$@!MDl`z7l0?ޏ=r{Æ J pliH)/gV qI-ya߸qz Ok|G?ߘ1c3v؁?0q;Chh(Ƀ$KN߉8 Y"&.]A2 d|QJi vWfO>q@]M 8Il"CZ99Mٌ\"@%\lKz}8t)Woߎ=z$ni! 6O>={P^=u d#Hm+0vX83cГ'Om b:|vr_zbK#""B;L/_>%vH ^A2*Vs ]t5tIH|Dl"3LZ#ۙE;Gd)"H^UA% {9<4cbb 'XKhϢCjہ3'X^ed( [DXر1qDlݺj{lCrI;"[wIE9A[ډ M)=v S RAK&3& pDrv B"+֧|oPDD  "3Vo6^k'Z "Mf"X{; 0 f1z=d hPDZD-E .# `:E7 PD:r]%g~Z?4`J :Vi:Fw PDL0  [jФV؉HH@c4j^Y>ۺN"C&E3E u PDnlL6rL9`L* I0 ("h i8.#|uEיMf>m% `!=l$@s4("&TnC"[a`'   PDŇz=dq\tG(" PD0^Lh g("xƏI J"ACHHf(",tl@" LI("1HG"bBH<#@3~M$`P E$@6#@f$`ldHv$@Q$@$`<ZD$co `, 6 8%` E#v:}& `" PD{ Ef PDY. ؀E. PDc3 Eń xF"g؛H("404HlF"NwIEJIlFcK$@$`4""" =^IENDB`signal-estimator-0.0.9/doc/example_dut_streaming.drawio000066400000000000000000000413371452044147100233500ustar00rootroot00000000000000 signal-estimator-0.0.9/doc/example_dut_streaming.drawio.png000066400000000000000000002226411452044147100241320ustar00rootroot00000000000000PNG  IHDR=sRGBjrtEXtmxfile%3Cmxfile%20host%3D%22Electron%22%20modified%3D%222023-10-25T11%3A45%3A48.488Z%22%20agent%3D%22Mozilla%2F5.0%20(X11%3B%20Linux%20x86_64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20draw.io%2F22.0.2%20Chrome%2F114.0.5735.289%20Electron%2F25.8.4%20Safari%2F537.36%22%20etag%3D%22gycJwfWftGrsoHy8WXtf%22%20version%3D%2222.0.2%22%20type%3D%22device%22%3E%0A%20%20%3Cdiagram%20name%3D%22Page-1%22%20id%3D%22qViSiRIcD_-ddjsiygZ2%22%3E%0A%20%20%20%20%3CmxGraphModel%20dx%3D%221242%22%20dy%3D%22865%22%20grid%3D%221%22%20gridSize%3D%2210%22%20guides%3D%221%22%20tooltips%3D%221%22%20connect%3D%221%22%20arrows%3D%221%22%20fold%3D%221%22%20page%3D%221%22%20pageScale%3D%221%22%20pageWidth%3D%22850%22%20pageHeight%3D%221100%22%20math%3D%220%22%20shadow%3D%220%22%3E%0A%20%20%20%20%20%20%3Croot%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%220%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%221%22%20parent%3D%220%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-43%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23fff2cc%3BstrokeColor%3D%23d6b656%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22650%22%20y%3D%22390%22%20width%3D%22120%22%20height%3D%2270%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-1%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%2260%22%20y%3D%22220%22%20width%3D%22310%22%20height%3D%22230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-2%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23fff2cc%3BstrokeColor%3D%23d6b656%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22410%22%20y%3D%22270%22%20width%3D%22120%22%20height%3D%22130%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-3%22%20value%3D%22%22%20style%3D%22ellipse%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Baspect%3Dfixed%3BfillColor%3D%23f5f5f5%3BfontColor%3D%23333333%3BstrokeColor%3D%23666666%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22510%22%20y%3D%22280%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-4%22%20value%3D%22signal-estimator%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontStyle%3D1%3BfillColor%3D%23F7FFF5%3BstrokeColor%3D%239673a6%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%2280%22%20y%3D%22305%22%20width%3D%22120%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-5%22%20value%3D%22output%26lt%3Bbr%26gt%3BALSA%20device%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22230%22%20y%3D%22240%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-6%22%20value%3D%22input%26lt%3Bbr%26gt%3BALSA%20device%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22230%22%20y%3D%22380%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-7%22%20value%3D%22%22%20style%3D%22ellipse%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Baspect%3Dfixed%3BfillColor%3D%23f5f5f5%3BfontColor%3D%23333333%3BstrokeColor%3D%23666666%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22510%22%20y%3D%22350%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-8%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3B%22%20parent%3D%221%22%20source%3D%224N66Dbb3Bsw2Mjw1kY2S-4%22%20target%3D%224N66Dbb3Bsw2Mjw1kY2S-5%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22200%22%20y%3D%22220%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22250%22%20y%3D%22170%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-9%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20parent%3D%221%22%20source%3D%224N66Dbb3Bsw2Mjw1kY2S-5%22%20target%3D%224N66Dbb3Bsw2Mjw1kY2S-3%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22160%22%20y%3D%22220%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22210%22%20y%3D%22170%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22390%22%20y%3D%22300%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FArray%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-10%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20parent%3D%221%22%20source%3D%224N66Dbb3Bsw2Mjw1kY2S-7%22%20target%3D%224N66Dbb3Bsw2Mjw1kY2S-6%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22160%22%20y%3D%22220%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22210%22%20y%3D%22170%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22390%22%20y%3D%22370%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FArray%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-11%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3B%22%20parent%3D%221%22%20source%3D%224N66Dbb3Bsw2Mjw1kY2S-6%22%20target%3D%224N66Dbb3Bsw2Mjw1kY2S-4%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22200%22%20y%3D%22220%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22250%22%20y%3D%22170%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-12%22%20value%3D%22PC%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%2270%22%20y%3D%22230%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-13%22%20value%3D%22sound%26lt%3Bbr%20style%3D%26quot%3Bfont-size%3A%2016px%3B%26quot%3B%26gt%3Bcard%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22440%22%20y%3D%22320%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-14%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik0zNjAtMTIwSDIwMHEtMzMgMC01Ni41LTIzLjVUMTIwLTIwMHYtMjgwcTAtNzUgMjguNS0xNDAuNXQ3Ny0xMTRxNDguNS00OC41IDExNC03N1Q0ODAtODQwcTc1IDAgMTQwLjUgMjguNXQxMTQgNzdxNDguNSA0OC41IDc3IDExNFQ4NDAtNDgwdjI4MHEwIDMzLTIzLjUgNTYuNVQ3NjAtMTIwSDYwMHYtMzIwaDE2MHYtNDBxMC0xMTctODEuNS0xOTguNVQ0ODAtNzYwcS0xMTcgMC0xOTguNSA4MS41VDIwMC00ODB2NDBoMTYwdjMyMFptLTgwLTI0MGgtODB2MTYwaDgwdi0xNjBabTQwMCAwdjE2MGg4MHYtMTYwaC04MFptLTQwMCAwaC04MCA4MFptNDAwIDBoODAtODBaIi8%2BPC9zdmc%2B%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22520%22%20y%3D%22290%22%20width%3D%2220%22%20height%3D%2220%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-15%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik00ODAtNDAwcS01MCAwLTg1LTM1dC0zNS04NXYtMjQwcTAtNTAgMzUtODV0ODUtMzVxNTAgMCA4NSAzNXQzNSA4NXYyNDBxMCA1MC0zNSA4NXQtODUgMzVabTAtMjQwWm0tNDAgNTIwdi0xMjNxLTEwNC0xNC0xNzItOTN0LTY4LTE4NGg4MHEwIDgzIDU4LjUgMTQxLjVUNDgwLTMyMHE4MyAwIDE0MS41LTU4LjVUNjgwLTUyMGg4MHEwIDEwNS02OCAxODR0LTE3MiA5M3YxMjNoLTgwWm00MC0zNjBxMTcgMCAyOC41LTExLjVUNTIwLTUyMHYtMjQwcTAtMTctMTEuNS0yOC41VDQ4MC04MDBxLTE3IDAtMjguNSAxMS41VDQ0MC03NjB2MjQwcTAgMTcgMTEuNSAyOC41VDQ4MC00ODBaIi8%2BPC9zdmc%2B%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22520%22%20y%3D%22360%22%20width%3D%2220%22%20height%3D%2220%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-16%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22790%22%20y%3D%22200%22%20width%3D%22320%22%20height%3D%22110%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-19%22%20value%3D%22input%26lt%3Bbr%26gt%3BALSA%20device%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22810%22%20y%3D%22240%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-21%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BstrokeWidth%3D2%3BstrokeColor%3D%23CF0000%3B%22%20parent%3D%221%22%20source%3D%224N66Dbb3Bsw2Mjw1kY2S-19%22%20target%3D%224N66Dbb3Bsw2Mjw1kY2S-34%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22920%22%20y%3D%22220%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22960%22%20y%3D%22304%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-22%22%20value%3D%22DUT%20%26lt%3Bfont%20style%3D%26quot%3Bfont-size%3A%2011px%3B%20font-weight%3A%20normal%3B%26quot%3B%26gt%3B(Device%20Under%20Test)%26lt%3B%2Ffont%26gt%3B%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22890%22%20y%3D%22200%22%20width%3D%22140%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-23%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23fff2cc%3BstrokeColor%3D%23d6b656%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22650%22%20y%3D%22230%22%20width%3D%22120%22%20height%3D%2270%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-24%22%20value%3D%22%22%20style%3D%22ellipse%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Baspect%3Dfixed%3BfillColor%3D%23f5f5f5%3BfontColor%3D%23333333%3BstrokeColor%3D%23666666%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22630%22%20y%3D%22405%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-25%22%20value%3D%22%22%20style%3D%22ellipse%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Baspect%3Dfixed%3BfillColor%3D%23f5f5f5%3BfontColor%3D%23333333%3BstrokeColor%3D%23666666%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22630%22%20y%3D%22245%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-26%22%20value%3D%22sound%20card%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22670%22%20y%3D%22230%22%20width%3D%22100%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-27%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik0zNjAtMTIwSDIwMHEtMzMgMC01Ni41LTIzLjVUMTIwLTIwMHYtMjgwcTAtNzUgMjguNS0xNDAuNXQ3Ny0xMTRxNDguNS00OC41IDExNC03N1Q0ODAtODQwcTc1IDAgMTQwLjUgMjguNXQxMTQgNzdxNDguNSA0OC41IDc3IDExNFQ4NDAtNDgwdjI4MHEwIDMzLTIzLjUgNTYuNVQ3NjAtMTIwSDYwMHYtMzIwaDE2MHYtNDBxMC0xMTctODEuNS0xOTguNVQ0ODAtNzYwcS0xMTcgMC0xOTguNSA4MS41VDIwMC00ODB2NDBoMTYwdjMyMFptLTgwLTI0MGgtODB2MTYwaDgwdi0xNjBabTQwMCAwdjE2MGg4MHYtMTYwaC04MFptLTQwMCAwaC04MCA4MFptNDAwIDBoODAtODBaIi8%2BPC9zdmc%2B%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22640%22%20y%3D%22415%22%20width%3D%2220%22%20height%3D%2220%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-28%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik00ODAtNDAwcS01MCAwLTg1LTM1dC0zNS04NXYtMjQwcTAtNTAgMzUtODV0ODUtMzVxNTAgMCA4NSAzNXQzNSA4NXYyNDBxMCA1MC0zNSA4NXQtODUgMzVabTAtMjQwWm0tNDAgNTIwdi0xMjNxLTEwNC0xNC0xNzItOTN0LTY4LTE4NGg4MHEwIDgzIDU4LjUgMTQxLjVUNDgwLTMyMHE4MyAwIDE0MS41LTU4LjVUNjgwLTUyMGg4MHEwIDEwNS02OCAxODR0LTE3MiA5M3YxMjNoLTgwWm00MC0zNjBxMTcgMCAyOC41LTExLjVUNTIwLTUyMHYtMjQwcTAtMTctMTEuNS0yOC41VDQ4MC04MDBxLTE3IDAtMjguNSAxMS41VDQ0MC03NjB2MjQwcTAgMTcgMTEuNSAyOC41VDQ4MC00ODBaIi8%2BPC9zdmc%2B%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22640%22%20y%3D%22255%22%20width%3D%2220%22%20height%3D%2220%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-29%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20parent%3D%221%22%20source%3D%224N66Dbb3Bsw2Mjw1kY2S-25%22%20target%3D%224N66Dbb3Bsw2Mjw1kY2S-19%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22400%22%20y%3D%22190%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22560%22%20y%3D%22204%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-31%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20parent%3D%221%22%20source%3D%224N66Dbb3Bsw2Mjw1kY2S-24%22%20target%3D%224N66Dbb3Bsw2Mjw1kY2S-7%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22420%22%20y%3D%22210%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22580%22%20y%3D%22224%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-32%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3BentryX%3D0%3BentryY%3D0.5%3BentryDx%3D0%3BentryDy%3D0%3BexitX%3D1%3BexitY%3D0.5%3BexitDx%3D0%3BexitDy%3D0%3B%22%20parent%3D%221%22%20source%3D%224N66Dbb3Bsw2Mjw1kY2S-3%22%20target%3D%224N66Dbb3Bsw2Mjw1kY2S-25%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22430%22%20y%3D%22220%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22590%22%20y%3D%22234%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-33%22%20value%3D%22jack%26lt%3Bbr%26gt%3Bcables%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22560%22%20y%3D%22320%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-34%22%20value%3D%22network%26lt%3Bbr%26gt%3Bsender%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22970%22%20y%3D%22240%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-35%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22790%22%20y%3D%22360%22%20width%3D%22320%22%20height%3D%22110%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-36%22%20value%3D%22output%26lt%3Bbr%26gt%3BALSA%20device%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22810%22%20y%3D%22400%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-37%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BstrokeWidth%3D2%3BstrokeColor%3D%23CF0000%3B%22%20parent%3D%221%22%20source%3D%224N66Dbb3Bsw2Mjw1kY2S-39%22%20target%3D%224N66Dbb3Bsw2Mjw1kY2S-36%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%221050%22%20y%3D%22590%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22960%22%20y%3D%22464%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-39%22%20value%3D%22network%26lt%3Bbr%26gt%3Breceiver%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22970%22%20y%3D%22400%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-30%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20parent%3D%221%22%20source%3D%224N66Dbb3Bsw2Mjw1kY2S-36%22%20target%3D%224N66Dbb3Bsw2Mjw1kY2S-24%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22410%22%20y%3D%22200%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22570%22%20y%3D%22214%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-41%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BstrokeWidth%3D2%3BstrokeColor%3D%23CF0000%3B%22%20parent%3D%221%22%20source%3D%224N66Dbb3Bsw2Mjw1kY2S-34%22%20target%3D%224N66Dbb3Bsw2Mjw1kY2S-39%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22940%22%20y%3D%22275%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22980%22%20y%3D%22275%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-42%22%20value%3D%22Ethernet%26lt%3Bbr%26gt%3Bor%20Wi-Fi%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%221030%22%20y%3D%22320%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%224N66Dbb3Bsw2Mjw1kY2S-44%22%20value%3D%22sound%20card%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22670%22%20y%3D%22390%22%20width%3D%22100%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22BkgR6BQGC-zBh1XBr6Q7-1%22%20value%3D%22DUT%20%26lt%3Bfont%20style%3D%26quot%3Bfont-size%3A%2011px%3B%20font-weight%3A%20normal%3B%26quot%3B%26gt%3B(Device%20Under%20Test)%26lt%3B%2Ffont%26gt%3B%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22880%22%20y%3D%22360%22%20width%3D%22140%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%3C%2Froot%3E%0A%20%20%20%20%3C%2FmxGraphModel%3E%0A%20%20%3C%2Fdiagram%3E%0A%3C%2Fmxfile%3E%0A~0 IDATx^XoDl.T׎ 0, [@1VJ%vgw=s]\";q7{ETTT81&`L 0& )wǕ1& 4\l+`L 0& ùv2&$#0{i N 0&`L ?x60&`Xl0ב~3&`L :G 0& S,6t`,&`L 0'b! 0`!aܸ`L 0& " L (Lt`[L 0&`'bǀ-`L0Xl0 wn 0&`L `]dL F,6`L 0&`:"brL Ȟ "6 0&`LX ߑ{p6T/)SY>?Q y6ib)(Y":܍вۅ;ѱeܻs3ηp3[$b8`L 0& b]v{XZ&FHo+6%MĆ}уܗ/x=}nXXX6lC[$b8`L 0&`怪p#d˞QQQx$7Phql?tI iӥW9wtt= )S2>Xl1H0&`L 0ug: '&AaɣЭm_nP &nՈ `ăǦ3&`L ț jxz>^*6,9VVI.;LׯH2tps\G"cUhR3*W:(Y6݁jUk_/_5Ӫ%sj\O9k6qtJ8sݹu ɒ@d0 ۃT6j`!~F 0&`L $ ¦B .jPr1{0r`Ol{{wlā=[1g&׽֬+DC$C tEBaӾߒeQn#lYo^IE N`A\ `L 0&  mVKgѶc4Go /Zװ_b|M{W )%2u6KWw4s,|PTy1ZF;k"zOGcx?Wy߿ǐ1S-t|nH$ ,--=efm7+7qEӤe{\p+ ͇D'CEq⡕T<7iɳ%Xlɢ,bέpm然zZ6 ރGAK*I#ɭ/*U,wEm/9h2w|ܣ2Ϥ'#Q (#n < :rb}ƋIPGl*K Ο¡}cmy6ؐ.CFtt#Ikd`d2&`L ;Vb]v{qAO"\yk/FE7/6JLCSM{ϊ#T(*&QŸbÛWA٩5u ٓ@q 7ODTضq%]>W.`ω$g&Y<`Z(W̑3=h?=zDx<{vMk`(Vtb9 4^#(3[V-[=gOFvDYŇ9j86DF-E;סc#8:552˄{(#eL K`Nߪ L 0&tI]ծnUAQy*dˑ s -m^ W/wwdΒ k7@>CIS˽#ji(b0b`dɚ~!eb-vPPQ^=S56%(Pp}D(@䰾ݔ"zOS;},'O.<8&,FvY6_<'O=-)@bù0~x_dˆ+ '>z6Ƃbh81&Q j9YwyeINťbs%0`2aL -v f;7=w4 MqyxOon]iYl)^ 0C`P]&P%bχ#VVIе׀2z{ǒu{"A5,6`L$ `ʝbL n`&$"bD &Ey[0W,6s``&IV`L`tC3& $0& /,6k<&`\G <0I,6r`FG26 0 H 0y`A^0&̕ :o&Xl9I`$;0:,6ݐL HD@r5L ȋ  [Rw/1(Xwd\Xl %W`eL@=,6ljs1&9 :xi^Kg*6 0`A1&0,6$bL ~,6Șs`̣Ƕ3& ',6i4&$#bd("& biO L{|wL c-1&G,667̌ =,6rǚ[bL@Xl#ln L{Yl01&?,65 ؠG03,6`˽cL@Xlkn 0=`A)&`fXl0gǗ{ؠ?`z$basSL`bi/ 00PP&I%? Ko4i[/az,? M(X:tG[bL@XlLh  5}VUذ|ls2G㴋 ؐ.}FLe({ _"#|]}j ?RM`JFNF|8Lٓ8%! 䊘 ,6hp9J3/$C)ۊIIR_}R?Y f-EV_`@oܳ $B «PHVV}xO]L""3Ξ3'܁}7bl$hq.D~ 9}ʯl`FOy ?~@ĉc4Δ<x?dKHz?$5-RW}R?ى ⹓hߴ Ob 1g~8y1llSG #ך9rk&JYVōY5ņoc8_fղX8k(ҧ Gk)$O:6Sf#1fbT)SC L<)ǼE`V>ytiSckJI>| 0jB\z_ߟT%[9"5ˣYp2$Q~L{w؏[qwkV#{4ilpZȢ:7C2C*--;HtpnEĚ`mMTŵo:- Qq SW.^ `FxxMELб4M:Xth?[z˷"tNt=ViT >Gcb6~P|+~HjyIMT^I=d@<‰#'_A?准5JޝplH^SʹX =gwLP)6|묕$_qR˒=6cQq/$J7 OLq>zi^j u{pI@^=M{޽F|hX n5ˌ> B-DOc apJF&M_^-{ o>(%@@}DUOb*S b9D\Ὠ] L߿F/n#UXXl1Lhܺu gΜ[`A/^)S5lllOXX''\v֭[>}z-Z & xݼhV̬nxѱ:jilyLnYQeӳAq3k1v+ ȫÿ"@E\bkMԡ@(fBfaG_?Ʈ(w`ԩY^NE(BIw}'Pށ}\а^e|:y&b?P"Ol [bLp̆xg00CRwRW}R??~@ 0g ۋtKyS×Q1F2IRbqcACF1YXz5^|  W.owDiЮi9 a"KHYOpn.[O[{ޕ-'Ov|ߝG{bp OJ6{5%Dl)OlZ9 -AMđjGS[K̙%vlbp_AyD# 3bp8U}2gJlPuZ`ALV{)<HnޏKMT^I=Bl!8yܻPsH6CCD$JGOE}5Zlxq*b솙 b#1cƠCȗ/=xWĨMac;Ƃ&W)>6.k<~!o6$JmW O^ /E]πnpw' L˛Q0.@acCQTy;|вi-l\11Ʈw ٴa5|!]Z[8N$#m^DUGH'<~$"M8)(Xw&g^w7I64Hԝ'5Qy'3!=,;wo`k@'7OT'%-L =gwL@[ϟ?ٳ%b2*ctlYh g@< 聹f29+rX=y+SZN?'rd -ʕ.%s|xvH{ԶУKs!|PJkXJøpC$KUJbwq'%:0rBzEޞ'!eb5MQl ofa]Hceqe'AtdAYE@v~\jOgPA^hM#}XXlnL40eϞ=ͅѢAIdb6! g̸tIgx?.5Qy'cA^A7ӞXXl09ýc % &N#F ߑnS jl:! ~Hj#y?.5Qy'cA^֘p%l|ѹIwF"E$ tb90/ :TG'b#H$LμQoYl`5js熏n_ƶ!a ;6R)F S[bֵkWqѵIt{ƍ1bTVMVV z>n  uXbț7l>oEۦ  7bnܹsB_gt3ԭUwluM4ыЦnʧEǣ+EG&'c>| ]vM\CF^ zBTl2X֭Clٰc̘13gԩS$]P! 0;wF˖-qm5jKưaÐ"E T\j%RM1|p4o\ݻwb쇝 dz%Cl۶ zm7f͜N%'g&D'bnf귻[l{QFax ֭=zdVo9C1x\;wD=z4%K&ӧOO& <==Q\9i&իWP #G[|iGG._cܹub?i$WWxٳSL:uhyk~ cz]ve7.ChQ#RŢ8qDܺu /h3M!GD t3(֪ō b&@6}NNNZ/Ȟ=VDsثVpa =SQUlP|RhQt+W<2 ϷOqѧOۅ8аaCtt{O?~mh"@uOS>JTMpb^_1#漃hC f͚gϞw\5b?b1 JJGh!DÇzgC(}z+N)CݺuyB&678x`g{ IDAT1 "u撷WB҆qӦM81M(QBe֬^%h JO&6gC5p!7N&=8bL$0{N<Г/S۶m'O"e˖ްaX<:^A{m֯_  $$C ssN!T>^zsd !ṫ/Y9 ۤ 6\~](hw/Q XD*bmn;t ԩS тņa5&`3dɒoRHdԩ8%6Vڄ7o3R=Up9`APclPQ|I2rHOebM!6( yx@b'N,~(}Ex_ OiӦ̴&q<.]*Hs\{Ǐ a֬Y(^Rl[}:VMǩ_9&8*l^ؠlP΅E*ڵkbd˗Ofg8_~ )VEz(S8 F&y=&=~OGFPl @We?^&6tJh y$ .BEZaiZ~(t".\?~lY Zaa/.bM6VVVZiM7@hN8!Q5lmlPm_g=ȓA{]ߙXl7qnO6Õb6P0GRDIŤZd8ɓ'b8J@Ab)$ Aߜ)( -R[߰|RG@1g2҂+W.ٌclbqc;BϣG &p*6P, MyQ(6m0f;v@7xEc9$ u;y3^A/.UgBdd؛SSN{GuM_}f0ydx@^ ty޽#!"fßb"@$:s1K,\T8lflS6 Z(8 )UT.YS:VA$@yI)scߒ@ " !/6~Y䣘I$XP) υ0At Qg~/]tEB?D:%j@εO쇴ech_Ca |k8E9οu NЪU+q%ս7tk'6ޜbFݖ!8 re'Fr\t9TТdI >kL@=$X[`A ĐKWb}vQw`۸.6ݴ<:);`!s\l}j|Sq>]M6]Yl0y`JkꃮōS5?&cNJomBk(q9 Bl zvD65SGb~@Dc)E}aa&O~i9aō\+צK{p0>c"E&7Z7j:kܗbPTrUlѢKG(6`iЖ@Դ~ί9w!COPhכ~χvX i<ֵfL,\M5qֺ5O~ڍ(_a8Zĵ;x58 2d6'f&6 ׀<nσbl Q׹3 < 79в.,6a ؠ=C9נō98#r .֫oEH4ʡS7iRc6,Y"=Dnnnؽ{RHH~lXឍR耀!b6ЍI uۮHY]FUJRk~!\c6$Im",x3I=f; }VpozʤIb׮]UVJ'3} /}GqN tU"UlC8HntWpBRLW$]bFe  ͛ J-\$2oZ *!!!∄z|=z߿N:XlRNXt(zwm\@7 !6n^WMEҤHtN&II7l^*I VNؗKo45b?b4cõ蘀>\)XxxwذaQZb… ^rׅkm֭ѳgOeqկK!((<@)bqcA#u3pϝW[hlp8w6+^'5mڴ(UT(3gΈ:*W,^[.,,'5} м0  ~!С0>EdHӡ;ҹe 1Cډ M" WC Y2Xu+A0nfH@%Jd@oZq9d@@>}BFЧO;vLx'ЕigE-'<wA4ir 8!a>rN؏ g۔zL8۶mA G),UPfMA'Oh#_/_WQ]HmذA, a֬YB ߿W~~~E@b1ݸqx2-T?-Z(ivF!N}:t(٨MbCA/2 G@-{g__e|y" "0'Wh5/It2e ,--ꔔb:tMꢕM\XZR}NùRFؐFxEE3u9yP`_ZiJ_K.hK"}8n\hQߦ/nݺիW*}yNХK-9}&l߾ %J.,6y6 ƻwC  Sq".ǏbaիWnjcsկ,:u*Ə/<  /dɢAZ*7omۊEZZ6 Tc6j$n-9{"[zizF՛74Kc6:YCvb@z6_cx?dZ! 6P<3 ?=ze@_)RA^5@bۗid0V$FHlPxK=Oq>F:%'mРA" =+"^t  PT`kk+DE͛hРȒ JH1ԯ]'w,ZI4$(QbgҒ$  ؀5 Yf^SbBPy*G!(p$IWX!b;K>bqcACƕA@S}ΜVgD ŻDVWC|ʕ.TK/XHo |fLsRȕ#MYlF@ tz?$ޏkk/ }pƍQzuXgK^ʹgھ}b뾜ڢtddxfȳ _XXl0dKb%O /W;v?WWfrrejۼyL_w>Z7,RIn'~ؐA0"RFbDUy/[b],n,6tk>C7xa @ZK| e^(~}v誅lIrD<,͛J J  iC,6.W/mP ez`dʹGA*(p~);8{N6mm$oؠ.Ϙ0kƌ;#FHHXZc/2W biL{|;/ǥ&*,6k|ٚ8fӃ#fݶAԗHe.ۦΰn VY? bi]:tNNőiӦ麛#?-^t<<"lVm[ 'F5a۴56ET,6|0D¶i棵9k,lR܆ e+֯"C؍ʪ3Ԯ-1d[WL.LrX2G{~HdHl0+d}/f,Y̥ېr`6x;NWz ȇi>VF"ɀ1̈,a˜M]SFOJ mz.Vœјu߿=@uٶ(Y$MgˣńH_(8Êҭpn>A֭[{(_P!+V SNP}Th͚5(_<-:ムu@^ f͊\z!g&ueQ߿*:YlX%LXlО> 3tL $#ϝ"Yk]zuX|}C۱ ?^>W4sfdm ٜL¯Ҕ?HMT8ej`;(A I&>}:2eʤ7ot]Q?ΝSeWW6m*n0M7c)btKؠ=CAG= Sqh6t=ie>j::wZj@T"/3σs qEJ'ڴC M~X-!SJJmvC.HO@ԭ[/^=ԩ2.^ٳg⵽{ɒ: IDATj|<Ǐ2d͛V?ْ%fȧOD&MR-go9 ݿ3b*WWQə&_Ӟ!,6rXlPTXlО! '`)nѩYW.#E_zLjLQw}g*ʹ+ ukX*MÊD/+:tStq:eΏ%KmX׮]~z,X...q[bzۃMҥK U޽x>>>|K!J?͛7"óŋ=8;1`lll̙31l0۷UTQѣG0qDxxxU2 "2IdA.www$ƀPa+L{r`˽c`A]RcA{\BCh}ll~Mr3'A٧w@?O9M>(ڣdY3FQǏDŽ h"d_Qq~TӧOA?CCB&icH0lGOOqԇԄyIld (Y}NùdqEL sfA{\C? 9SppV{>h+6|GnR%ld='cdi {F?|j٠T+IDP7_\ φG T`on HGXrML@XlО6 3b pUqĝ[ׅȠa1}RlЅ솭 䯘 I`߱ dvD!Mc6(DTDq 勋"f{`ƌ-fD 3T;u!<,a1}`A_΋ {qoH4 ;7"C>{!TT RC nBҥWo]n J:b`A{,6hϐk@RJE}i;~X %E.͐'$Iչ;_APTi:O  : a`A{:Lݤe\ Rطqb%q RfVƱ`VWg_l܇[}'!W g8r&n=G7J7N[G@|tbȐ!jC|}}訶ׅsF&B`FXlĆNio KD`'v [PQ,6ĆL*+2RSLevލ֭[G˧n;vVZA.g̛7O 0`A~c1uؠؠ=Cyؕ#Dh:b l ]bŊeqqRJPrheO:ӧOYXXz(WZSׯb6]32& /,6k<&.%{>ghv5gu;l4Xl0~wh׮llZjPHĆ0&4Ź\ؠHؠ=Cr0 F9l7zʼ=נrmp[=zCa `L XlH8;. Iؠ=Cr0 F9l7:kls}5->>>pvvF\ n @ 0#PJ8t:2آQΕ$3n]E,6nHؠ"nVD|Z޽{m۶Z0&`x=f ^3jp A`A#\@Xl0xi5 kkk(443fԩS67`L &b43i8M-,6PuGYl03;};ǎӻ-Æ AwdL 0& S,6H30,6Hljalڨ;bQ,*\[z[F֬Y&7`L Mif p4ZXl06ꎲ`'_ }SO::1e 8ٌ>`LiFi8M-,6PuGYl0ᓕa m۵G%Anܸ#GDT$+dL 0&4'bb*b4ͦf,6[/`4pjCнK3[ LAUѷ3E:ke$IbĿ?~艋`%#ztmp/X<9[wuB!6d˄w* 8cjV+ػe𺠴~A>F'(gêU0~xrȞ=8B75ӧͳŋXSR…`L 蓀bɓ1j(aԩx%Ξ=+>+Ϝ9̙3cǃׯ_>{gϞ *ڵkܹ3) ڡC4hOƫW0gԩSGi|&O5j`ƌfGӦM,67b9G[Xy(j omv~6ɓ'Eě<QLKG7vyĆÍe޼[gl"Hk_]v2/SL~iқ=4fJ(֓6KwAܹ&62غuD?~j-[WQ:FA <==cG#83`L 0=Vl I$ Hh(X +W.!(Q=z@npe4n?Q|y,]ZGGGlذA|ΒsN :ΝEQZ5xxxDC5by{,6,6$|c&~"$#Hl :hOݔFLp 5] ؠ93.,6hƜ-+?Au`5GA1^߆dɒb:f&Mf`>vQNqp\TR<9V8tSEIuņپk !q2fH74r՗ ΅N0AM:b !6@^^w]Pݻw5knt.`L 0c /aҤIB  K\ŸbC׮]E=$^س!3s.*Rܼ>+XƎ῿9"-[+CBw (s`Asnè ŕaă|ͪe0rPWip]QveKƨp(2AI$ر#TH - 1}{+D.u҅@2Lbr4mR8#E<`(8/k\}Xl50 T05!iҤLǏ'm(xÇѯI FA"j߾=y0&=uņ%M$Ӆ(Ob{L(H((Y~@34l 䅸rJqsT|l2QHU;9,X7g<+VK KPlM7#{hѺ9F=v!c(o94V|ETQ6nΜC(;}4Ԭ] ¶/!C ;uoS|`/޿{ `ڬȑySJkkaw^ݺ מT]{;TW_!@O/lްE^ϩ,^}bJe*wIXY%c}GL>7{>(=b,ْ  d6tgi[U,o9STϑhq`L M@O@6bi31|HlڱRDhҼ &OMlXr-utEmQa} <2g!biwB:!?H!Bx >b=FAԔ/Q?cݖX`1vnۅw>JW/תO8rh׫ <ڶ¾bCD{$@p=7oBfѺ]kthʔ¡p"!,ɒg̙NШn|M)%JG*uwO/,,\mӮ5X _"4$D)64iK|n7wN@1v7ݽJb5;r*h ];árEq%:̩G(Tc6(Ć `i9tيh_k ֙խP*r/_1 (OQa<aCZN›c{,YT ¥S zME!ڵkcӦMBp1ȱy)c-{ b$Dlݬzϔ9#DD Q!C!pQz=ݽUp㇏}hWb`tƩ/~ н{woΜ9j2G͚5QjU̚5K}g4mwޅ%J#AlxBT ~Ćk7(&NhߪJ(yPlpUw9Slp5~l hXdAԩS'tMڵ+6lؠ /s"r-K~0{lA(7LR{φÇcň!J,ǫdcǎU7Rb7iҤNtl3aB$@$@F0ElXjI'^ gϞE   eǎhӦ <==GT^k֬7gٳgJC!, F,v*r$].>>oUH&ZbusPl0ؚ[7?) 15xxx`޽eq\z5?^zJ,ȟ??z\;El/"6HȄ~:^|F!"9rD Ixz!SLwĉ c۶̦΁IHH@kƊ /'O"C oypqL2Cűc~oMHC4iPHL0už}]UMVziO'(6d!8P Plv;ir̜w?AҟFثĉ:{= Kt VCêDiJ⿗ؽi/Ӌxmƭ#z4h\Ue3q(]5iD]tQCbRn{H)ZBԩ b)P]Bgdr6g̙ѳgOUg˖-ʣa֭H<9F Zy4O$@$@0VlaaݺuؼyD,Hׯ|}`PT)%.ȏ}{+ބN!#=zgCĉX.]ZOמ-Hbk Pl0Q %*+;([ lTok7AYQh^̚o1kRlRMIsy>>3i-Z4%6 bkΚ: @A!IbCmaI՗QV0pf<ٳc+T0y;:>;tm!Č]U=-Wʼjذa8x@nƍ *AΈ;e5jzS""Ė޹sG AX͋!^䐒0k̘1XlˢErSfV$@$@$-cx H8iԩSCDL?H#/ɣ&1cF%XH%J ؠӚPlxvk & 7H"TD7e)<>T^ -Kz\:TlXx4W)۴+C C1n0B ΒC qr#$|B;6lP R$D`q@<@!os$&UIQ1BI )7R[[ ,ɲ5kVNIHHƊ bR+4H&*U*%_Xb| ۶mp4x(+@!1A RlpEs!Sln7o?J% }"~~pGG*憐,bÖ=a!-?+Wv9n-Կ{64o?mgvKIK$@$@$@F0El0ҤSV~^h6y ԥ! \;S5s9}#ݻH:YBD7n`8p `!  ? ڬm8: N=Q |/1ybŲڸ|||Ν;#EV뇆IHH#@8Naբ!> @b#x7l9VlfB͚5)8،8;"  PlfgPlІX4Kg~6b!6KRasHHؠ͎ؠ GBiڡ'J2`1kЉ&i;v9p$@$@$(6h4V(68R;D)68uWF\E qԯ_&G$@$@$! ؠ GBiڡ'Jnk_@6CǓ&MBZ>}z 0@ o̖$@v#kBޱg6ٲ6GbOٝY(6 Dڴifq}D)S4ۆ4}6owww1 } б^ Lw( j&g@)6p'DbIXN(6 w{}z2k_~EfͰrJվnݺ={6"Fh=id,X9r0 ؗg$`. v,gtu[yc߿[{|?~Hr2}Ndž Y G"Of?؋ФIt:u*-Zի֭[m IKb}w0sQl[φg=s:-ztl?t]-s!vbĜ(6hLv9\O#F`8u9ƲW^fkl޽1m4m! } Pl/N`.9 L{-+7j)"2d+Vl>slNBb,FӼx>v- AbC>}зo_F9sL!k֬ac `,%@RV`hQdN_p]CѪCO*ZQqSZiZ뷟E¤'O{p y+W6{llH$`?Ǟ=%(6XB[[l|X(^:UKҤ=e4_B=Pr G Plg jLA,YZb˗q1 HPlp5I@Pl|Pl[X:&ƍq\p]3=e .?Vz_-ؖvކ_uB)̞Ć`ժUׯccC `?,!@zRl!-hӨ*Nُ7_%:l۸ -;P,$` Z ]]BTKj$NUl!U|dd[nx).]ɓ'dk֬YfM5Jy$1*EB(ƍS> Pl"ܸv X u (Y e>=u 7cUh\,]>jkg~QS,Ir{72MzD&o_+A."8h Xb۫WpR7KEalٲ<==퍂 ǏN1TC̘11cF4nS%Oݻ<>6 ? _bkԈ)2^r?*E>[r"6n\UwտSN9MJ5ѭ0O=jJb8)6XΐL$ ÜpT-ۻ3 hMý{J\x|9|.] Rd$Q1Rjw+=^qٰo>TPA%o\|9.]<DtQV-lٲ;wn@`226 ]`,69y )RQ?ٓGȚ#<SĆ LȁAۯ+VlO=ZRl!-I`9=sV1? C`pLXᓗ^;@$bHZ\E1jTMi]VY 3HS$gCjհcTT sEn6ӡUVشiSajlC!@k`Ѣ~E 'Ql9B,_% 3 l۸sy9 ౙesE 4+ΟƠQD S Sh_b iAcrA.Q9xlƀԜ TB)Q0g!I kv%0<۸_޿h7wnZ'O=+PlКe.]FVm-3 O<ԩS3g΄Y^ FH,"@"|f5Kl[N8`)6l|k 6Dܾje A=A<>~^5l~Ca+oAŦQ2hں+fN>C!m׵%=}zPlHH"aȘH"Ua U+|gxOZԱҷ3\SBƟceʳwaҘAx \:3-g9^x{jo^R!ΆN- Oo$ ^KM{"^|^(Ql0҂}>’y- 6(6h+ &/)C|ѪCO_=C$ \'a/EH%i+ 'έTẖKA<DlH8 df``+Sl!-؁9k%t郟Z&S`az퐰ux]7k+bF첕Z.^WŔ.u˙b>f̴(_:ҥKgi;oG{|{зO! N]"֨Xe*"b K l) fjwbsԩU1 P^={OPw[ђ$1< ؈M`x*Hni.Z7V,[/&Ke*MbУCc,[Y{$K_"ry{ԪLu#Ih᳟JKH1ȯЪcO[}f$Ad.-' IDATD26 AqC#F 1bL.!%KcĈ^IBK)y6p \S wB*owB !1EF~丐F.Y #Ŭ=lL2٢`ڵk_8?U7Lռ9rΘ#mH x3 ^>!;bb#V.SG1d̷Z .҂Plh;uĆK x Q$l sD 6h z8q؜7Ə }?^kV' I+wGʆ 1Z4 LbwG`%JT4oם`Lу{/]9)"vKXR!ף`9CZ 6mnDlh9 ^=-~ls$%` 'zq0d0Ϩo߾2dHBǕq{ܸAĆQW}5Im^Dcg$@?]AIbFr`#lNkU ~|~HTT$x8PlBn>yUϢUXk3gD:u=~>m$.SFs?onwwlHH^&2聸rtH1Plpu(I{,,gH 6"@FbCX ;%UZDPQl o,7>0dZo2gll3I2+V`;QϜ׏! I+Wh'Wc}tJ@zww$qs3V"Іm8 ؚˉSl!-؈S7 a bCX{S ,]s BJU>}zSP֭[شiҦM4F$rw?tCSl0[؉ GAX/X$?ѿVǚ)6X.mۚ+cxN{g7j]]sgn]\1,]IA`Ah`a ]YjbCx]p8/G{6^'O1||UVE-p-4mjRGI|o߾*}ѢEQti%(HSF~PFWZnp;b- V [{fs$||H EԭZ)!z]`6T/-;"Mw{9O=z5byƒذ~z?9r@ƍpB\p/VD/ď#GTO>] yHb[v-ND$;ubV#Êja xln KTK9ܵ^=dϩN`qZ)68&J!SJ ? Pl0kڙ@xijdɒعs' ~KADt/_\r꨼'(6j f\ܦt)n]r|Xh20V4Fm-w7;"CϞoOSs]_ Z 퐀ȉW)6ώ-mL < ⅐3g`Ș15kF)"<ċO\@!H_Pv+z}J&xj5 !CLDס[4. }ct KwMj0Pl0[ژ *U;>}˫Ē*QD ϟFǏ׃cPl`"3+Fti*qpݷ ޱ2eBݑaCDͮӺs !5p FOX#Fo\)IB<#T;Z)6llHv%DC!VlQ;+v!nܸڵ+.^I(ٶm[ԩSM4ǏU'N`Ȝ93LSN6nnn[C9kTSRnSW&L;SK?j$Hױ#Ҵm( &(6~%|>dn'l/|zXc`Z? X!ڴ g7nΝ;(\r=Fwީp]v!jԨ9s&>|;J䓎VMlpxI_?}ƒ û7THb!Uf~} ?Fȑ\xlp!S!\W!YriMT_M(޽{JDh޼96lt{7='t愝?nؠI:rD10`!yd\l-6<}ĎG~J*m+V '_ wp ͫdΘF4r6*aq곏?!FտZ3A͆=znL QD-J/Y Qx>hm6n=ѣE*񘉋 Q 5.^GX1QpnӥfČyky!&nUq3'JSM30p,8}^=cj{n z咨׬oCyQpZi84eOkؠh(6IL7 δ8WxuJ&tFW5$ʩd Zlt39~Ā.gIZ4Z BNغJ+p ď"udF [`xk*7ƻwШ^E,9HWXb+ĉkx{*6lykuQ㵷8?%H(>\=Jx)&K6k`מ(g;DWNT ~~F8w:ڵc{-64n= mVŭs'x :J}οxgr_!9Ou<|,T!_8u :Ic.Q5Qۣsz3xnܺ)@=z4{zP5MJw ΊC;"Z֯SBaY=v vqZ?iMbDeOGA_8o=}Wqz&9<'Oj̴ikWjb%Y'$[$po n]"}ڟTׯp\OSPED|# dÉ 0d^3{F?dAX|R+T:R44}IreӦM'ׯ1uTM5.n O@N,IF5kqs2ސ 5/^ǏbŊH6 -*6m@ѠZ|NH45`'{ڸ|6Yo}HpjdH~[/\| :41g:8I'P0vb"6˫'V.UK) c*#$A1ThߪxP}U9WƨPp@TΈVv$)QgC`A~o`ӶEMLS\+6m;@Ȇ"=h(6ǝt@V޽{W\A߾}Q7L) fҥKQV-dʔ gϞŖ-[PNm6FhC¬#ܸqCNj2=k\(6i90@p$(Hf`Z~FFԵ["ŋb`jpczg^!Sjx#( qCu4G#ԪV+ ƭgo!U]G0A\;, SD]c1u xw4[B Tņ3AcUJ[ܹHKgwWAr+4 &CzE4g!LC&~Ȥ΍g$نn۷oQJt {Q C~;>KJhbCnݔ #GVmۆԩS#Β~5O %Y0x6^y(HL֮] 4@-i!B5K6mF`φ3g`>RL</_uAn‹)ww {ָQlJ& ؞@p$ȁ ݻõn]DŬA=x'OF=TNk=ƌFV"Y|䌒Q2G<0*z6G4ʞCFU^rcqPdA R(NJ5;o }P^=4lЪ;7 V]2'.dtWWiڶ5 Z%?CVl6Y3f|,0x(<"Yd#/5j~h֬ /ČS s6HXF`"nܽ{ٳgWxu<$ׄ_~g6ōbVvIK&i8"m8q|F'l]d1 Pl'-ǵ3O@Gxig־B̴Xb =}TI$Qodvƌ*0 4i 5j'o=zS "Hވbӧ1."nZ%Jرê;7 V]2']xg:k65ѣ#eÆ*C \ok˚!R1 c5?G+N8,K)Z$~dƶ~~gqcǡU=-ZHc`~„ Z jvT45k_$Atɗ짟~Rh`Il[%^|C\`{n}C;oر NB׮](Vĉc} üyrJ$M4 b_0-<d V^2^ 憒"E 4=k\(6XuhtE=/#"iг'[X O#ad*ׯ_Ǖ QRCxbWyeXR޼y?SY[ǵoXk!#}; 䆵= C={Apݻw!nܸVZ) ձirA yƍcJ2 ?"HF ayffN*€Uqܾ}[qqqc:{6$O\"SBrBH{i'!$qN'E޼y`uSޡCs6Zq%bY sܛ=߼Q_:6'K]3c`N8*F4mؠZ*W Rh׮bǎ^ŲeԽeĉ*SHI0T{9ҥKce˧N PQyiRti%(H*^j(rԺukm&gE+Zi=Tkߏ3[n="9xΝ[ݛ'ǏΝ;+`$ Z{vy8d%RIȝ4d]r%cǎj5JM cƌQlٲLתmlrѸyqʕ+cxcAă (/yӒpȃ$bV^G˖-U1 $DBxBvQf(a uH=, !Y`Aꉐ"z^ 9M2wK.2q= abIDATkm p<;?V*QM wjxoYv GGAEo߾z!r}o&6á'R$<$JN .Ӵ.<$A^Ky8{"HދCZךpD|D\H]\f&ײ$sN&!"8#-LN=6o =kXAEp^GczQl*sLōKk\(6h>DJ@B*.[#GiÆչYSsU^޸p+²e(;r\lg,*o孱0ȃ|vڥB>ClӴܔ$ //Yʕ+  /e9I-/Fa=ޏ<܋ ^<[3 /$tXNX=!/5y'>Kx- McyA'GK P!| A 8TYƊ5#׿#(Y!Z=^ܬ6Y'4l'H2 @@ބɓ9r0ѳgC rb\BΟ9 KҌuLb hweJQ9J6[eSI[bKw"hA2ł ba'PdI9rd#Eų@~Xlrtf#KK>C^*kceOQb3gƔ)ST@i#_s?%z1Ihڬ^Vx? a%ITє)Sk"`ׂ1$_ ;"*GBh{i R^:tHk·f^0fb9Lźv%Nj]έqq6 Cf 0 ct%7"K 'ۏ<yq'pk"%2| 2FSў,!@Ary\X1. xSA98z/ |$Í7TR?Al ޽S$'$<`ʩ N:T/?ﴱJdǏ>bdCD`KRavt)OHi*'~YNfI mo%6^)}2Vq?N2,=^ܸTōbvCK$!FNdb4$ XTQ}mL7#ogf"oَލJi w^_3)jK:b\ICO킻~So,7`Ѧ.Dm:|ޏ;8/#;4/nPs6ָQlpHIdI1E˓7Te)LrB[-תKѯsÃ9~>/\_WT-G2~Zf/2>2T{x5x?xq?NA55+J`ub7 :Y\L@hŨHx߾}uVjL"29Rm[(qc`X7\9 %P .92k$$X?6v.x-7Ρ?h6>rF[; ȚErپ% eL$Oָ>JņpA&dņg8;0J29cd1bʐ/ ĤȉCHI@٧O%TRf BB' ȓm_l h -)6jq xÄQlO\qq gG0ճ 6`lil٥ nO[S %{FczfgL~}fM [`F*'"f͡Ig)5)68>pSlnņg8;09 "LpMl^ha uSU{iKq{>VT(qzM38!%ďIel9c*܊gFLit!>pQ.XDoߢJ*ԩ٣$PBl֭s!rȪɶmTUwQX/ .TլYSyS<޿SСC ImРZh///H"\ڴi<4Ə̙gΜq}VR(u(R݃xgnÞ$bdD6ʶ(6ܺuKy4jH]ԿCZObܸq cVG,>y$M"cƌHcWWW fʔ)!uo ?~HٯbOoŘgʘ~b)XH!Plpe If!c̘1FIڴiz  RnHK.mԼЧOoL̨Rx>JhbWl߾]vZݻ8"4aܹXhJ*<ҧOd!²ocÛؒ0h&M_x0xE5f gb sz)RN%C`^ZӿACÆ MT&0a+|ٷCxM;wn<{,3Q=z1">%KLԑx(XlmLHF<PUxފ)ϘSl0 8 d0 X3 eX=zT=d')VhѢA8p@ݨJ%JoK珠_%nÊ'@ի?C@8p`@(Ehbϟ'x6}xN!!(QD;=aOYl5)!ߨQZjEHRTWիAoB_ҤIkzQlJs\$@`>6&pI@(ʗ/ۻHнMy{G q1b㧟~Rt$^DC(EHb<\ ErȃݻzX ?yll7]v Z*'N%<4dy(7oV\ISAn\q.\XyAx%$$p")BϯbJ=K}{= O!C]?D9!E/ٓnsm$![(Q"Z8GH+~e߈ &LhfOGA! =ؠXH@FR8͓˄Pj^MCaٳ'._CF'N{"6čժU V>7ϣbŊJ$1IR>c>x@}? $ៈ0 yۼyʧ ca@be}6...=CE`φɓ+QDrJHNi/$7$ y0l,Xr;5{ZQ nڷok$LJl-{BD: -HOXliԯ ZF# ;`'tN@ܸEWwk~U;kد3{6[^/ A<!tQ%rw9EذYGÞ)6hMT_ F(6hfH `p!\xQy9ɓ1cƄ"~!8}<==3[:Ο2tBrc::,~Ӛ˞b֗!Ј@ 89+W@B"ݻ .ď|Fܸ%RH i!kNN+|LbCXGG{Zsؠ5Q}zQlr4$@ؠH!mp (6Ӆuii)6hMT_ F(6hfH(68d j(6hMT_ F(6hfH(68d j(6hMT_ F(6hfH(68d j(6hMT_bѐ t)nZ  0gC 6["6oZ?%6od hCb6jEb^q\$@$= $@$@$@$` &rp8d ]ؠeHHHJb^WFqQlІ#    0`9`U h2 . PlpP$@$@$@z%@A+͸(6hÑVHHb @b *\4H@(6rY8(   ؠוf\H+$@$@{HHHL @XXb.L$Kt, ^ Plh3. p =@$@$@$@&%|Rnf0a:+=" G!@QV$   p8n8` Pl$͐ (6pO 8+ κ7 Pl:bv@$St0 k Gby؊HHHH$@!LD@$N Pl i ؟G@$`Ý 8 NȜ" @(6pc PlX%= _"HHHHQ PlpԕI,%@RlO$@$@$@$@!HNs;R5IENDB`signal-estimator-0.0.9/doc/example_soundcard_air.drawio000066400000000000000000000255601452044147100233200ustar00rootroot00000000000000 signal-estimator-0.0.9/doc/example_soundcard_air.drawio.png000066400000000000000000001155301452044147100241000ustar00rootroot00000000000000PNG  IHDROAsRGBCytEXtmxfile%3Cmxfile%20host%3D%22Electron%22%20modified%3D%222023-09-19T11%3A27%3A56.453Z%22%20agent%3D%22Mozilla%2F5.0%20(X11%3B%20Linux%20x86_64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20draw.io%2F21.7.5%20Chrome%2F114.0.5735.289%20Electron%2F25.8.1%20Safari%2F537.36%22%20etag%3D%22FuZT7YZkc6CaTQjlXRmv%22%20version%3D%2221.7.5%22%20type%3D%22device%22%3E%0A%20%20%3Cdiagram%20name%3D%22Page-1%22%20id%3D%22dlh2HGEMS9u2Ikbi2MeV%22%3E%0A%20%20%20%20%3CmxGraphModel%20dx%3D%221035%22%20dy%3D%22721%22%20grid%3D%221%22%20gridSize%3D%2210%22%20guides%3D%221%22%20tooltips%3D%221%22%20connect%3D%221%22%20arrows%3D%221%22%20fold%3D%221%22%20page%3D%221%22%20pageScale%3D%221%22%20pageWidth%3D%22850%22%20pageHeight%3D%221100%22%20math%3D%220%22%20shadow%3D%220%22%3E%0A%20%20%20%20%20%20%3Croot%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%220%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%221%22%20parent%3D%220%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-1%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22100%22%20y%3D%22240%22%20width%3D%22310%22%20height%3D%22230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-2%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23fff2cc%3BstrokeColor%3D%23d6b656%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22450%22%20y%3D%22290%22%20width%3D%22120%22%20height%3D%22130%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-3%22%20value%3D%22%22%20style%3D%22ellipse%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Baspect%3Dfixed%3BfillColor%3D%23f5f5f5%3BfontColor%3D%23333333%3BstrokeColor%3D%23666666%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22550%22%20y%3D%22300%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-4%22%20value%3D%22signal-estimator%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23F7FFF5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22120%22%20y%3D%22325%22%20width%3D%22120%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-5%22%20value%3D%22output%26lt%3Bbr%26gt%3BALSA%20device%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22270%22%20y%3D%22260%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-6%22%20value%3D%22input%26lt%3Bbr%26gt%3BALSA%20device%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22270%22%20y%3D%22400%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-7%22%20value%3D%22%22%20style%3D%22ellipse%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Baspect%3Dfixed%3BfillColor%3D%23f5f5f5%3BfontColor%3D%23333333%3BstrokeColor%3D%23666666%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22550%22%20y%3D%22370%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-8%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22jdgYiCKV-6AsK4i46VtF-4%22%20target%3D%22jdgYiCKV-6AsK4i46VtF-5%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22240%22%20y%3D%22240%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22290%22%20y%3D%22190%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-9%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22jdgYiCKV-6AsK4i46VtF-5%22%20target%3D%22jdgYiCKV-6AsK4i46VtF-3%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22200%22%20y%3D%22240%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22250%22%20y%3D%22190%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22430%22%20y%3D%22320%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FArray%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-10%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22jdgYiCKV-6AsK4i46VtF-7%22%20target%3D%22jdgYiCKV-6AsK4i46VtF-6%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22200%22%20y%3D%22240%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22250%22%20y%3D%22190%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22430%22%20y%3D%22390%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FArray%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-11%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22jdgYiCKV-6AsK4i46VtF-6%22%20target%3D%22jdgYiCKV-6AsK4i46VtF-4%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22240%22%20y%3D%22240%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22290%22%20y%3D%22190%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-12%22%20value%3D%22PC%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22110%22%20y%3D%22250%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-13%22%20value%3D%22sound%26lt%3Bbr%20style%3D%26quot%3Bfont-size%3A%2016px%3B%26quot%3B%26gt%3Bcard%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22480%22%20y%3D%22340%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-15%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik0zNjAtMTIwSDIwMHEtMzMgMC01Ni41LTIzLjVUMTIwLTIwMHYtMjgwcTAtNzUgMjguNS0xNDAuNXQ3Ny0xMTRxNDguNS00OC41IDExNC03N1Q0ODAtODQwcTc1IDAgMTQwLjUgMjguNXQxMTQgNzdxNDguNSA0OC41IDc3IDExNFQ4NDAtNDgwdjI4MHEwIDMzLTIzLjUgNTYuNVQ3NjAtMTIwSDYwMHYtMzIwaDE2MHYtNDBxMC0xMTctODEuNS0xOTguNVQ0ODAtNzYwcS0xMTcgMC0xOTguNSA4MS41VDIwMC00ODB2NDBoMTYwdjMyMFptLTgwLTI0MGgtODB2MTYwaDgwdi0xNjBabTQwMCAwdjE2MGg4MHYtMTYwaC04MFptLTQwMCAwaC04MCA4MFptNDAwIDBoODAtODBaIi8%2BPC9zdmc%2B%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22560%22%20y%3D%22310%22%20width%3D%2220%22%20height%3D%2220%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-16%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik00ODAtNDAwcS01MCAwLTg1LTM1dC0zNS04NXYtMjQwcTAtNTAgMzUtODV0ODUtMzVxNTAgMCA4NSAzNXQzNSA4NXYyNDBxMCA1MC0zNSA4NXQtODUgMzVabTAtMjQwWm0tNDAgNTIwdi0xMjNxLTEwNC0xNC0xNzItOTN0LTY4LTE4NGg4MHEwIDgzIDU4LjUgMTQxLjVUNDgwLTMyMHE4MyAwIDE0MS41LTU4LjVUNjgwLTUyMGg4MHEwIDEwNS02OCAxODR0LTE3MiA5M3YxMjNoLTgwWm00MC0zNjBxMTcgMCAyOC41LTExLjVUNTIwLTUyMHYtMjQwcTAtMTctMTEuNS0yOC41VDQ4MC04MDBxLTE3IDAtMjguNSAxMS41VDQ0MC03NjB2MjQwcTAgMTcgMTEuNSAyOC41VDQ4MC00ODBaIi8%2BPC9zdmc%2B%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22560%22%20y%3D%22380%22%20width%3D%2220%22%20height%3D%2220%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-20%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik02ODAtODBIMjgwcS0zMyAwLTU2LjUtMjMuNVQyMDAtMTYwdi02NDBxMC0zMyAyMy41LTU2LjVUMjgwLTg4MGg0MDBxMzMgMCA1Ni41IDIzLjVUNzYwLTgwMHY2NDBxMCAzMy0yMy41IDU2LjVUNjgwLTgwWm0wLTgwdi02NDBIMjgwdjY0MGg0MDBaTTQ4MC02MDBxMzMgMCA1Ni41LTIzLjVUNTYwLTY4MHEwLTMzLTIzLjUtNTYuNVQ0ODAtNzYwcS0zMyAwLTU2LjUgMjMuNVQ0MDAtNjgwcTAgMzMgMjMuNSA1Ni41VDQ4MC02MDBabTAgNDAwcTY2IDAgMTEzLTQ3dDQ3LTExM3EwLTY2LTQ3LTExM3QtMTEzLTQ3cS02NiAwLTExMyA0N3QtNDcgMTEzcTAgNjYgNDcgMTEzdDExMyA0N1ptMC04MHEtMzMgMC01Ni41LTIzLjVUNDAwLTM2MHEwLTMzIDIzLjUtNTYuNVQ0ODAtNDQwcTMzIDAgNTYuNSAyMy41VDU2MC0zNjBxMCAzMy0yMy41IDU2LjVUNDgwLTI4MFpNMjgwLTgwMHY2NDAtNjQwWiIvPjwvc3ZnPg%3D%3D%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22640%22%20y%3D%22280%22%20width%3D%2250%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-22%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik00ODAtNDAwcS01MCAwLTg1LTM1dC0zNS04NXYtMjQwcTAtNTAgMzUtODV0ODUtMzVxNTAgMCA4NSAzNXQzNSA4NXYyNDBxMCA1MC0zNSA4NXQtODUgMzVabTAtMjQwWm0tNDAgNTIwdi0xMjNxLTEwNC0xNC0xNzItOTN0LTY4LTE4NGg4MHEwIDgzIDU4LjUgMTQxLjVUNDgwLTMyMHE4MyAwIDE0MS41LTU4LjVUNjgwLTUyMGg4MHEwIDEwNS02OCAxODR0LTE3MiA5M3YxMjNoLTgwWm00MC0zNjBxMTcgMCAyOC41LTExLjVUNTIwLTUyMHYtMjQwcTAtMTctMTEuNS0yOC41VDQ4MC04MDBxLTE3IDAtMjguNSAxMS41VDQ0MC03NjB2MjQwcTAgMTcgMTEuNSAyOC41VDQ4MC00ODBaIi8%2BPC9zdmc%2B%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22640%22%20y%3D%22380%22%20width%3D%2250%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-29%22%20value%3D%22%22%20style%3D%22endArrow%3Dnone%3Bhtml%3D1%3Brounded%3D0%3BstrokeWidth%3D2%3BstrokeColor%3D%23B20000%3B%22%20edge%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22645%22%20y%3D%22365%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22655%22%20y%3D%22345%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-30%22%20value%3D%22%22%20style%3D%22endArrow%3Dnone%3Bhtml%3D1%3Brounded%3D0%3BstrokeWidth%3D2%3BstrokeColor%3D%23B20000%3B%22%20edge%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22665%22%20y%3D%22365%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22665%22%20y%3D%22345%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-31%22%20value%3D%22%22%20style%3D%22endArrow%3Dnone%3Bhtml%3D1%3Brounded%3D0%3BstrokeWidth%3D2%3BstrokeColor%3D%23B20000%3B%22%20edge%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22685%22%20y%3D%22365%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22675%22%20y%3D%22345%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-32%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22jdgYiCKV-6AsK4i46VtF-3%22%20target%3D%22jdgYiCKV-6AsK4i46VtF-20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22420%22%20y%3D%22236%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22580%22%20y%3D%22250%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-33%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22jdgYiCKV-6AsK4i46VtF-22%22%20target%3D%22jdgYiCKV-6AsK4i46VtF-7%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22600%22%20y%3D%22329%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22630%22%20y%3D%22327%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%3C%2Froot%3E%0A%20%20%20%20%3C%2FmxGraphModel%3E%0A%20%20%3C%2Fdiagram%3E%0A%3C%2Fmxfile%3E%0As! IDATx^tI!h \pXp;www p n Aƃ{.Vw\WCڮ2sTrv$z6/g)y0&&0gIx2#`L ,`Lx:򂘀E`dQ0& OrPdL DGL XOVR^(,,<& Il 0<;`d32ȓYL (Iœt6`,`Lx:򂘀E`dQ0& OrPdL DGL XOVR^(,,<& Il 0<;`d32ȓYL (Iœt6`,`Lx:򂘀E`dQ0& OrPdL DGL XOVR^(,,<& Il 0<;`d320[ aBȕw[֑>~/KNH<%/6{lfǃ2&`XYŪbԅH6=BCCxd,5wdNR$fΜie,=`L@-,J<gUʂc1":uc89'vˆ~M Sljԓ'=;'9lʼn3'm?[.{^MqAY f.Zoxn߳xnꘀ(DN=;6C{+/:έkp&X^D,$Ri7O*uO ('M8\$SRQf=ԭRo^_]b)6&^6'~X /_G 5uc5NJ#OVxnꘀPx"ySqy ɐPQe\ׅfX|ri s*d[O6Q'۶yklYs }F?4~v*@L?K(!  C'u[67kS'dĉѣGYݭ"Ot_ݚ5kPR𸸸DSl5Vl6W+*9^|V.4g3ʣ6m$Ο?!CaҥôH)ơ+_!CyE񔷬=>5, (6cO4!SAB@QB9RuxW(RD/^2um:M)6^^^ʖNjȏ&5NQԍAZ~LS,"vAœqR=z4F倴s0lذ(?g x2(-4[j?"Nux}˗8yNZBIn:,ϟ_lѶ'mQ7j?~DR]w9A%EºҥKXr־iĚ&ɝD!ѷ~E=IQlX<\}Q5JW41[ '|O≶&L ǦIF.%ٺNcDMDœ@iOf*BœqXR2cxB'@ xR/W>xE@`B#ot@rNXa9\I ecv,E'IQl\f׽ԅ~1Ɂ"E#q$t@w QY <+1gB1XƎI ecv,E'IQl\kWUefGb9 {nQSΝ;n_=i5DQ`o*xR $' =ѦM[Q Mv=]V>nRݻcjTnܹH,Yny7&xn7m"keY:gISA[J P4۔wl?<<"q2ZljQ1G*UHr-╗#M͚Mle/q"%Us61bˑAœEAI,*W9/_}pNn͐hIcd0:~?>utdLnFB@} ~C/RU!1^lQ+رczTSb#6,b#ğ[O&|y{߂c͔a ϙGY<酋;D}@&މѣǘUp N*O'qB__i/]MEQ6*AeJ./_.Sܹ3`ݶ`t] s Cj#Imoo,ދϿ|`"ôF/͑ĭ qO"13b- V]tkM =1:W;;$+U껐jYJ^OL†.*V|p9Q&BQ_ChZ޼yI' xR c\ !ڷ[7"!!Q2""T1$M]O([NPWT 9\|G^8jә|%Pbv$L>%Ewe{FQbŊEi.j/UT0a_d`7o^stm;ɨ9p-gdxqƅ/}хE~,r>CVznD蹓@?Eb*pIjԃ]bG,>cTsuGshܸEՁE+}iT#ʕpȞ]~C oĿVt%sΓ$Wp'ԺΜ8:[8kZ6}<7Z v !q?A3$\s7vG&Bdd,ˇb߾}0`~KPwtV P w/Z[vq 7&ĉܣG#א!?Kmm8p l mCrʜ$O6Z)c!4$X$NX*ޅ̍"Cynύ8Iᓻ4M臔+Cۨ 0*^hޢA#RׯyšX&Mj=zhݺu" Z\>E"YsmL7/ͫP^]<OfEEޓ-:+) ˗H&MC<2d?t'*޿yStT$LP$qNѪ}7U'WŶ^幯v :퓾IdlIK^@x:b%+-T}bQN ӧOf~53ED HlA"ݻ(ŋ9r"s玲ӭ}hLac+]ǴF≘kStQ:`ڏHH=O>ᾪ!!̛=ѱ$O caW^3mPZx&$ qr wt9 CfBHol,l%|+Q;X :]ut ]A qyR^(?gb[>kDօ<Ϗ#ܿY$#8k[:)D7v0sfQ?ڴhb 1cǎ3*i0zh8daK#pEeqU&-;)n\Eq܏6e9=۸/oנ FͅmS7O'tdd ٻUDݸg]zʖ- *-0n8iFdm?ʕ+E&:JieO[hW.QqJ9IH_Fi:~ʔF鞉gf\ŋN۴ 2rtM&1+Qe:w…H!KwI;OP’ySzfz~eKiϧ㥗R{8dg.DTM/yԥ^ 'd7)!}`.](ﻂisG{=ҖƍEq֭[ǸUVHGV@bHF" hrቮ%̔ID'"J"7)_>xRݦd;VɔŶeQ]m6ԫWOHlcfKF?WENSdѱʔx/|I#_ظj TNغ~6#UȆkHI %<۸W:ID^zeWQ>|̙3dnښzR1oݺ'͛#0VMֈ$Ǐe6%eKF%e?~>}$$H9sƣ(Mً\eթRgji$DlX<٢YmWXE..K1eT M6Oj8ETVԁw!Rd;Fœl(mP(VM\n6|UxR;煫H(T={G9Oʕ+WWHϞ8q'O߳U;ؤ+Wr:u$g",LZȓfZ>,ϧJ.>{-[Rz(:6]>\Kb!Y4x̘1fn&_dbc,Aԗ'}q <{w]A gA BRam(Hœp4'kœ+z=f.Fhnʔ)0` 's8ڀ1Y<͖adWY0-[!wܲO7mڄ#F.,'%'qO$,=jծ S'JPIn"I]2lY<< Xw U5)VcB4?ܺsI7ЇqޅC JF!Q5rdkftFXԭomP| P%}߽Y2CՊÁ#1b f  RӜE41UC@0?ã~H*9^=*Sju%;f/)G~Sh :G;慂 [lضe;Oom>Eof)ϳx;'_z#',% 0R$F lY3h \smQ51r;ʖMۇNQDȞ5#vσ1tk!Y<};Eͧ]Ѧy-T I$Fq,lHdH_dB<>yQHa=%kTZ=7T3?ܽsEhf-3z)AI_bX<:!wAߨxg ."3gNŧOPH! 1)Snj̜2 FiPZ%,] 3MCѶ_ܽܺq J艣0aB\z'>zdM<6q:n^dɓGox;֯ހxȖ=+z4Ң oO6͑6]Zm!{׎8}4FnhaL?UQF H3}.8 L243&Į?>}AA=m.{YK-}">-_SfM2( lAy,g#DOœqo!CēcYxڸv#]' Q?j"*T}EO{wQPVu1g,HBlJ"s6ujíF}$M B:>O}ݶ0_-#00c'-qIlۻO?EbDX2)0mG[zE5ǔ)|ќݹ}kim}7ȓ޶3|vjqҤnQ'MNV {7ܯ<{ڏœ?%ؔbX<) K ' bHH׌'#(zty 1 $L(yھ MA5D4cO%Kı~z_x1G%K9OMgCq ; ǤSDw̙c}XNM4SDq(Դe4iXl#A2C(_U=Z5EdI O'Řm:FpPȑګ 'N,b2gٸeQ|ҳNdd_f~JXN<;r\Dj׫ի`"|zmBn'`$3'O/,+D|bZ'-u.O4M vm%jϙ+ϑœ]h `7/S?Ϙœ:|(,uA$5:$؆X<Ύ4O_Zg/܈E˷ M VArԂC1b"xz+wȔ! :U}2ke}^ =z.7gC{N QMd2k oJ&5#er')sb$#GK j I^/ =SbԩQQ4y~?ݠ,,A<=Aœ|/»wHsTծ(DQBu3W hiM rd1ZRؿmPX/C{U_|5Ѱ^e#wxœ|8KR"8)x3eztn"wUsSppH(ܩ,YI>WZaax0q">yB =ǏcHQR/o]"~9dzMcœxm'ZWI>vm!q]#3}z,ciX<لUHOp׾Oψ6jg8%qęPn7ق7w6}\iJW% x-bd ^VY<~CfbƼ]ڕi7tB8u`8m4ŃG,Jt>m0~D(͔hժ(XǏxWŦU]ָ¸€-<' pIM޲ݹx>mZ,]O}_ Erg4nX$MTj"IϨ]MlvKoV,3ΘœY xI&v9<Z [lGL2e˖Fc%ɴU?'ջ&&lE~hӦ-r%ڵk1rHMX 03BX<)ZͲxVZ׺Xp[2h8}͚5Ò%K@֭Cҥ*YCœz|e)3]`P!Ԯ];C\H-[gΜqy;N<)l,icn߼nYcEX2w2>{wԨƈr-'K:1{-_ͨmӭ[p9Kӧ̚5 zWj'ORIq( _' c'Du2̝.S4iՑ1`dRܪlhҬQw)%|}}yf 6L\@̙Al4-eʔ7nؾ\oj?˖-=z$WuvlLqÅ3qHy,DޝCD1SS 9-8!mЬR׬)o6A޲m)o19O5j׮e˖iS$SNҊ+C֫۶ ȑ(^[2jaWD"w,?U:-=.si۲?'uIDATx=^l*DӛcǀŋTU +œbh 2 #'3-G"'je,_JۧOk'B/E'?ND9o=} gBgEN\`زٓiY<)fRL2)9m/w} >}tѢH舂  }߽;w|>EN..Xg*OF-jҔ9zQ6Pm%v |p7ΏlǯEm#Km3"C&"D&Ki,,?p!)Q 2jr/'*c`lr8G?۷J۶ԁ"oO""CLiDݻZ*).eBϳx"۰$^T:DLmqB8o8VТ}$/?j1IOAU5YZcdirWѲe+ܚ5kD DK/.5kOϳvsJ?mcS=3mJJ*~|$vq VȭʛTTœH8VE,; C>C'q)Z+Y V8Ѳ ):Aznħ{K?~S8V9>t+'co]Yg79:Gb3Ǝ{U=3FDB<GTANMT$e=Z86D`ڈ_9۷E:n'Eܹ9ҢfȄ/~?ՂsH\$L/Γx2}%uz1gΜ͛eޝ:^^p.Lݼ.C{An8EM*cVHW؇œـ D?LY'>}@o_ؼ ā IjGbd)V]k2W_ ܹ-Z5aFB&OeĐtPXUFDQ !3,Fl'OE{UMѥ/R+ O"17j<<G3uN3f"`SQ(Zxt.RN x}Y< OiO-Ç#- ՠ11adҫ  0f8СC1f7/6)S~԰aClc޽{ȝ;w0aB񽐐59NwލMkumۦAcN4I2N2*hN,I_kHϾO1^ɻE"P,lu:_8S*+*ٴiS7CVs4ESݏ...ݖ8qbrďZ|rmwF xѷo_c$w4'O椯ڜ2_='SO'9wԣE99OFx=f.Fh"- yDժUЮ]HEׯޔ҈n$x|ڵkѲeK)DOQqGs`dNʏxmD:˜ q8eySls0f'ZlVT1M6aĈl5a_6^"ED'P\9hR!k֬F"GEJ"٧b痌œdTќX%KIt5nT@͚5 zқ"' M7&'ӱ摔'p䭱I|ME1uEh[oРA'N|'bرmSǏDœA!S`djœiyh`$_:MWdIxGG1ŋy/\t4YOaLM@nݺvS; Pm)'S$I^$(E9KQ51K2%RN_͛7);QuC*C'Cs&%VtPu2pAxHŊMc$Ic X<ׯ_UVؿQk֬5k EFad>~T*t#O[l9s^ʕ+;cǎꁿK$4Qf:SD =Wt„V=NKv6ɰa@>iՋܹ"8,dCɆ,'@?C^PP^P,_:x2?cr o.mm۶իquе*:.Kɍ aEߏN<=OOƠ7O&X5œ`񤬋8k\(]2EwQ1Mr̎œنI}*D iݺǬ'q%/ '#BVēn¸Z|#aȐ!h޼;Y<)׆2&O e0x4h^~-Ephmȑڭӗ/_D"O/^mi"OԩS1~xD4'KN{E_B4l-Z&U,wppJ7rtX{ ( EhE4Q0y'Ȳ]& I lSvJ'͖ϟ#ͽ|ڭēC/_ɓ'E(u"J}u։g.\5ږ#DPm9ێǏQT)q}Ngذa"XXW<]t +Wם;mߑX$(//Ou xR/gL@f,d!x- &O&XġClE'HXB$b`4ԗÇ;9oڴi] ܷo_RJ#FhǢӁ=E%"|r?H6mE>m͓."(͗ 3f̨cIQl 0 x(SiuJqpݺ#Dw%կ_?"FµkPV-Q΀O;EyCӧObN$(čfێv%h$t(/C񌓓Hh*FҧO/DdQN=OQn%VE/UVܨ=z(XOreL (Cœ2\٪OVN_4zh)DbҐ8 eeFI$T(1; @DJ, www&ža2G%C%GSNb pΜ98{,~*hR~$4[v<0yS?Y$ĨޣmCʃX)8$]Xddž`X<`du.1"ɢaL@,6'~7:,Υ &`QXd&``o`L 0&$?JIENDB`signal-estimator-0.0.9/doc/example_soundcard_cable.drawio000066400000000000000000000174341452044147100236140ustar00rootroot00000000000000 signal-estimator-0.0.9/doc/example_soundcard_cable.drawio.png000066400000000000000000001036151452044147100243740ustar00rootroot00000000000000PNG  IHDR2sRGB1tEXtmxfile%3Cmxfile%20host%3D%22Electron%22%20modified%3D%222023-10-25T11%3A46%3A14.119Z%22%20agent%3D%22Mozilla%2F5.0%20(X11%3B%20Linux%20x86_64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20draw.io%2F22.0.2%20Chrome%2F114.0.5735.289%20Electron%2F25.8.4%20Safari%2F537.36%22%20etag%3D%223Ek41uU_4V1QIihJ50rd%22%20version%3D%2222.0.2%22%20type%3D%22device%22%3E%0A%20%20%3Cdiagram%20name%3D%22Page-1%22%20id%3D%224aUtfOnFfYkB81kRsZ-h%22%3E%0A%20%20%20%20%3CmxGraphModel%20dx%3D%221242%22%20dy%3D%22865%22%20grid%3D%221%22%20gridSize%3D%2210%22%20guides%3D%221%22%20tooltips%3D%221%22%20connect%3D%221%22%20arrows%3D%221%22%20fold%3D%221%22%20page%3D%221%22%20pageScale%3D%221%22%20pageWidth%3D%22850%22%20pageHeight%3D%221100%22%20math%3D%220%22%20shadow%3D%220%22%3E%0A%20%20%20%20%20%20%3Croot%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%220%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%221%22%20parent%3D%220%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%2298YjvIqUe0p6eJIReEFX-1%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22300%22%20y%3D%22470%22%20width%3D%22310%22%20height%3D%22230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%2298YjvIqUe0p6eJIReEFX-2%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23fff2cc%3BstrokeColor%3D%23d6b656%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22650%22%20y%3D%22520%22%20width%3D%22120%22%20height%3D%22130%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%2298YjvIqUe0p6eJIReEFX-3%22%20value%3D%22%22%20style%3D%22ellipse%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Baspect%3Dfixed%3BfillColor%3D%23f5f5f5%3BfontColor%3D%23333333%3BstrokeColor%3D%23666666%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22750%22%20y%3D%22530%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%2298YjvIqUe0p6eJIReEFX-6%22%20value%3D%22signal-estimator%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23F7FFF5%3BstrokeColor%3D%239673a6%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22320%22%20y%3D%22555%22%20width%3D%22120%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%2298YjvIqUe0p6eJIReEFX-7%22%20value%3D%22output%26lt%3Bbr%26gt%3BALSA%20device%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22470%22%20y%3D%22490%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%2298YjvIqUe0p6eJIReEFX-8%22%20value%3D%22input%26lt%3Bbr%26gt%3BALSA%20device%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22470%22%20y%3D%22630%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%2298YjvIqUe0p6eJIReEFX-10%22%20value%3D%22%22%20style%3D%22ellipse%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Baspect%3Dfixed%3BfillColor%3D%23f5f5f5%3BfontColor%3D%23333333%3BstrokeColor%3D%23666666%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22750%22%20y%3D%22600%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%2298YjvIqUe0p6eJIReEFX-14%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3B%22%20parent%3D%221%22%20source%3D%2298YjvIqUe0p6eJIReEFX-6%22%20target%3D%2298YjvIqUe0p6eJIReEFX-7%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22440%22%20y%3D%22470%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22490%22%20y%3D%22420%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%2298YjvIqUe0p6eJIReEFX-15%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20parent%3D%221%22%20source%3D%2298YjvIqUe0p6eJIReEFX-7%22%20target%3D%2298YjvIqUe0p6eJIReEFX-3%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22400%22%20y%3D%22470%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22450%22%20y%3D%22420%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22630%22%20y%3D%22550%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FArray%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%2298YjvIqUe0p6eJIReEFX-17%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20parent%3D%221%22%20source%3D%2298YjvIqUe0p6eJIReEFX-10%22%20target%3D%2298YjvIqUe0p6eJIReEFX-8%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22400%22%20y%3D%22470%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22450%22%20y%3D%22420%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22630%22%20y%3D%22620%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FArray%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%2298YjvIqUe0p6eJIReEFX-18%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3B%22%20parent%3D%221%22%20source%3D%2298YjvIqUe0p6eJIReEFX-8%22%20target%3D%2298YjvIqUe0p6eJIReEFX-6%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22440%22%20y%3D%22470%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22490%22%20y%3D%22420%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%2298YjvIqUe0p6eJIReEFX-23%22%20value%3D%22PC%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22310%22%20y%3D%22480%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%2298YjvIqUe0p6eJIReEFX-24%22%20value%3D%22sound%26lt%3Bbr%20style%3D%26quot%3Bfont-size%3A%2016px%3B%26quot%3B%26gt%3Bcard%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22680%22%20y%3D%22570%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%2298YjvIqUe0p6eJIReEFX-27%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BedgeStyle%3DorthogonalEdgeStyle%3Bcurved%3D1%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20parent%3D%221%22%20source%3D%2298YjvIqUe0p6eJIReEFX-3%22%20target%3D%2298YjvIqUe0p6eJIReEFX-10%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22700%22%20y%3D%22580%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%221020%22%20y%3D%22660%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22860%22%20y%3D%22550%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22860%22%20y%3D%22620%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FArray%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%2298YjvIqUe0p6eJIReEFX-30%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik0zNjAtMTIwSDIwMHEtMzMgMC01Ni41LTIzLjVUMTIwLTIwMHYtMjgwcTAtNzUgMjguNS0xNDAuNXQ3Ny0xMTRxNDguNS00OC41IDExNC03N1Q0ODAtODQwcTc1IDAgMTQwLjUgMjguNXQxMTQgNzdxNDguNSA0OC41IDc3IDExNFQ4NDAtNDgwdjI4MHEwIDMzLTIzLjUgNTYuNVQ3NjAtMTIwSDYwMHYtMzIwaDE2MHYtNDBxMC0xMTctODEuNS0xOTguNVQ0ODAtNzYwcS0xMTcgMC0xOTguNSA4MS41VDIwMC00ODB2NDBoMTYwdjMyMFptLTgwLTI0MGgtODB2MTYwaDgwdi0xNjBabTQwMCAwdjE2MGg4MHYtMTYwaC04MFptLTQwMCAwaC04MCA4MFptNDAwIDBoODAtODBaIi8%2BPC9zdmc%2B%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22760%22%20y%3D%22540%22%20width%3D%2220%22%20height%3D%2220%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%2298YjvIqUe0p6eJIReEFX-32%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik00ODAtNDAwcS01MCAwLTg1LTM1dC0zNS04NXYtMjQwcTAtNTAgMzUtODV0ODUtMzVxNTAgMCA4NSAzNXQzNSA4NXYyNDBxMCA1MC0zNSA4NXQtODUgMzVabTAtMjQwWm0tNDAgNTIwdi0xMjNxLTEwNC0xNC0xNzItOTN0LTY4LTE4NGg4MHEwIDgzIDU4LjUgMTQxLjVUNDgwLTMyMHE4MyAwIDE0MS41LTU4LjVUNjgwLTUyMGg4MHEwIDEwNS02OCAxODR0LTE3MiA5M3YxMjNoLTgwWm00MC0zNjBxMTcgMCAyOC41LTExLjVUNTIwLTUyMHYtMjQwcTAtMTctMTEuNS0yOC41VDQ4MC04MDBxLTE3IDAtMjguNSAxMS41VDQ0MC03NjB2MjQwcTAgMTcgMTEuNSAyOC41VDQ4MC00ODBaIi8%2BPC9zdmc%2B%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22760%22%20y%3D%22610%22%20width%3D%2220%22%20height%3D%2220%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%2298YjvIqUe0p6eJIReEFX-33%22%20value%3D%22jack%26lt%3Bbr%26gt%3Bcable%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22800%22%20y%3D%22570%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%3C%2Froot%3E%0A%20%20%20%20%3C%2FmxGraphModel%3E%0A%20%20%3C%2Fdiagram%3E%0A%3C%2Fmxfile%3E%0A3[ IDATx^XK_TLl1}nQynEq $m@wE]gg0q=;sf& `XS`KO`S .5YV` F;/A`aTA+  2R+[dxq) cp.  2XVx`1_LY`XSA\b8"k`G5ϔ V08d ΥG`&[1d4&^t n`#XI*syz+Y%{8uo gQs7?/_ M4V\ŵbM)zmfCLSKIqB̞2fpGf_DDD8FJUk釪l`Qz!^a$ރ ]רZqjh=l[Pti݊yH:5ve%%> 2k%Ś 2R z2$ӥs'1_{y ]_ =}臢lF`шz)޸ a$$@Ty+XYe]4jw* c1yv&hrRܷ) cx>?#/ώФ 2TV 2jR/;bKQ$`Hc[nPVb9rJBxA&.XUAh]/vvv"_$%%<<[ĉQnݔt 2Zb NsaNH* ,]wSteȘ1#6n܈͛7cΝȓ': bŘ7oJ,#GO>С>|___TT ǏGQV-4lP VZ!0aڵk'_]t~Q0轋@V@o`[װa 8;;#F@tt4-ZFaܸqIP޽;2eʄYf+WD2FnnnX|`'[lzdEl + 0k0 ET:w,udW3g`ӦM/^M4Z"oʝiڴPw CѠk׮aر2e o-+  2bØ"2ðanݺ OӧOo84={}X[[ bIz]/y\Y@ 0RYDFE!aGԩSرc֮]ףhѢ۷"25j>}f͚lٲ"^z\2fϞX)] #?k6P 2j;ѴRҀrd(1uCBBXP".m1]tI$RL~dʔ)#gȐ!"B[KVVV'ߏASNݻ7^|)c'ODbŰl2ܹsG*lΑ_  2[T@N--YDZJ& j׮-n)&\P]:TJ̝;gϞPC0C C6O>ŋ/PF V̙(QrpҦMիW#&&CE``^zZ`{* a+ QdɾtL=խ aXWAF] 2} y%0wynf`Ѭܻ`Qz :b$&_D| clSAF}ZrOT"2R/fKQ$`H^ 2_+Id4.62t /N.> sss踴8s3֭[/Ǐ@j1h:.-+I;d'&e=PIo0n}+ 2 2Q[-믿!n㥗:YI d֬Y#nתR;zرcNV_ C}4ʕ[a7=t`RmLddK:L6M!quuBSSSĉȟ?xJrw0EPl"~Ծ}{EdUm\r߿GǎN2۷oAmSJ%졹 8PDiYD.״7o^QOٵk7oޔ׳)RD_~0zdȐA-""B<:|pqA%`QN/#dt$]]&ܽ 9a٪=,:ü|eGgQY:n/p=8 5M譳3(8qu( ݵ5ڵQS|itUH[R0(%WI(\rSLպ6'Nm&%UgQR0dtF׉uv#Q|ή tCGɝ7Yd+$ˤm7nF~7l^碘 2ĵtN .D{RR5l3'jfoeB $**7#,`I^#C* +LxSSS177GrϸH_SW&:o~v!eLMVX*CFy{]̀q;!Cbc.Y:t{f"q)ԣ5{m3ķ믺3Gֺ__D=sۅOw23Gaݶ32oen%{G^vګ垘ビ'ObԨQ)3?WcO&%8 2?AJ |~uۅ/>O}F@h?YRVM6ךTW=[t]^x{{%KX[[5ھ};V$ KjCАX|֭3􈍉5}kC >/חr̉;"O.qnuK nESgQr͛71b:X`rȡ<} t[cj cLޖ\|v<>Σ9K6L7 ߾}C&XzfæjMs*.YO*Νd,QBk&%6fs9Dk 0j褐2o'3M6EPPxqƨ0߼yNB@@ݱcǔ޲+/XBycEc}yy_Ln#3wDgtH ;svաCfY,lt`c7M ]OG>޾}+^ӧOGϞ=!˗/شi^ƾz*e˦W^&M*.+ +C/z,.Ȉp< M&k˺1b~ W |j[l,^9"{SBt4?έ1Ȩ[џ +COL,ңР.I͡%g1TPAa]vaժUѣG6oތ{ 0Qܺu hٲ2͌.Q[&{>c)3;F5Up g+L7 HH׈:p;w@\15E rpIVdԭ:{NH h;[ȗ/Hĥ#EJzp茢 7n!Cmbtd1[׊2T[H|H?b(V(z -"5!ׯImn-Z|͚!uڴjAFr&_q|[D' h 9wX:vGnnn"2g8;;+4Ea„ "Lt%00m$ *fi֪ ju|8Pd;Dxzeji\ک5ݳȖq8C x7MSˌ(:c0rhXZZ*dŋ1~x?~kV͹s̚5 CU Um ÇCٲH.Lff0;_e?5lȅAƐ's esEӐ1`,T[AOfLDz{ OϔMKJ:YxԣO3f̙3vZ/YN&'~}PdƍLӺ59L_3ɝmm@ 2R Śesq8-xP Ɛ7'ڪPWሌLpϧx}RLLG+O)LE%5 YDM%Szb׉UXp CX82ڊVJ>]AFۊxH^ȎPyz:AFSMS߾ȤJ{9KONP Ef%rd>}`|z1}'8/^I`U<˗U T idт#A&y ЛHGѿV XK(v=ZJ.-i+&]ά tiTPZd CJ*% 2KJ`+TE"sD>~g)"۲H H״Jޑ[eQFωEF;#F,O] 0hYp}.=2ҡ@߶(i&~}áw9gqTXIhdn߾0N:)4 %*EE!#xS~oΦ,쐵Aq'S?TbUU;Ȝ7eqkW=։e+-$>B3dՉNnpۣH9p)$<|iKx'1jzv@Ѣ7{zٳxw,>/"=[<={"]NWz[d 76~RӖjY clO8_RLVGܹ`bbxGANS4ٗlذacPz[K.]}r^|~N>G)_߾ٺBVyvzB!0|OAF|*F2epȑRfMԪU+A/_?K*v?rw(GI!ҷox񢸓n0-}(0h4껂AFoݻd O/muqdѮO%?]h`1 7}sWEmakk8}4FlS.^,^q{wZi2޺\? cOU `>~} Jst邂 :5r$9"4K5+-BnTҐAF%ٌ^J3gn7`W:-3üctUg6hcW ^^b(m(y06e@c03 x* 2\-L=z,,,,0Z!Θ b޼yZ['~ xT0(,W$dxHA)xIm ƴ1utIJN:U'ӦY8U4(9ol S$dJ2dx-HA)xIm z}Gibc6tO;wnut'>ALQ|i].y0$+W )( #/鿍ABhq=FN;w.Fe5n݊={<߭[+ dlo`ᥡ.#b0uvbŊ[y?ػgL4 3fT{R.ӻK߾vv* 2Rfё@FQhWo<@o[0f20FTt,(:*U*9_LQٸ< %":&+xBy~Ha? [d͚SV&@٬ޞ8R˖3ҞI( }bM)-@PV%d̘^t&K#_]o7{.j7uu>sd & (> VFUWۿDDwsJGdn݊3fSmې7o^Gm߾qqq6l\]]DdPzuQf͚*"krwQݝA&Ejic%6mvꡨPn EAzuǎ='ЭDC:®rB`@l颸u8q`)T,];U+ߟ>w9"j!:Zncc///Il'P/u_p111xq l2/ÇGnݔ?q85+⢢PŋRU5d.{nz8yu^Ѭݏ׈^_A?tu9C.sj_lO}z]nH?Z7H+$2)"2_%lsObQ 7k.lڴ OF޽> 2!O; H%'']g1 2u )( 0v?\9oVƥtnߌb#w&+'wӰX ʕKɣڈQ@嶻*Ԓ" Ӥa5lԿ=V,#hqAF97+][27ȩS?. KgϞEѮ];4 L2>}Pӷo_]v6ն-* 6e##qħ i+h6Eva;|^asg`fl¸)+.]ZmUއөQv%P %>yra*8},2fPrX<(,]Fx0 `FlrBmC9~-˗/c̙tl޼Y L%0zDlʇ(ʩ-Z ȟ?Zԏùa??Id ,pQs'O?%cI;l\ U%K`:p]>j5{<ΜӠv( 2PH 2+xcLF РNeL ;ܴ0#rihJE;LUסSFzy`pl~{`, 0PKiaXjߤzviF"ƒ/)?Y 049t萈P4}(ʃٷoO. |UbE:7oޔ5kPn: kk| CPi'`ee5dhds杛Ц^Qn-dɒE-S;rΜ<_*Gd@C04I.Gq I֭ѧOL6 &L4ҨQZ"Z*w!Ce\*_ƍ2LGO=5aՆUȕ+'Gdnػkˋ Spadϑ鳧H7Q~lݽE]ס#SvhШ>__a뷐-{6,Z6X8wV-_ޣD☿dȏ"yʝ:f/XXZ;C8rD5 lٵYwط{}3Z`-1Bb> 44LKHM7{+aĜNU 1Ȩo;Ѱ 2ORCU.ް!ޟ=*Ǐ,NC{1cv`VپerD]Ѽes|P`N]89s-"ܘt}5Xz)B65[6,[ Wx뇧Ovkjj1;Ua?c'Qؒװ?Q8{w̘3v# %k1 AԉSڶFnгs/T\/Ěk -@sfh?VB94<#D:a2eKS_hsRz1(-7Ё 2:4 ڝ9sf|A[q/E;d(1~P¾=*V "TGdzu=; Cyi5mv?Z(y h[fɂ%xarqhWo1m!9fMc(Wv.:F5jUΨvX[vm-ϑ@J͚I&4mDϳ}#QJOgȁ~N}UXE 2W,64oh/Pc l\&dTjQ-C#2o TjԨݫ4V~:{>qqGHтkヌ}e} nXNC,idٱ!!")>(,ٷ|hUWŔѨNMiҤ?'=&Sfb zFa Nښ1Wn_FѦE[ܺqA~.G^^vշ'V_d._,:s F5RٷG?ܶK@߁nd(S7+24 2$tAF):lL>]@cccq5A{Lνo>L2aĩ=}N ҡ%Z6iq„Nj% 2?Zz=ǎk_߾lDF].|;"@NDAF0IlWQiRn߼obQόR]c3h~ xwb-\? 3dP>y7}rֿ @fiڢdAAԦ3zjG ?l߳ʔJ2Gs) b2ܸv 7X$.ZWʻ~<#FʿWɑQd*Alٸnlu`::t91뷮ǴkwBf&uf(rdR! 2kh{#pfݰA@&((7ąJ*UeaW.Pr뀾L-V(cB[&tj)}04Q]pEQ3C`sW$y %8wn݁u&k s!ÝE-ĵ̅ ¤iʡug>r8$GF#(ϟ`1 1w:,--)Y2ݫW\<I\XպmkL3Mly1( ACt`L C'߿/n}FI7 7^,N];9.U#2՗{W 2Q smAǶ{L] 2AZzp<}Z"2CnJ~ЩkG8; O˓q)q + }="M?Ü4i?r;WWW9b?bǤN:X~=LMMloڵߑ#G?̌3ĥytopBqFr`Aޓ'\o^b0(\45RL5Ft'cXaцq̛7.\~Ыǻw0vX \2/tI =Y@ CHɓ'`иqp5q nݺ:tJ017Gh遌JFjSAFmRrGTAF\jVo8Wș# ڵcDFFcҌp;ro~D^p#Z>>| ù#ĻNܽuF`l>/ҡ/x+o-וIF@zIws6IBI<IpB C0UREZj""Spa9SŊØ1?2g}\ESn;2kg6®-z8MQh"2u:4'N\. *P\9^|>6ׯqطuڵXAodd{")QFqIPP8JHt nC sy/_^^ȫ /U T8_?G{}{ED:WAW`QNf톉i(m7P2(AϖG1`,*Y7$sGaȀgWGQ }z3ӰXɍAF}L}a|Ҋ+ ׫ P %+Y~1.(TiҠiXȓћ' 7Љ 2:UR%K:m Aǂe;$+bWL2AVEG.MQdE[Ker=v.(:D[JۣGK[G/[nE.]P&44T$4SK3gĖ-[)Ebƍ='e˳Yx8l dU3d稣'/þÏwvr ,-2hjʅcPXAs쒸&19s>Z#|j5/< R=}mmr[ O 2& yH`QZ6bMW")QQ1oB@dwaUL1ܻCվ?tŊcg k&2n "R=ѓ4A̙08&f?!9"#yjw 2՛GSMt]+qpqj}=q3T\WNǁΣCϱ"tNxаHmc\zbƤA I[KD;+('F6 g,NHý;Rop@)9>  -/8 2HzLnú͇ Y2[BSD$~Mkbј8c5o9\9߂ Ee9Oً`mTt)}Z8gz'<hd4ﰲsPB"j <;cሌjzu+vd& #WIPGr<^D(W"2d'r1_erOtt4޽+n jԨҥ6zE1.)_ӵkQTI'` d%sGl9PL9ى3E yyy!!!h۶poD&MTf 2Jŕu7ao¾۔LGA޼yѭ[temv;`jazϟ#] 2q-LAF ")VA&r)) гg/qӧOŽ-'O[R\It421O#kz^5J) \\YG 0Hx6G,] G'jDDDW >b+B,uܶm0W2AFUZ0H_j-z>e[O=1H*&%'OĨQRҍ^ Ǫ6oϟajeSJ bF^AD #G鑙p-tUU߾}w^ѾsXvR7{,`,6Qƥq;k/z `&>Ȍ7ǏOyWF&MPd$#͙+Qvt钢qmL[E/]Dx!AaܡR;(;y/]J߿ XZYîLy8 jR**l>( ^ NCPBܺu hٲeQܹ`"CѢ (*x*B]Ç˗yEEɻJ)ræcGdoL!j L\)1G7C:o5.8:FӖX8V@' 0DvdiԨ%JPy///ܸqC/^³ٳz8#+t|9_ӎz~~Cv !ׯerѼ9r4kLU dU'P`ǦX0s2ZX߻~w^wv\x>pӐؽ? hU--<#ML`` ۇ ]O'͚VE̙udt"a :n]gL,0qh hCuL͛xw/hdG|RU|CoRXZZ*ի+^~;v`ҥ"1ٳE$b؈dbe m+-XGēuRIDAT?e)l!}E\L ĈikTԏOt􏯑 paX, RxqX- 2ejJ 2PǠ?Zg[LMMmxX < V֙ \.H)Dz{MS.#JOQ@/ĝ/sss%>}z)RzRQ|cN7d%> 4N,o^K!ܹ|ok+E {#Y|ط(ok`3L]|Kvzڂ#2Jo/y"w׮]xH 3ǎӧQzu'.̚8> O\DG3to!ff0I?u͕I0GĞ=ay(UД*i#̧oܽ!7nGI'.:w'.RMW>%jVkJiFJrdڴiSNׯGƌqrr‘#G䠣l~Α_ŋ@#7C"VN,2MaєܯB 8VǷiۉn+$WJF@KH^8 ŋWJF\N&2hLgIRKןF %CCCŶљ3g6mZ-Zqqqx9|ƍcƍV6lgg4w2*MLd(&w='rh(Q|t[u) wJ`i,g-^>,S?*2׬<;#wZ;u ZЉ;Ȝ8*VҸt1(m-mٲWVZٳ':v(Tܾ}[Dw~w ς]DDh(QEedT]]N# <|.rhz94|t[#2KSnȽz'LfK~%]^v:!+Vˋ ~J. 2V<>+>ptbR=WE}r")C7vꤎ%$d|FG>m|k@6o?#KsD߹b~ W/ʅ;6^貰 TPʟGܹ`bb" 25E(RH:2ȤȍܘPtK0EhdG>ʧb Ѕ_"1+f$:;7~p@:fy+)BQ}) 2۱jYTeRx?ʚ5kDDfܻwOa.W#2:$ GӴe{q^|%c;bG{dly##Oڋ%u,/^ g"KZ@ Z 2Zpoѭ[wmX[nE5PT)I aGMI*@G,e+`8/?7Lԣ8i'պ`d0wۅO僥ʐUNXe.uczaрjrh֢-lmuzgFv 2_I&mB*.W`ԕb1vC} &ej_,cj@j_=2RAFW'=k=zÆEK.(X#9A&9z as1L\\\ @7axȈNʡ3,ZAjKDa1uYp}0*?~]I #)w 2{2SVKf8&MV d% I(v=Z׉Yp!͛: T=gdv3 d}MЍ+L ,!ةI cEӳ ƴ1utMKǏԩSuQZdQ܍f`Ѭ}Bht//Ulaf}e.J4cl|9"3y`e`QF-e+ ]y4*ȴjJwCR$8 7KdͣTAڵkȐ!ʖ-̓oFI[ĉQna =t  2*KRCdFV@ ?"~,]'OƦMG888;%:tRJwW4DZаaC+Tc„ h׮tŀ b =RAF`Ѯ< :tHj[ti [lm&T޽;2eʄYf\R@w Ca`ve˦ʺk ;yd+ ~MAFzh**`H CӘ>}Pt"4z\\6m*k.^ Cھ;v,L[K/W?4nd"0(,Wԥ2=KdBo)RDL߾}ѳgO!5A AAP0$*dtc3hw 0hWoMEd >}BfD0mիW+Wٳ+5E 7Ӡ 27d72t#[,uŋ1H TVMӲTKvUÒ;O[UCmd4.  2_@毿BDD=z$^7d%)Yf v!^.Z(ݻcǎ{]R;YIMLpp\r}+ 2 2Q[ DV0l0?^DUMȸ xhs $=H%;"(:6ۋ(,"-^r ;[no߂ڦJJCs8p,Sݻwț7G?QٵkPfÆ ػw/r̙ "Cꟶjժ%".d'=RILLLɓGAFr笀A+ c5idƌ///-Sݺu #Go/XYYM6 xZh!hSTrm(dPY5mQ4o 4d C?G+d+A屐>>>%>dGGdr-rx(S;š$`NPŊyfK3d.&˝Ap&Im-[|)SEH I*UD@!66Qi h (6,,LDg*W GGGH;&-)жئZt)_8D[BT #m+~G z<EtlNA̓f(D99, 2Tf [N c0"Ix" 2v X;WLtj-zft}("I Ǧ:VAFSAF1ZAFcY+ { ( H #a鬀`ѱxx`QL'bnV@ 0l 0( 0Hyl:+cdt^1dId9н 2[ 2 $* 2v X;WLtj-zft}("I Ǧ:VAFSAF1ZAFcY+ { ( H #a鬀`ѱxx b Rm\2Q[+  2`TTAFE+ Ad$46`VAW+`< 0y( c4扲`E ' V^+`p 0KyB V0d signal-estimator-0.0.9/doc/example_sync_mics.drawio.png000066400000000000000000001632131452044147100232530ustar00rootroot00000000000000PNG  IHDRYr{/sRGB`tEXtmxfile%3Cmxfile%20host%3D%22Electron%22%20modified%3D%222023-10-25T10%3A59%3A15.629Z%22%20agent%3D%22Mozilla%2F5.0%20(X11%3B%20Linux%20x86_64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20draw.io%2F22.0.2%20Chrome%2F114.0.5735.289%20Electron%2F25.8.4%20Safari%2F537.36%22%20etag%3D%22v_L9TnylOEsYmBi_X96y%22%20version%3D%2222.0.2%22%20type%3D%22device%22%3E%0A%20%20%3Cdiagram%20name%3D%22Page-1%22%20id%3D%22dlh2HGEMS9u2Ikbi2MeV%22%3E%0A%20%20%20%20%3CmxGraphModel%20dx%3D%221242%22%20dy%3D%22865%22%20grid%3D%221%22%20gridSize%3D%2210%22%20guides%3D%221%22%20tooltips%3D%221%22%20connect%3D%221%22%20arrows%3D%221%22%20fold%3D%221%22%20page%3D%221%22%20pageScale%3D%221%22%20pageWidth%3D%22850%22%20pageHeight%3D%221100%22%20math%3D%220%22%20shadow%3D%220%22%3E%0A%20%20%20%20%20%20%3Croot%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%220%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%221%22%20parent%3D%220%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-1%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22100%22%20y%3D%22220%22%20width%3D%22310%22%20height%3D%22270%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-2%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23fff2cc%3BstrokeColor%3D%23d6b656%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22530%22%20y%3D%22220%22%20width%3D%22120%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-3%22%20value%3D%22%22%20style%3D%22ellipse%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Baspect%3Dfixed%3BfillColor%3D%23f5f5f5%3BfontColor%3D%23333333%3BstrokeColor%3D%23666666%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22570%22%20y%3D%22260%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-4%22%20value%3D%22signal-estimator%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23F7FFF5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22110%22%20y%3D%22325%22%20width%3D%22120%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-5%22%20value%3D%22output%26lt%3Bbr%26gt%3BALSA%20device%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22270%22%20y%3D%22240%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-6%22%20value%3D%22input%26lt%3Bbr%26gt%3BALSA%20device%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22270%22%20y%3D%22330%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-8%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3B%22%20parent%3D%221%22%20source%3D%22jdgYiCKV-6AsK4i46VtF-4%22%20target%3D%22jdgYiCKV-6AsK4i46VtF-5%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22240%22%20y%3D%22220%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22290%22%20y%3D%22170%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-11%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3B%22%20parent%3D%221%22%20source%3D%22jdgYiCKV-6AsK4i46VtF-6%22%20target%3D%22jdgYiCKV-6AsK4i46VtF-4%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22240%22%20y%3D%22220%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22290%22%20y%3D%22170%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-12%22%20value%3D%22PC%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22110%22%20y%3D%22230%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-13%22%20value%3D%22sound%20card%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22540%22%20y%3D%22230%22%20width%3D%22100%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-15%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik0zNjAtMTIwSDIwMHEtMzMgMC01Ni41LTIzLjVUMTIwLTIwMHYtMjgwcTAtNzUgMjguNS0xNDAuNXQ3Ny0xMTRxNDguNS00OC41IDExNC03N1Q0ODAtODQwcTc1IDAgMTQwLjUgMjguNXQxMTQgNzdxNDguNSA0OC41IDc3IDExNFQ4NDAtNDgwdjI4MHEwIDMzLTIzLjUgNTYuNVQ3NjAtMTIwSDYwMHYtMzIwaDE2MHYtNDBxMC0xMTctODEuNS0xOTguNVQ0ODAtNzYwcS0xMTcgMC0xOTguNSA4MS41VDIwMC00ODB2NDBoMTYwdjMyMFptLTgwLTI0MGgtODB2MTYwaDgwdi0xNjBabTQwMCAwdjE2MGg4MHYtMTYwaC04MFptLTQwMCAwaC04MCA4MFptNDAwIDBoODAtODBaIi8%2BPC9zdmc%2B%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22580%22%20y%3D%22270%22%20width%3D%2220%22%20height%3D%2220%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-20%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik02ODAtODBIMjgwcS0zMyAwLTU2LjUtMjMuNVQyMDAtMTYwdi02NDBxMC0zMyAyMy41LTU2LjVUMjgwLTg4MGg0MDBxMzMgMCA1Ni41IDIzLjVUNzYwLTgwMHY2NDBxMCAzMy0yMy41IDU2LjVUNjgwLTgwWm0wLTgwdi02NDBIMjgwdjY0MGg0MDBaTTQ4MC02MDBxMzMgMCA1Ni41LTIzLjVUNTYwLTY4MHEwLTMzLTIzLjUtNTYuNVQ0ODAtNzYwcS0zMyAwLTU2LjUgMjMuNVQ0MDAtNjgwcTAgMzMgMjMuNSA1Ni41VDQ4MC02MDBabTAgNDAwcTY2IDAgMTEzLTQ3dDQ3LTExM3EwLTY2LTQ3LTExM3QtMTEzLTQ3cS02NiAwLTExMyA0N3QtNDcgMTEzcTAgNjYgNDcgMTEzdDExMyA0N1ptMC04MHEtMzMgMC01Ni41LTIzLjVUNDAwLTM2MHEwLTMzIDIzLjUtNTYuNVQ0ODAtNDQwcTMzIDAgNTYuNSAyMy41VDU2MC0zNjBxMCAzMy0yMy41IDU2LjVUNDgwLTI4MFpNMjgwLTgwMHY2NDAtNjQwWiIvPjwvc3ZnPg%3D%3D%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22565%22%20y%3D%22320%22%20width%3D%2250%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-29%22%20value%3D%22%22%20style%3D%22endArrow%3Dnone%3Bhtml%3D1%3Brounded%3D0%3BstrokeWidth%3D2%3BstrokeColor%3D%23B20000%3B%22%20parent%3D%221%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22560%22%20y%3D%22400%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22580%22%20y%3D%22380%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-30%22%20value%3D%22%22%20style%3D%22endArrow%3Dnone%3Bhtml%3D1%3Brounded%3D0%3BstrokeWidth%3D2%3BstrokeColor%3D%23B20000%3B%22%20parent%3D%221%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22590%22%20y%3D%22400%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22590%22%20y%3D%22380%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-31%22%20value%3D%22%22%20style%3D%22endArrow%3Dnone%3Bhtml%3D1%3Brounded%3D0%3BstrokeWidth%3D2%3BstrokeColor%3D%23B20000%3B%22%20parent%3D%221%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22620%22%20y%3D%22400%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22600%22%20y%3D%22380%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-32%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20parent%3D%221%22%20source%3D%22jdgYiCKV-6AsK4i46VtF-3%22%20target%3D%22jdgYiCKV-6AsK4i46VtF-20%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22490%22%20y%3D%22196%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22650%22%20y%3D%22210%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-8%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik00ODAtNDAwcS01MCAwLTg1LTM1dC0zNS04NXYtMjQwcTAtNTAgMzUtODV0ODUtMzVxNTAgMCA4NSAzNXQzNSA4NXYyNDBxMCA1MC0zNSA4NXQtODUgMzVabTAtMjQwWm0tNDAgNTIwdi0xMjNxLTEwNC0xNC0xNzItOTN0LTY4LTE4NGg4MHEwIDgzIDU4LjUgMTQxLjVUNDgwLTMyMHE4MyAwIDE0MS41LTU4LjVUNjgwLTUyMGg4MHEwIDEwNS02OCAxODR0LTE3MiA5M3YxMjNoLTgwWm00MC0zNjBxMTcgMCAyOC41LTExLjVUNTIwLTUyMHYtMjQwcTAtMTctMTEuNS0yOC41VDQ4MC04MDBxLTE3IDAtMjguNSAxMS41VDQ0MC03NjB2MjQwcTAgMTcgMTEuNSAyOC41VDQ4MC00ODBaIi8%2BPC9zdmc%2B%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22495%22%20y%3D%22400%22%20width%3D%2250%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-30%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23fff2cc%3BstrokeColor%3D%23d6b656%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22480%22%20y%3D%22490%22%20width%3D%2280%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-31%22%20value%3D%22%22%20style%3D%22ellipse%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Baspect%3Dfixed%3BfillColor%3D%23f5f5f5%3BfontColor%3D%23333333%3BstrokeColor%3D%23666666%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22500%22%20y%3D%22470%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-32%22%20value%3D%22sound%26lt%3Bbr%26gt%3Bcard%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22480%22%20y%3D%22510%22%20width%3D%2280%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-37%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23fff2cc%3BstrokeColor%3D%23d6b656%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22620%22%20y%3D%22490%22%20width%3D%2280%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-38%22%20value%3D%22%22%20style%3D%22ellipse%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Baspect%3Dfixed%3BfillColor%3D%23f5f5f5%3BfontColor%3D%23333333%3BstrokeColor%3D%23666666%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22640%22%20y%3D%22470%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-39%22%20value%3D%22sound%26lt%3Bbr%26gt%3Bcard%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22620%22%20y%3D%22510%22%20width%3D%2280%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-41%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik00ODAtNDAwcS01MCAwLTg1LTM1dC0zNS04NXYtMjQwcTAtNTAgMzUtODV0ODUtMzVxNTAgMCA4NSAzNXQzNSA4NXYyNDBxMCA1MC0zNSA4NXQtODUgMzVabTAtMjQwWm0tNDAgNTIwdi0xMjNxLTEwNC0xNC0xNzItOTN0LTY4LTE4NGg4MHEwIDgzIDU4LjUgMTQxLjVUNDgwLTMyMHE4MyAwIDE0MS41LTU4LjVUNjgwLTUyMGg4MHEwIDEwNS02OCAxODR0LTE3MiA5M3YxMjNoLTgwWm00MC0zNjBxMTcgMCAyOC41LTExLjVUNTIwLTUyMHYtMjQwcTAtMTctMTEuNS0yOC41VDQ4MC04MDBxLTE3IDAtMjguNSAxMS41VDQ0MC03NjB2MjQwcTAgMTcgMTEuNSAyOC41VDQ4MC00ODBaIi8%2BPC9zdmc%2B%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22635%22%20y%3D%22400%22%20width%3D%2250%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-43%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22H8G9I3JoE38qBTgvnNji-8%22%20target%3D%22H8G9I3JoE38qBTgvnNji-31%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22530%22%20y%3D%22315%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22530%22%20y%3D%22335%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-44%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20edge%3D%221%22%20parent%3D%221%22%20target%3D%22H8G9I3JoE38qBTgvnNji-38%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22660%22%20y%3D%22450%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22520%22%20y%3D%22480%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-46%22%20value%3D%22input%26lt%3Bbr%26gt%3BALSA%20device%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22270%22%20y%3D%22420%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-47%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22H8G9I3JoE38qBTgvnNji-46%22%20target%3D%22jdgYiCKV-6AsK4i46VtF-4%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22280%22%20y%3D%22365%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22240%22%20y%3D%22365%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-52%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22jdgYiCKV-6AsK4i46VtF-5%22%20target%3D%22jdgYiCKV-6AsK4i46VtF-3%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22530%22%20y%3D%22460%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22490%22%20y%3D%22290%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22540%22%20y%3D%22265%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FArray%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-53%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22H8G9I3JoE38qBTgvnNji-31%22%20target%3D%22jdgYiCKV-6AsK4i46VtF-6%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22400%22%20y%3D%22278%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22580%22%20y%3D%22289%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-54%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3Brounded%3D0%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%22H8G9I3JoE38qBTgvnNji-38%22%20target%3D%22H8G9I3JoE38qBTgvnNji-46%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22514%22%20y%3D%22488%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22375%22%20y%3D%22390%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22550%22%20y%3D%22580%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22510%22%20y%3D%22580%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FArray%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-57%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik00ODAtNDAwcS01MCAwLTg1LTM1dC0zNS04NXYtMjQwcTAtNTAgMzUtODV0ODUtMzVxNTAgMCA4NSAzNXQzNSA4NXYyNDBxMCA1MC0zNSA4NXQtODUgMzVabTAtMjQwWm0tNDAgNTIwdi0xMjNxLTEwNC0xNC0xNzItOTN0LTY4LTE4NGg4MHEwIDgzIDU4LjUgMTQxLjVUNDgwLTMyMHE4MyAwIDE0MS41LTU4LjVUNjgwLTUyMGg4MHEwIDEwNS02OCAxODR0LTE3MiA5M3YxMjNoLTgwWm00MC0zNjBxMTcgMCAyOC41LTExLjVUNTIwLTUyMHYtMjQwcTAtMTctMTEuNS0yOC41VDQ4MC04MDBxLTE3IDAtMjguNSAxMS41VDQ0MC03NjB2MjQwcTAgMTcgMTEuNSAyOC41VDQ4MC00ODBaIi8%2BPC9zdmc%2B%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22510%22%20y%3D%22480%22%20width%3D%2220%22%20height%3D%2220%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-58%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik00ODAtNDAwcS01MCAwLTg1LTM1dC0zNS04NXYtMjQwcTAtNTAgMzUtODV0ODUtMzVxNTAgMCA4NSAzNXQzNSA4NXYyNDBxMCA1MC0zNSA4NXQtODUgMzVabTAtMjQwWm0tNDAgNTIwdi0xMjNxLTEwNC0xNC0xNzItOTN0LTY4LTE4NGg4MHEwIDgzIDU4LjUgMTQxLjVUNDgwLTMyMHE4MyAwIDE0MS41LTU4LjVUNjgwLTUyMGg4MHEwIDEwNS02OCAxODR0LTE3MiA5M3YxMjNoLTgwWm00MC0zNjBxMTcgMCAyOC41LTExLjVUNTIwLTUyMHYtMjQwcTAtMTctMTEuNS0yOC41VDQ4MC04MDBxLTE3IDAtMjguNSAxMS41VDQ0MC03NjB2MjQwcTAgMTcgMTEuNSAyOC41VDQ4MC00ODBaIi8%2BPC9zdmc%2B%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22650%22%20y%3D%22480%22%20width%3D%2220%22%20height%3D%2220%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%3C%2Froot%3E%0A%20%20%20%20%3C%2FmxGraphModel%3E%0A%20%20%3C%2Fdiagram%3E%0A%3C%2Fmxfile%3E%0A3 IDATx^tTG!B'x n!$šh;qBw/Iv7yowi}ΝM~{>3D+ S`JG?[W _퍚 AV641+ `\ W~vh#yb*|YV@ 0d)76RxƐ%ʵذg+ p&Ks!Kfv|yt+r8p!KBmG V!K3=C!>g?`4C̐r&Kѱ`Rw yϐeH!uϙ,uǏgX+3dig?`4C̐r&Kѱ`Rw yϐeH!uϙ,uǏgX+3diIL2 +MHH}> D.}o۴#vADDlll2u}6c :,WlB LT/p7_"KCdR*CC"'f Nq$_ fWYg/CEapvoשS,_Wz]Y .ES`DbȞG;4Y3g4Og܋8p .j;d2/d}vvv1d1Rd T^dmXsٮ?sh#1XפUGd͖C4` av|T;ƛ!}j4_Dɿ}>˰a>Ы FzÝ{ѶEmJatMdI(Yn~$rqv3c2YTN˅v=]X ÃѢIul\9)FIwVޤAeJNoS9aߡvк.FvGE7:Moڰ s% 5.1mFwoa\>q޾s*(\trn֌iW,ƖFƐJ=:) |s*`bs (TTú I,Y/ڪ #jV- -~hߏ T~ś Ŋ Y]g=;7GkaJJ5g9\dɒRWlQA<&,WPX>̟1\\KryhvHE5QbNXz&%I$+eVj!KQRAF=ǥCV 0dYp3wǐefUCh},mǗG@Μ9#]˖TPBڮ]P`Aȡm뻗!K1gv|yt T K.(POJH @F0fT\9!v/C٤DG Yc`v|yt T@-{… oJX|9V\#K,ؾ};f̘Yfϟ?ϟ_ѢE \v <@R0j( իW EaÆȞ=;Ff;mlHM6ѣ#%,ŇHQ2d)*;Ð%l[@V>}p} 4!!!9s&jԨ#G Yɒ%0D'+j۷GT0i$\rG׮]AA֭[1w\a@,]t^ YdRT8$w!KrI +~ȢLT֭RA5/ҁbŊX3YU7n, ?~,`Joժ]rQ+6Ȣ,کS0|pxyyr!4C&êCˣSjd]xGnЮݷ_Ǐ w!sرE2eJk YqOR1g@iO,4_Pd2Y8`ܸqúuxb,]yvZ-U~} 2aaaS)"긪TҥKc YB z0d Y KCb*C.i[5@EjH ?~(iTUjUAV…8|WdhY{UlٲzBV/ŋmw^͛ss=H˗jƁkztZ7x=>?0.՛pvSrdϜrd@AlRK{ Y;aM ٳg 'N+t*l6i2M>[t-=YXLL:EEE]wÇQ|y"[RSLAppj$I ӧOׯ>}*SN* Yd]'ŕG+^)R8NNN⇶f…s} ȉsP>C>n5(Ȓ*w;CRU,ņFi>xGtPp1O^D֜~:^ߠiݒS4ڐ.dRX@+`]Qfrt k͖uo ɒ>)ڵY3B&e݌(6w  YڞZBw> : )R cn )нdLe-!KQ`gA,mG3Yڎԣ36GB_Be2֯dқޕD|ջT07\TЕx~>^;wn366wkk`̘.?{'O1dRg$V\E6 I&Ν;<1і 9s$|>%Kѣx\rb+rAd' i+ݹʫ;4-"ec*dEM_<-S;KZԪ ]&53b .Nzȑd]"́oK1)jh Yj)Y#FR]G%6 յ kѢEbG-ZbV:bgϞ=b*@T/'dѦT[X1ѩC"lYF+>*2]߶M 骔Anp[I|D+KW'mF@Fr! EF۸q$6)k-!ˢs֨9 +((HN>|Xd LݿjOdϞ]L͐qӪUK͛73]&+$$:q"##ѲeKqVb׮]н666KϞ=EFehɓ'Ț5Nڰam???TPA!KNug[2Nz1{Oa߮AE˥n^B2g!|ֽWзahQ8rr!ːB>+ ,:fҤIغu+9NE]2+E^ZUjD(W\T0d_w1C-ZpY=d.A;=<;3Hg!Λ77n?̙3 sO2'eꇎi #GD6md!KYzq9p /wE˷ikh;uE8sv~샕А޿{lÐujJd;`+`>|8޾}+@2B7vXa\EGP2Y/_Su,Cu#޵k8jg„ "H2Ym˘16]R%4k m۶nS:n^WԚ,jѣG(X18OjrK,զ]sAVTÛ'r9Qn|PmוOpi>^AO\7oeܿvJ-~!CV _!KI:{PddEիW8~(O^jc_gcڵ c6hI `h*Z ᧟~gGG*݁Q!Xb~TiِNWOHg0۷/3N,#DK X8Q n?D$"K-^GoDJ(TI{8>1ƍcȐe˗/ѡI>b,s+YrC-M8^ˋk&X-Y9˗/0 lts&9t萀CuQӦMg0hd/tC= I{ݾ"ҸEӥK>:t3hwޠ˘f5+vb0d)64VŐhYWsBV_ "F Ijd?W|%m-[6-[*UJ `j(cC۹:,KZ Yڞ Yڎԣ3'dwѲu{%6Qie(cݧqg"Μ9S3Dksm U!+ *~,eLJ3Mz*~d +j/1dM.6$& Yk=HC"*Cîm`Lg['LQV\e躸5Y7z.n+%܃ 0dI M0d)88 +ʕeȀiAFTRqBڵkm-7; Y]tEPf̣3@(ogRx=z8_[WJj:y`2K`J !Kb-֩S9sRt=߿_| 0dOk) d@?Toӏ+;j͗1g`%!V > ܿ6mBsYmڴA9$V!g@F|ĉPIׯ lYR8y+eV| [ @]*x &NuϜ;=(J,En:<} !KAaLS1iӥ; xN(ijM(0jjϞ=gsxʔ)T`-5?DAFeʣx E0~BVJ`Ȳ+|ZT.!e!C0`YxN0dY8}5e,6Zfas6~.M(0jrb+}ƍ٠i 0d_ma6_ck!5pٱ1 DE,)woI,>m'OP^=ʕ˘[⼆yhڪ2`RF  :~XU1{Roh&O=y\8#`2_N8!`Z%J=ij'$$ϟǃوtT7)G":vx. 0d-_0nܸZ{*\,?YT@H2%eˆW 0dP̀[qCW!K1bSn{z"'kM|b`RL(ؑ{a nNeAXx+oF)C+ph4i1j d̜UNآU)eU`^,uO} 6{Ff?UPxy(X' S!+aYn,KGJ=V6jJUa˥C\ʲ]s+enť!KZ=ٚlX!k0zz(%l 0dY@t dȒPL6O*ZRl&r)%l 0dYpcȒXP6]է`WybX`Ȓ]b@YPd 6bp^XlLqaH,jW j6+XGf O :8:ov:`ȲθkmԷƌ<ZÐ&|pO<p(6u_8F+  Y2 ͢=a(YAA\eť!KzM5a122R, ޿[d֬q C,눳5Ѹ;aKfRgdzŢY9DU.}e틍r(%l |ǑP-:8X3 0d%@ퟣ#_YۏC,B,ZR!KKXf͚u0sE޽'w], Y<4CBӏ /hIR ___I`c)e^3Y U!*îA ,H ]R8o>Ӛl0dYS!D&!KEm#epjgΜS`ggRJL2q^>ԦeR[dW 5s&?x!S-njU,v@FLR䚡?Sql_x*x"XR,K}CS򼼼[=zt҇9} Y< xX\,YcׯpppOb(y aȒ9^RgȒJILrT@vߠCVl5Y??gϞ!s> :HCdRCvAߐdh#زU2gRV<, CŤI#TвBi0`̞=;F9˅*, Y* n2dɭ0ۏK,ZW@TX/^&Kq P6+fJZ[)cRJ$,C`3dYg{ &H('kذaq*>@z!ˢ+s,=aȲƨ[טMY.2#Y} Y͐ 0dYR} ч9R YZf+` ـ0ˬ88Đeݹo 0dLк s8I=>,U=,yװaC̙rk.,X9rg 2[eȒY`6oqLyoϞ=غu+nݺ%~lll*~6mڵk8S VC0 )O:)RH"3`]hԨƌʕ+q.aR^L#i0&;7nmbΜ9H*UCQ5C 0dRJgȒ'Q3Y[l/Ǝ+VÇhܸ1v{_E-p5f~',Xe˖ŗ/_p9EXϞ=KɊG`d!Kfb!KHYu*\<<<;wnY;wFǎ3\)SKebC<_>T2kQeҥqmÍ7YdȒU^gȒ'VBV1dN:`iY~N<"Eˎ Y Y\*="(kUD]O?E{ӧOH,Bp{5"G`fGǏmң3:uܶ D9mvL<Eᢅ0O?ФycIc!LTrvvƠApUPDEVHM2Ee I$Xp![l~@O'QQC"@l˅TYfMYɓ'qϔ)^|ΓkLYASO .R0{ Gڴi5E}3}%֨% biH&5:=tWD)]t|f'CO`MkW#UT8t- nzi+>!G߽2dtAӺ\m6pd٧~v'ĽѸyc-^>|xN+;}?,U(cbƔؽc>N@``fOŅ`ggˢppp߶ȿe cʨYKM)HnhVeTJԥKt4sCfBEpqqv׫W!C-QF;s{x!KyOvڰfYI'"yd9 VB߁A֟bDԮW ?,7]8 iҦ~ҥE!llݼ #Ah\ RJ{Ob].įm;# Sa8v8;=|eR?yK-+kΌٷ׮.`J\YG5h@,]wnE媕ĵ^!_|WO@g@/$IT?ay1adw׾_ppf9R\c\hش!W,/t2}YWS=NFۙjVK& 1d Hbk) `KiAzj0F_Ė-[ٳg߼\rEs>*U@{`ϡ] aU Qӆ޼y&uyf7/ eRok*aLY2LQNmEGh׼MٰzRo\_dh -q8\\G˅QktմE[b-[\?}&|%*nvrr5ja2ubm-Ff0x À^D\! opmP'ޓ Xx>} ҤM^۶72dIrm0d)764 ĕe'u4{lQŴmBSL4Ҋؑc";C˄CG .߇vl ӢAA AՁ?${쓮5+  )no?v(ԲmK,_7lOKi;Y:?l],c.YXp 7oŒ3#\z ba  y{Ǿ? ;5gl+Q,s _(؄az;"=-IcǎY _&d*FtɓG9MO72顗Ң oCbB!z BX/^C{ݖ5 kH/-;TjjV ;wUew.6MہN[Qdgjne\ط n62uOcUˆ5YL=iHKn}LVBnglO&gբW YZ*)i͛$ڶmĹfŒ( ;dQ6S`0$MTZQNL֮1eTԩ_[} d.[}T+\sYEE b(wQNٶ1ޣq]L* ѳdˊ#}Xڱ6Z҅2:ꄗ/^aT mh锖B?5Ys}xM5Y|HL 0dк,ҟQRL0#Gv1}e/L!7:~*^&{~chEeMl|ub.UBzn18w<5Z]>cqEONY{oQ"Z8w(M?ɫ}Nu?W&qX7W#(5j{F€EaݺuhѢx"#_|}9!bbŤM%lK e}]D%6Uq,Yb}(Q':z/ߨתEZ_I1YE9tPÇE6*?qAXQJ ş)~sȨUcE4H\ظqcqNng(DEGolڴI(3EiMdO:^/-}Nf qJ1Pm(] 4h`8`!v6l_.F+ h&MD5:mseԫWOl@,ӧ:T-ѷ^%*D'-ҒݻEJ@DuS=/n)S&T3F5_t?G_TOK9GW\)jCƐ%l[I P$}.޽+6閲ї-.`Ȳ| 5C-7>u2TMeʔY:zFzTLN8ҤVҥѭ[7gv xh~i4R W#>}ZL@ˇGRtKd@tm=Ar%&(#G5`r6,9e۬+`),fRX(, ;м Yqd2N'Jѕe`Ȳ!K1JG2 !8*y`ȒGW U!˲+w,ń*aȲʰY+7@,tQ!K]*+ XV,ꯘ t!*΃f4CClӉG,yte+`Y,bzgRL(, ;м Yqd2N'Jѕe`Ȳ!K1JG2 !8*y`ȒGW U!˲+w,ń*aȲʰ[Ir +Vb!Jmhj,CcQ ɧOpyNt>ndv}<% IDATǜ$džX){ *WF֎q~_x(T4+ymOOظAR)]f[T!+i6CVxn88"YH'O"HvK!Km3zVЭ[ppuEŋ(YX3vlEXeRƜbRF,CCh>}UD)+O~$ɛM EŐeٹS |XƀE]>M^W5T*9]`ɊDѓ|PfP.`Jx|, L,-YB Y O;73di'r$uDĉ?vvvH$ zi!E y * e/vHM 5|2dɧ-[6MV|!A˴yѐ%l| ,?zm"[ )K6=q|qOR c//_P.\f.]CCHT#LN1 0d%\CYhU ϝ>2 .n.4οO'?y4h9֨g^!ˢsVB2Y Zʘ YʈY s—/_D)ѡK mV?3u*ȁ!r_ KŠR f&i쏦9z,9eۆ2LH>C+m`˜C.ȕUHȚ-"}fn'UDߍ}:k?vEkP1;ΐevɹd1hYvj2dYVީEM}~ș[aڷ  B0{lD7V PYgA _>ȇ8$N!uoḳ&Cyt^+ 5`I YdKxĭCϐ<.v(X7K_rx)q2X F-%!Kو\Š%TgȒO[|L3Hlf:jLdՌ0(f(|\ DF±a L[ 2̐ X0gK\1 dcz8>聨ZXF @âV\2!Ӓ`_:xK7Ƣ@DH([rG zbh?[{{ǩY k_8rtt߂pjRà{[[; ƛLU7FÇՎf,_ѣHSTh FԲ%zz&؞5`Ȳ<qIn(sol^+ |\>__`QՃE YZ GLrF_I *G,EG=XlfJQf Ux+@ES|صKbR ܪ2d-_ 2*%l 9Ե@aS Y[+P <ׅ%K J`2ضqlu}=XVTo'|yi!uHQJ1dU1ܸqٳgOJBZ/_>Ȏ(G,dδqXxx IK㗁J$^?[Q Ru&&iUbR °aðpB|5É%B޽1qD888(0 u0d>5 O!޸vIVryr#^7ƫ$]yf$ߌCcԩSq:?㰱Q;YP|aȒujqcyYϛ^<[Q|dH?v*RSdt!Kcpww7Yf (4z CF'upN[gfvx DD|eQ+g2s_L8_oV=}$H`+_"f;S7n FPlw;SӣGrѦKo޼6zzݻw׎9J*YB<̨ }0d|Vfc!ID* |ſΝMpF.wwڲX Q@4"ոe5SUݺq-:x73FLEdD9EʖE͛_tji7]OӡӔʜ5copG|}(v-R+|KBP̈́7M,W+XDA^F`O5iOϟ|x4`k#F '>_~ kO:xz`"of36#Ӧ֘1 EJ31f PM $`&(eBRu) 63ݷKV՚<{  "5m*mSuZ\ ɍY4(_(j/ YL6"}UV]lMQ}|:2YQDPNj~(@L2d~*?S*e½S3gn.)!eƁܐӫ]p}{Q,S&]V{Vk_46p C&wk ,zͭ%!JE:tÇ0LsVєV fH,CC" ,1Hܛ:U_T(_|d 6 SNYfؼywA޼y ӧOH,x-88cvmɓGO&Mm6ɓ'kQN͏I!KSXdFc" _(B6u %C~Gpt>>>:tb\p޽h=H!!!׺w w˖-ӿGE?gΜxӧcРAMK,s$'A 0d%H>߬$"Z ȲeH>⵴+W/ N_i9vX7.ڻK.EΝsǜ9s~z⽲eˢm۶ݻ]x1~+j~ƌGɫ1di%1Cہ7o\&ы ll G{Pv"44T'dQe$ItݻwQhhD/*U*=˕ Cf Yڞj,enf W*U3gvLS{Ԗ/_>Sg-Zm͚5 73\ hu0d)qOQ!KۓBMCD9;ؚ5pgd􉌌괙dF*Z>|8%J &MoooG ?V4:,+j*Cgw5B׻wAf OwiV@WӃK˗/3@z}ݺu.-ùss/-E9s3fԦpV:*-,+jZ!aÆr1ڵk ,9rsQ+d|8w(>Gw8D7C2ZTSSsrrBڴi>}zqw@5:t{Lv?x=6_7G59"B֩S@;V)RD#zD\liXEPQ<p8a۷h߾=ۗiTN^iҤIY hi0d){w*VȊڲe |}}E=ʊ+4n]vǎ믢6V|J*QFzG.4zhp֦MCuF EGưaTeˢ\Os600Ф9 &ĸIbU))gjo.M;uUVʕ+#A7}z } c,uV̝;WXl+yhtSQ(/p!2j76T([/.2MKuHQH }0d)bdQ&jժؿ?Ə/~(+E0E-M]6zL=6Ȣoz􇊞B]dqXдp??\l^_eK[;wOV'T`b~GmZU=hn6_=Cx)%Ȣ#Ν[@ݱcGKK YM_@+Wj߾ BLarL~ 2dm3bÎĥ@V1d|`,z}bmrѲ#gb5J,0kTG@^Q oMm4=^ Cg oYT;h \zT(߫W/j 8> z}}Zj5n㠵&5Ɲ8-*zH3Q^?ZZƥe~Z dV ttÇEM e@jʔ)ˊ-\Tگ_?<}TիYdb)o\Ӧ|}_2UMΆ⥀ CV7[B:=~X=IաCcouY4*ң^l(b^=q,5ū폦f>t* CJ'm-ݚblm~.],tUZS'6ӍvZ: | CaU(0Ik,/kO669`OEM|#+ $Y|k,}dDxyE+/~=gTCg=3di;YRQDdɐ9z.n+>3!Kag|:-]Q|*UP|$M^ۓG hP, UC2d鎺I4)v܉ɓQr)M}K,ѣGώ(WZ!kqُ-n'ik:D:>MwnnؐKE$IE-Krm 0dI,(GsAֈ#7n`ԨQA] -Zu֡Eȓ'.^={}hCQ]˾sVbQ=Jk Y1GbO-Q {n(8{XJ W!K1bаaC(ooo k(Segg'?t35C2OV/5o\dtPFĉD˖-Ѯ];t kcc#Sdx]&… ?>>>0a$2RLe2f̨ WT ͚5C۶mДv&j'{ ,(@x4%{\3!8e#p}`<^X@Ei̙3GSZkj/ YV5-;X!KM+ ガ7z ǏӋZ-cl]Vܻ`(P@,r AM@Eˁtv!0OlCzh"[;`:*d?+Vۏ;- 'N}:yLծ]ؾ(svG(^-4M_-j/ Yr+rC-M8>C  X-Y9˗/6F;:tH@!iӦ3Yt8A˅7Ft(Dl2lڴ ...2Y"&2U'HMY/>mmmd"i<7ƐeTC;|XLEON另բj/ YZ}ܐ5l0\~]UDgΜ~ɐ SkҤI4uOOO\||H|t-5@MTH}O$M"-Wl8N2rT&gcJTMݺ"&J62a=Zhʯ`j/ YDrBeZq%SwqXI2{j054ŧ*[VdRٍ̩t*B'2_1] C 0dRH3dI?*ܹ3>} )PdRdnJ$lD"[Nb; j1Ѥ}X[{{diNلP|aR㌳Bt,i .n/Բ% /\ K` d;sgܛ~nᅦSfi̖IfIBe2bP dY&h_ߋfw̟VBz4DN-ĘԱ2X̀,mJeOeEGGvvYӀN cƤ3jJ6p0'`Iz2{91@A&˺u@e?O z(޵LT fA7 nVl,biFr$dYl*r,^n,ӯ8O Uv$Spiq6 gǎbiAǰdYlb4Yֽ4Y汾ˑS[WP|Bt4~CS䛏Hu,E/4YԱE&ӈswGlxb?nx2}'ŋ q\|򏧣#=XbFrTYK Mifwnr}˗G͚5[oql5&Fi! ʖSp*UmhpReC.%JJk"Ϟ=#_|$^s(݌ 88XpN֤,(gEH%:'nݹ7t#wLydK?xQfhx;,ZlnܸƍDYޟ "Ÿeh׮]V-&pI@k)Y\\i7ϝy?\?e8MːP|QyZ(R$>|QFC(]9sϛ"}RGW^Ō3"\늉Iзo_xzzkkd֬,#ݓ5Hv'`YM&˸ˑP|֭Qadsuŕ+Wnݺ74ϟ?-[ҌzY^h {"&pqcsIIp jB,dġ3G̸q@b"ġsb֮]2M5|pp<øqZ/4Y E$`+>u*^ pKk$޿'t|L&K%w/l)+şQm7l0j0´9pڴicРIIIԩ֬Y#o~˗zA+bF,ꉽm0q&K;͙3+W6sձcGjLNNƬYtRCO DBe$![ C,'xOoN?vXɕO?D+z Wڟ9wF(_d,/ 0gn`p0{gg>fiXİ[3DXZCCVBddʖ-għqmۆ;wFz,wB1iz1< [3YԋKm Be8?$P@RN5Ό+}XI\l..j~mFOو7LVͱc9 U֭lْj Ym{6dhRBL3lM$` LSW+4LK7fQTj9udiV%PuCR[ M:a/$@Z` 2Y"Wweɓ8mmhj+zRO3H@cww֭_ҀpWq31M0 777͡JSa҈6F&K];O@Z/4Yj hLC݁dEa f݃Rίo[Ngz|,u>ZQ8ܢ~PE+d(HL d>\FyX6YbB}[[wJu4o|? a'xt&KWR9o!GB(>,gzR@$`&Ҿ}X1T۶>L6ZF!! )Љ3K̋&K/mgCԨapnzR&03NE,Jӄ{LGv!?Ĉjai _cL@r2wmr>Ck MaK s%a+J `}r5bň:X[6oDyЦYuM>^ܛT^98̯P݇vdmz_3lA$`!>|yLaD/B;?z"-[6U$Eǎ"6>?0Nʊwꇘ=<ղ~ךBfx7 x)}rۇ6>4JL䩫8pǣ. |Y+'..ą P 5^4 oȋv(V.MEm"a |Qmt,{A/4Yz-9o&HLe3Jܥ{|c#::V[sg>,eK{$;,62T/[aHNHDPq(dsQVZRBLlM$`Al=}hCӂPizIJHcque@) B M ȡHLO }oTi͌By.;FnQm]/4YH,u}hfqp+\ sτ|=[)T=:Ç1(R!⻙йCSٝ؍R~ވܿZgxt1Jsj]'O_Dـg/gm3ٵfȿ nͿd^nl؅GR`T I&@ u.׭jRR4[Pʻ(Dw*nȦ)ZC?SS9 {]ڍcQtJ,"omعq6[N#>>MlZvӅ ~M_d=g^|wD7KF,cS !`#C&K_MJY,{i Xu9wkO='N]_V݈oe*UGL`Mğ@*吧X]w{w-Dܽ N%!6: m΢;YH0Y)~e [~=.GmshԢPQ7W~P+L9>WJVl|Ozzr'+!!񥝬D.#h UH/{2F0 ڪ^h  X'kN*5YZ CO \ֈ:y~Y P'O<9#Ot3. Ge_}|Csهء&CQn u1YRbKK̞R&[1Y7֮őԨap ɲEI!MzC܄ GRxg *#h[ilk9[ Xh&Kd%PVO˞-BLE'@?3  T>R&^k5YϝÁƍ{4Gmې+ ԋr2lM$`^IN={%>4-5;v`H{Ŋ`9.,AQ/B![ `!C>4LօS5hB-Z288;B^&KC& IZCsș8u Z3d%=;ʕq(9ŧ^ԋ29L2~lM$@0!k &>x9s5xQ P/,e ٚH^%`CK}h&$$ [l*;Y`=_x{֭p+S&ft'wck x-s{MsWaqʿ(F^hR#tWllF-xYsvvv|h2W~'(<>&` | ⛅Ӗ2]bCpdw}QEhck Ȓ@aٰ0+vƸ͡fcEpwωơ'ԯ3唂ۅ |/R,֪Ӈk2pmTRnܖfо,_4lNy/de$2'M7x0y+zɊ&K?& KhWF6WWګt1GP@<,]i7'Bzn#Ӹ=Qd1S̈́~c,9pʿ҈EX''GܹK"!!kND>q- 4,pwm&EgTH[ ^L>4C{ШECMRR4dKVnEQ7[ɚ:?(iYpqyQj[qvQ8MV:ڢ@ĝ?RQ}KC{ick Л@#&O,}ḣHt0?ev C4y \tMJ\~ވZl"ԓl+$͛0q)WJ]Q}KC&K-& (}ḣ"U?I靽2'.F|w7WkSݜ)S.\ed6 Cud?=Z]俧k4_;Yi8" fT`T S/ТRFIH@eZg4D||Rv?~b~囂߇O`XG"VH-?uwçT1:^,LVZu=i$sY2-՗o*oټz()̖zQO|("![ "Z )Vȷ ՕosG}{v,YRԋ24Y5 JCc?4Uaɺbar|}hd)$@$#T`Շ-,eؚH4&vMe hjFQ}P/ТRFIHLlMin#bbQ n…M(ԋ2<[ 62HVZ=<MprLֹPKY`H6h_{5E(K[ Ҧ==QuVxTs |h*6YOHw:yĉ8P$hM+[ick М+IP/tM0ez&K=jQ}P/z^,eؚHLC!ʖK+e^E[ 7}(mZYY6vQ}^vrHLF@IdAsW $%!j\6MA(;aF^[4Yh$@$>>5 gƌoh}~`Q<-qwn;9óm[]3'@e HH@W""piS}B@=Ԫ ! IDAT?Fr*P@ىy2u`$@$ciΎSÆi^`Haɢ4HHJ 0}h~ RQF/PF ,U0 0OLϺCQad:s$@LC{x)x{ۑdIK&˸|; MW-±.] ? iᨚ7# `P;TE뇋3gAK ;;H&%@eRHL@CCFEz˖p˖F,ZFC$@H> ظ*Wl|kFueM؂HKeI}f~ZOF&nd0: 0>Ua,yz 9EڴAE`J2 dY1j PӇ!M?ƭ͛q70V׊&ꖔ"  0}'WbÆB\PyZ__NxɲڥHH@LN=j۷åxq& @eY >Y׬A6WWuɲHH@W҇'«_?E}ZrcQ`4/pi9Cw8E5b4YFˮIH*0}(FB͚N&KSH,-EF@xr2 Bmo5!@ fB$@AӇ77m%<3jN% (?> Z5%,ce$@$`9}h)SP/|E9= dM H>0[4FŇ֮msb!@eH@aޓϳ{xXY`̬2ap$@$`9,=}xi\Dxh,0j93Hiue X KL&%$X.x$^jP3F-P2M! + pjpF@@Vlgug.<س9rnlce`E&˲֋ђ /8ت3==QmWh2@!@e9kHIH󑜔d١x^p̛lcd`I&2׍Q 9,3_ G$@$@$`h,s5 2bx$@$@$@I&2׍Q 9,3_ G$@$@$`h,s5 2bx$@$@$@IۜIENDB`signal-estimator-0.0.9/doc/example_sync_streaming.drawio000066400000000000000000000625531452044147100235330ustar00rootroot00000000000000 signal-estimator-0.0.9/doc/example_sync_streaming.drawio.png000066400000000000000000003324711452044147100243150ustar00rootroot00000000000000PNG  IHDRHpsRGBtEXtmxfile%3Cmxfile%20host%3D%22Electron%22%20modified%3D%222023-10-25T11%3A46%3A31.285Z%22%20agent%3D%22Mozilla%2F5.0%20(X11%3B%20Linux%20x86_64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20draw.io%2F22.0.2%20Chrome%2F114.0.5735.289%20Electron%2F25.8.4%20Safari%2F537.36%22%20etag%3D%22umHluXf-SZiS2GuLZrPc%22%20version%3D%2222.0.2%22%20type%3D%22device%22%3E%0A%20%20%3Cdiagram%20name%3D%22Page-1%22%20id%3D%22dlh2HGEMS9u2Ikbi2MeV%22%3E%0A%20%20%20%20%3CmxGraphModel%20dx%3D%221242%22%20dy%3D%221965%22%20grid%3D%221%22%20gridSize%3D%2210%22%20guides%3D%221%22%20tooltips%3D%221%22%20connect%3D%221%22%20arrows%3D%221%22%20fold%3D%221%22%20page%3D%221%22%20pageScale%3D%221%22%20pageWidth%3D%22850%22%20pageHeight%3D%221100%22%20math%3D%220%22%20shadow%3D%220%22%3E%0A%20%20%20%20%20%20%3Croot%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%220%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%221%22%20parent%3D%220%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-1%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22100%22%20y%3D%22210%22%20width%3D%22310%22%20height%3D%22280%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-4%22%20value%3D%22signal-estimator%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23F7FFF5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22110%22%20y%3D%22325%22%20width%3D%22120%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-5%22%20value%3D%22output%26lt%3Bbr%26gt%3BALSA%20device%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22270%22%20y%3D%22240%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-6%22%20value%3D%22input%26lt%3Bbr%26gt%3BALSA%20device%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22270%22%20y%3D%22330%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-8%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3B%22%20parent%3D%221%22%20source%3D%22jdgYiCKV-6AsK4i46VtF-4%22%20target%3D%22jdgYiCKV-6AsK4i46VtF-5%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22240%22%20y%3D%22220%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22290%22%20y%3D%22170%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-11%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3B%22%20parent%3D%221%22%20source%3D%22jdgYiCKV-6AsK4i46VtF-6%22%20target%3D%22jdgYiCKV-6AsK4i46VtF-4%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22240%22%20y%3D%22220%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22290%22%20y%3D%22170%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22jdgYiCKV-6AsK4i46VtF-12%22%20value%3D%22PC%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22110%22%20y%3D%22230%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-30%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23fff2cc%3BstrokeColor%3D%23d6b656%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22480%22%20y%3D%22430%22%20width%3D%2280%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-31%22%20value%3D%22%22%20style%3D%22ellipse%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Baspect%3Dfixed%3BfillColor%3D%23f5f5f5%3BfontColor%3D%23333333%3BstrokeColor%3D%23666666%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22500%22%20y%3D%22410%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-32%22%20value%3D%22sound%26lt%3Bbr%26gt%3Bcard%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22480%22%20y%3D%22450%22%20width%3D%2280%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-37%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23fff2cc%3BstrokeColor%3D%23d6b656%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22660%22%20y%3D%22430%22%20width%3D%2280%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-38%22%20value%3D%22%22%20style%3D%22ellipse%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Baspect%3Dfixed%3BfillColor%3D%23f5f5f5%3BfontColor%3D%23333333%3BstrokeColor%3D%23666666%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22680%22%20y%3D%22410%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-39%22%20value%3D%22sound%26lt%3Bbr%26gt%3Bcard%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22660%22%20y%3D%22450%22%20width%3D%2280%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-43%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20parent%3D%221%22%20source%3D%22QFHJZdolUIHKQ8WvCYE6-33%22%20target%3D%22H8G9I3JoE38qBTgvnNji-31%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22520%22%20y%3D%22450%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22530%22%20y%3D%22335%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-44%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20parent%3D%221%22%20source%3D%22QFHJZdolUIHKQ8WvCYE6-44%22%20target%3D%22H8G9I3JoE38qBTgvnNji-38%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22700%22%20y%3D%22450%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22560%22%20y%3D%22480%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-46%22%20value%3D%22input%26lt%3Bbr%26gt%3BALSA%20device%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22270%22%20y%3D%22420%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-47%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3B%22%20parent%3D%221%22%20source%3D%22H8G9I3JoE38qBTgvnNji-46%22%20target%3D%22jdgYiCKV-6AsK4i46VtF-4%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22280%22%20y%3D%22365%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22240%22%20y%3D%22365%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-53%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20parent%3D%221%22%20source%3D%22H8G9I3JoE38qBTgvnNji-31%22%20target%3D%22jdgYiCKV-6AsK4i46VtF-6%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22400%22%20y%3D%22278%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22580%22%20y%3D%22289%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-54%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3Brounded%3D0%3B%22%20parent%3D%221%22%20source%3D%22H8G9I3JoE38qBTgvnNji-38%22%20target%3D%22H8G9I3JoE38qBTgvnNji-46%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22514%22%20y%3D%22488%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22375%22%20y%3D%22390%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22590%22%20y%3D%22520%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22520%22%20y%3D%22520%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FArray%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-57%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik00ODAtNDAwcS01MCAwLTg1LTM1dC0zNS04NXYtMjQwcTAtNTAgMzUtODV0ODUtMzVxNTAgMCA4NSAzNXQzNSA4NXYyNDBxMCA1MC0zNSA4NXQtODUgMzVabTAtMjQwWm0tNDAgNTIwdi0xMjNxLTEwNC0xNC0xNzItOTN0LTY4LTE4NGg4MHEwIDgzIDU4LjUgMTQxLjVUNDgwLTMyMHE4MyAwIDE0MS41LTU4LjVUNjgwLTUyMGg4MHEwIDEwNS02OCAxODR0LTE3MiA5M3YxMjNoLTgwWm00MC0zNjBxMTcgMCAyOC41LTExLjVUNTIwLTUyMHYtMjQwcTAtMTctMTEuNS0yOC41VDQ4MC04MDBxLTE3IDAtMjguNSAxMS41VDQ0MC03NjB2MjQwcTAgMTcgMTEuNSAyOC41VDQ4MC00ODBaIi8%2BPC9zdmc%2B%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22510%22%20y%3D%22420%22%20width%3D%2220%22%20height%3D%2220%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22H8G9I3JoE38qBTgvnNji-58%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik00ODAtNDAwcS01MCAwLTg1LTM1dC0zNS04NXYtMjQwcTAtNTAgMzUtODV0ODUtMzVxNTAgMCA4NSAzNXQzNSA4NXYyNDBxMCA1MC0zNSA4NXQtODUgMzVabTAtMjQwWm0tNDAgNTIwdi0xMjNxLTEwNC0xNC0xNzItOTN0LTY4LTE4NGg4MHEwIDgzIDU4LjUgMTQxLjVUNDgwLTMyMHE4MyAwIDE0MS41LTU4LjVUNjgwLTUyMGg4MHEwIDEwNS02OCAxODR0LTE3MiA5M3YxMjNoLTgwWm00MC0zNjBxMTcgMCAyOC41LTExLjVUNTIwLTUyMHYtMjQwcTAtMTctMTEuNS0yOC41VDQ4MC04MDBxLTE3IDAtMjguNSAxMS41VDQ0MC03NjB2MjQwcTAgMTcgMTEuNSAyOC41VDQ4MC00ODBaIi8%2BPC9zdmc%2B%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22690%22%20y%3D%22420%22%20width%3D%2220%22%20height%3D%2220%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-8%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22350%22%20y%3D%22-115%22%20width%3D%22330%22%20height%3D%22110%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-9%22%20value%3D%22input%26lt%3Bbr%26gt%3BALSA%20device%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22370%22%20y%3D%22-75%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-10%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BstrokeWidth%3D2%3BstrokeColor%3D%23CF0000%3B%22%20parent%3D%221%22%20source%3D%22QFHJZdolUIHKQ8WvCYE6-9%22%20target%3D%22QFHJZdolUIHKQ8WvCYE6-22%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22370%22%20y%3D%22-95%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22410%22%20y%3D%22-11%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-21%22%20value%3D%22jack%26lt%3Bbr%26gt%3Bcable%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22520%22%20y%3D%22385%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-22%22%20value%3D%22network%26lt%3Bbr%26gt%3Bsender%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22540%22%20y%3D%22-75%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-23%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22440%22%20y%3D%22100%22%20width%3D%22160%22%20height%3D%22190%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-24%22%20value%3D%22output%26lt%3Bbr%26gt%3BALSA%20device%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22460%22%20y%3D%22220%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-25%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BstrokeWidth%3D2%3BstrokeColor%3D%23CF0000%3B%22%20parent%3D%221%22%20source%3D%22QFHJZdolUIHKQ8WvCYE6-27%22%20target%3D%22QFHJZdolUIHKQ8WvCYE6-24%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22540%22%20y%3D%22330%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22450%22%20y%3D%22204%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-26%22%20value%3D%22DUT%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22480%22%20y%3D%22100%22%20width%3D%2250%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-27%22%20value%3D%22network%26lt%3Bbr%26gt%3Breceiver%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22460%22%20y%3D%22140%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-32%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23fff2cc%3BstrokeColor%3D%23d6b656%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22460%22%20y%3D%22310%22%20width%3D%22100%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-33%22%20value%3D%22%22%20style%3D%22ellipse%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Baspect%3Dfixed%3BfillColor%3D%23f5f5f5%3BfontColor%3D%23333333%3BstrokeColor%3D%23666666%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22500%22%20y%3D%22345%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-34%22%20value%3D%22sound%26lt%3Bbr%26gt%3Bcard%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22450%22%20y%3D%22315%22%20width%3D%2280%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-35%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20parent%3D%221%22%20target%3D%22QFHJZdolUIHKQ8WvCYE6-33%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22520%22%20y%3D%22270%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22380%22%20y%3D%22300%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-37%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik0zNjAtMTIwSDIwMHEtMzMgMC01Ni41LTIzLjVUMTIwLTIwMHYtMjgwcTAtNzUgMjguNS0xNDAuNXQ3Ny0xMTRxNDguNS00OC41IDExNC03N1Q0ODAtODQwcTc1IDAgMTQwLjUgMjguNXQxMTQgNzdxNDguNSA0OC41IDc3IDExNFQ4NDAtNDgwdjI4MHEwIDMzLTIzLjUgNTYuNVQ3NjAtMTIwSDYwMHYtMzIwaDE2MHYtNDBxMC0xMTctODEuNS0xOTguNVQ0ODAtNzYwcS0xMTcgMC0xOTguNSA4MS41VDIwMC00ODB2NDBoMTYwdjMyMFptLTgwLTI0MGgtODB2MTYwaDgwdi0xNjBabTQwMCAwdjE2MGg4MHYtMTYwaC04MFptLTQwMCAwaC04MCA4MFptNDAwIDBoODAtODBaIi8%2BPC9zdmc%2B%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22510%22%20y%3D%22355%22%20width%3D%2220%22%20height%3D%2220%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-38%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22620%22%20y%3D%22100%22%20width%3D%22160%22%20height%3D%22190%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-39%22%20value%3D%22output%26lt%3Bbr%26gt%3BALSA%20device%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22640%22%20y%3D%22220%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-40%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BstrokeWidth%3D2%3BstrokeColor%3D%23CF0000%3B%22%20parent%3D%221%22%20source%3D%22QFHJZdolUIHKQ8WvCYE6-42%22%20target%3D%22QFHJZdolUIHKQ8WvCYE6-39%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22720%22%20y%3D%22330%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22630%22%20y%3D%22204%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-42%22%20value%3D%22network%26lt%3Bbr%26gt%3Breceiver%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23f5f5f5%3BstrokeColor%3D%23666666%3BfontColor%3D%23333333%3BfontStyle%3D1%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22640%22%20y%3D%22140%22%20width%3D%22120%22%20height%3D%2250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-43%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23fff2cc%3BstrokeColor%3D%23d6b656%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22640%22%20y%3D%22310%22%20width%3D%22100%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-44%22%20value%3D%22%22%20style%3D%22ellipse%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Baspect%3Dfixed%3BfillColor%3D%23f5f5f5%3BfontColor%3D%23333333%3BstrokeColor%3D%23666666%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22680%22%20y%3D%22345%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-45%22%20value%3D%22sound%26lt%3Bbr%26gt%3Bcard%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22630%22%20y%3D%22315%22%20width%3D%2280%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-46%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20parent%3D%221%22%20target%3D%22QFHJZdolUIHKQ8WvCYE6-44%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22700%22%20y%3D%22270%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22560%22%20y%3D%22300%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-47%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik0zNjAtMTIwSDIwMHEtMzMgMC01Ni41LTIzLjVUMTIwLTIwMHYtMjgwcTAtNzUgMjguNS0xNDAuNXQ3Ny0xMTRxNDguNS00OC41IDExNC03N1Q0ODAtODQwcTc1IDAgMTQwLjUgMjguNXQxMTQgNzdxNDguNSA0OC41IDc3IDExNFQ4NDAtNDgwdjI4MHEwIDMzLTIzLjUgNTYuNVQ3NjAtMTIwSDYwMHYtMzIwaDE2MHYtNDBxMC0xMTctODEuNS0xOTguNVQ0ODAtNzYwcS0xMTcgMC0xOTguNSA4MS41VDIwMC00ODB2NDBoMTYwdjMyMFptLTgwLTI0MGgtODB2MTYwaDgwdi0xNjBabTQwMCAwdjE2MGg4MHYtMTYwaC04MFptLTQwMCAwaC04MCA4MFptNDAwIDBoODAtODBaIi8%2BPC9zdmc%2B%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22690%22%20y%3D%22355%22%20width%3D%2220%22%20height%3D%2220%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-49%22%20value%3D%22jack%26lt%3Bbr%26gt%3Bcable%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22700%22%20y%3D%22385%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-53%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23fff2cc%3BstrokeColor%3D%23d6b656%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22270%22%20y%3D%22130%22%20width%3D%22100%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-54%22%20value%3D%22%22%20style%3D%22ellipse%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Baspect%3Dfixed%3BfillColor%3D%23f5f5f5%3BfontColor%3D%23333333%3BstrokeColor%3D%23666666%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22310%22%20y%3D%22110%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-55%22%20value%3D%22sound%26lt%3Bbr%26gt%3Bcard%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22260%22%20y%3D%22150%22%20width%3D%2280%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-56%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik0zNjAtMTIwSDIwMHEtMzMgMC01Ni41LTIzLjVUMTIwLTIwMHYtMjgwcTAtNzUgMjguNS0xNDAuNXQ3Ny0xMTRxNDguNS00OC41IDExNC03N1Q0ODAtODQwcTc1IDAgMTQwLjUgMjguNXQxMTQgNzdxNDguNSA0OC41IDc3IDExNFQ4NDAtNDgwdjI4MHEwIDMzLTIzLjUgNTYuNVQ3NjAtMTIwSDYwMHYtMzIwaDE2MHYtNDBxMC0xMTctODEuNS0xOTguNVQ0ODAtNzYwcS0xMTcgMC0xOTguNSA4MS41VDIwMC00ODB2NDBoMTYwdjMyMFptLTgwLTI0MGgtODB2MTYwaDgwdi0xNjBabTQwMCAwdjE2MGg4MHYtMTYwaC04MFptLTQwMCAwaC04MCA4MFptNDAwIDBoODAtODBaIi8%2BPC9zdmc%2B%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22320%22%20y%3D%22120%22%20width%3D%2220%22%20height%3D%2220%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-19%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20parent%3D%221%22%20source%3D%22jdgYiCKV-6AsK4i46VtF-5%22%20target%3D%22QFHJZdolUIHKQ8WvCYE6-54%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%2250%22%20y%3D%22-40%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%2260%22%20y%3D%22-140%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-65%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23fff2cc%3BstrokeColor%3D%23d6b656%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22270%22%20y%3D%2210%22%20width%3D%22100%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-66%22%20value%3D%22%22%20style%3D%22ellipse%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Baspect%3Dfixed%3BfillColor%3D%23f5f5f5%3BfontColor%3D%23333333%3BstrokeColor%3D%23666666%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22310%22%20y%3D%2245%22%20width%3D%2240%22%20height%3D%2240%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-67%22%20value%3D%22sound%26lt%3Bbr%26gt%3Bcard%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22260%22%20y%3D%2215%22%20width%3D%2280%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-69%22%20value%3D%22%22%20style%3D%22shape%3Dimage%3BverticalLabelPosition%3Dbottom%3BlabelBackgroundColor%3Ddefault%3BverticalAlign%3Dtop%3Baspect%3Dfixed%3BimageAspect%3D0%3Bimage%3Ddata%3Aimage%2Fsvg%2Bxml%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgdmlld0JveD0iMCAtOTYwIDk2MCA5NjAiIGhlaWdodD0iMjQiPjxwYXRoIGQ9Ik00ODAtNDAwcS01MCAwLTg1LTM1dC0zNS04NXYtMjQwcTAtNTAgMzUtODV0ODUtMzVxNTAgMCA4NSAzNXQzNSA4NXYyNDBxMCA1MC0zNSA4NXQtODUgMzVabTAtMjQwWm0tNDAgNTIwdi0xMjNxLTEwNC0xNC0xNzItOTN0LTY4LTE4NGg4MHEwIDgzIDU4LjUgMTQxLjVUNDgwLTMyMHE4MyAwIDE0MS41LTU4LjVUNjgwLTUyMGg4MHEwIDEwNS02OCAxODR0LTE3MiA5M3YxMjNoLTgwWm00MC0zNjBxMTcgMCAyOC41LTExLjVUNTIwLTUyMHYtMjQwcTAtMTctMTEuNS0yOC41VDQ4MC04MDBxLTE3IDAtMjguNSAxMS41VDQ0MC03NjB2MjQwcTAgMTcgMTEuNSAyOC41VDQ4MC00ODBaIi8%2BPC9zdmc%2B%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22320%22%20y%3D%2255%22%20width%3D%2220%22%20height%3D%2220%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-70%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20parent%3D%221%22%20source%3D%22QFHJZdolUIHKQ8WvCYE6-54%22%20target%3D%22QFHJZdolUIHKQ8WvCYE6-66%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22340%22%20y%3D%22250%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22340%22%20y%3D%22160%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-71%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20parent%3D%221%22%20source%3D%22QFHJZdolUIHKQ8WvCYE6-66%22%20target%3D%22QFHJZdolUIHKQ8WvCYE6-9%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22220%22%20y%3D%2220%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22340%22%20y%3D%2295%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-72%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20parent%3D%221%22%20source%3D%22QFHJZdolUIHKQ8WvCYE6-22%22%20target%3D%22QFHJZdolUIHKQ8WvCYE6-27%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22340%22%20y%3D%2255%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22340%22%20y%3D%22-15%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-73%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfillColor%3D%23e51400%3BstrokeColor%3D%23B20000%3BstrokeWidth%3D2%3B%22%20parent%3D%221%22%20source%3D%22QFHJZdolUIHKQ8WvCYE6-22%22%20target%3D%22QFHJZdolUIHKQ8WvCYE6-42%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22495%22%20y%3D%22-15%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22525%22%20y%3D%22150%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-74%22%20value%3D%22DUT%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22680%22%20y%3D%22100%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-75%22%20value%3D%22jack%26lt%3Bbr%26gt%3Bcable%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22330%22%20y%3D%2285%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22QFHJZdolUIHKQ8WvCYE6-76%22%20value%3D%22Ethernet%26lt%3Bbr%26gt%3Bor%20Wi-Fi%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22570%22%20y%3D%2225%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%222s0VxUsEmC20woC3r4OB-1%22%20value%3D%22DUT%20%26lt%3Bfont%20style%3D%26quot%3Bfont-size%3A%2011px%3B%20font-weight%3A%20normal%3B%26quot%3B%26gt%3B(Device%20Under%20Test)%26lt%3B%2Ffont%26gt%3B%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontStyle%3D1%3BfontSize%3D16%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22450%22%20y%3D%22-115%22%20width%3D%22140%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%3C%2Froot%3E%0A%20%20%20%20%3C%2FmxGraphModel%3E%0A%20%20%3C%2Fdiagram%3E%0A%3C%2Fmxfile%3E%0A8O IDATx^tTIӆxB ܂;]w .,/,,!xMĈ'_dzf{N[]TNuwŗ/_/&L@YGM9& TamH"`"UI6LDjV!0.NEqcm,R T`eL  &Tń=b H 2&`bX*/,R H'"U:R6`HU^L#& TH `&FE"Uy1at,R#eL  (Tń=b H 2&`bX*/,R H'"U:R6`HU^L#& THwT*=Np˞UkEN="sϧXɲXW]fˉ|f5qx}mڪ=&\*?l TEEb1XJG*`l VV xA MhK:OG~HdV0ɥ 1S "UyQdGL@:ґJ3#1~>tj]Ge*Te*<b_`"Uy1at,R#f0>JT*Ok5pAEaccLY0WdH-vA+1ұUm:y=^]ZBhԼmck/;71vDz.#&7^6z12dK5JxǤmKwH;{{ ɝR$yQXʲ"UILErHq5: 'CM߹u #tǦ='gFk+-$@>{}Ajx6e J04kycLWlXE,Tת-WՋ=?˗a H5,Ĵ"51&r,RDjzq)Q,Ja+ר5NGQR8->A2aU ~0|,)^Zmhߵ/ϙcg {N _#""CLU hU0N]Y bB"FUQt{ׯ\4l3.a9+rmD&5$$}3u4޾~[7`ܴE_w)Hwo_D??Lt<ѫS ː OBPD>|ΩR+wКg,RXʋ {`*4Tܕ+E~&KA9iy$h3U+KjXۍS$Ω~(RR2`ߧ{z١ӯF5Jbp^| CLՊ?$z>ǂgmZ&^زM8r/L_Z+Jt*s0޻ׄ2z.,I.9}ػk3Μ8[ƹ!Hxw_L_D#]AsIo6Yji$m`8NE!is[LHX |"OھE_kqz)EJBe\/iㆈ]>N~%K׷^3a?1_g}:kw0b2,us"(_FsW/Ř!=mxFsFn}c5y$EW=DRH.=gdATlk-D*mQΚ MH=KsgcʤHM.=|:R5QX*/,R H'"U:RiT?$XKIWE)a]N-m MmsJď}i;_`f1O]}+RvkvnӮ; ~bW;MߏOBNضq.?+|+%M&?} <{ j\bVl9ԀߡA6_@nփ"CiT،EJPň t?1\dqasq9udtqE2]q} UvfZZͻ>66PHM'C"Ր-&`$,R>XTʌfΚu}>_1yrl\ DDd2fʌ*5[!B}{i+RA՚H#tC&, k+k74kA4CF Ϟ 2"jg"ZpVt9]{ JƩa}:l:vzƩ3Ad']EK._(DC2t3TlGTOƄ}53(#֥(>hIpbhemϟ#ZKSGNZ*8T$b-2 HIS-r8&h,RE:wUwSMkp™Dy5ETcq,R H'"U:R0)f_cvų'g.o H5"8fGL@:ґA&LTEb1XJG01,RPʋ {`*)dLHU^@Y*/&NEtl 0#"UyeGL@:ґA&LTEb1XJG01,RPʋ {`*)dLHU^@Y*/&NEtl 0#"UyeGL@:ґA&LTEb1XJG01,RPʋ {`*)dLHU^@Y*/&NEtl 0#"UyeGL@:ґA&LTEb1XJG01,RPʋ {`*)dLHU^@Y*/&NEtl 0#"UyeGL@:ґA&LTEb1d#K *@ Pqh*{D8eHU^L#& >DYAO>7VH85}+{H̴mE~&B,RU4#,oH5yô+{H5LܴiE6^&R,RU8#-onE]EaM+,R2`m/#uE]EE3,Rŷ2`o/,R@,R 8-a, TF8~~,RP,R ķ"5N&Z,RU:8.oNE]E"vX&TKEjCge nveS ]bhT|#P/ꍝ1<7FMo,iW8eji TmhL@X4pFr[H`j,jW8eji T-`L@X5r[8L]E"vX&TKEjCge 7v+{H5XDz H/vׇs߽{7<==={vU/cA05ΝCTTJ.7Eȵ"U.OIEa9}4QP!ÇhРFʕ+}ק65ڱcGϟ}\hذA>_8e*#*rmH˓1E`}&u˖-;w.F+V/N:h߾=5k7n%JaÐ,Y2TPիWBTussѤI1ЪU+tUc">d@"U3t .͛(Z(F {{{x3fO*z ///lR|˗(S  bرCј1cpyχ.]H<94={1yd15 N*}͚58ە=NY*.`GL@:ߋ;v`̙(P|||j*\v k֬7B$L4I|…Bdo۶mB8%!.]:ԷA/}}%'O16mZK۷ QY^=t?~'uVD)eYŧ%*dshӦGm;rsA"EbDj@@h[NċE"'ry5&H,R&R֭ <<\dhԫT%K5|$"(JXwGnVk"sRH5$&5jf'''|%R###Ř$!z &8z(M̙3LfFWdR5bgRI8u(ކE=g-2`42eJ1=zuɄ^-Z@v/6PY}az ^ede xCzSOt靠XUHʄ(m:~ؐ%K(wѣDYR$TL"D'eEiyʞ={D~eHMլIVj6NR'ObڵȔ)0J#{TifE4l (ԤTZw=i6PVv`%Q,>[[[,^X -3!hiS./iFh$wM^UT67Q2͛7U&袝4?M:TJ4Niy -W{!\iec+V(qH1Lkb>K8ew+/$OEvL5;iC /b|&J2Y-EFgR H'"U;{v}엿T)_>ڬFv)XJ%8c)TŅ3 {`Ss[@܅f_AԁS"X`۹O#p mn,RMHp&c=d`ʃ@*T@yhVg&W,[E"Y꟱[`jpLX 5LꍫڿǙT++Xj0cX&4. T/_(_L 0&\=tM_~M-[wmp,5R+ΘqkRb^GL@>TQvvvصkbTϑ>}{QA]5E)2eʈPTzGsg?(h֫Ri)iGbG_~3rZU6to`Z,R!JZQ4]ƫɴ%{H9x_GM@"y9l0qlO.Y/I/_,SR*ȯ⳯O QVv~K_:i6="m6"5"5::BC)T}DI7,RuO3UPH8N9|Ȇ7.Q"N!aJR{'l$d?v`)IEjڴj2St:C')*NG[v o޼-,,?:b2t*pB<}T,DQv֯_۷#00˗9P@O_tAº]wRkZ "Wϟ#ubԫWOX`觓\]]gtrb 1[@GҘ+Jf̘!NJ*8& <3t@'ߕ|,Rmʋ {PHF'Mm۶ȑ#h)2˖-ի VXȑ+ Lǟd^6lA#R4Ǐǻwb'WI>/]ybcƍٳ1 $BH2$D:zO}:t8YH ~$RJPjSHleڵQX1W0F4E($>wF\@bk׮a͚5T+KivbرΉ'uV񁊖pZEVɗq"UyfGL@:5۷L/P̑f?>)^IYTdR ݻ1m4L0Ad25QHl/kYKT4i֭[ Q@"@dɄp& ƶOD#\h--~J(oP__~&dW"5**JT?$HII&&JOK,3fv܉cǎ}ЬJAAAqWݡqHK.b,1cƈ5k5jdSʋ:Tń=b Mj#""bAgkzQF3}bjbkl]V2e9K mZ[^xQLjIk6{Lel<ƕ.RǏc޼yxG4(cn:1.h } ojӧAF qWҘ%0e0aaab\.]ZTK8eHU^L#& D*MO8ʐ!AHlj$/_.FIjCKȾ9jYL зoߘ~Z .]:!4  zKp7mڄ3~%R)E) VB"?˕+'/-]9%u~τA:fun>D=Z|qAYMpҦM 9H5qWZB5j$2{Ӛgj: X8eo"̹E&`pj ;H jv;w$2eJ}%UԩSGLcRvֶR&6$ƾg( Df_%_+ J%?>|(I"HXjΤ1Mkfi+=OWPES$,/+W=z׫WH4>4h*U1Ok) Oŝ1ZL?qWjXhh](K~,RO`^JHàD*ehw3r2$:K*%$iۋi3 BڠDk(J:w,c?] )I(h̙354]KSt/]t ]T?}:$o, ^*E6Zn@bAT)#LkyH'ݯmӇ'LGiRݺu (CJtTP%?3-oYfnAMRTMSO3,R 7nEjŒ&zjm`jA4.<ݯA"Uy1at,R#5i_Ƃ~cq1veS,R H'"U:R6(o,X,RE0,R 7mZa - THn~`j,iW8eji TmhL@X4pFr[H`j,jW8eji T-`L@X5r[8Tc7P)TNfXjoej%"U3߲_Tcq7T)TCE.HM<+ TՆ(~{\ IDAT`j,jW8ej%gw2`q/tE]EBX&KEzcg ejwaڕ=NY&nڴ"UZ|/P)* ܖ7R7X ڕ=NY(pZ4"U X|+P+jq7N/8j,jW8ej%gw2`q/t`,R D7"5ѨF&^Jaߌ*?v*4I5 |J֝AA'm,ڐq"K= 3; J~W,B?s/0JI/L@'7Qɒ B'{ߎ±r dYj7"UydGL@:S_aF]cxevTΏ 2cx=/~G/YW+<,>_8..˴jHU^X*/&NTDGj >lX8Y88 wΏ 2c ;E͚]p KIFc,R5ʋ {PHO{w"`R?'d ٱA&`,ċvȾ>?++e7*{,R.ʋ {PHwLWW1 t& MAٱA&`,/|]4lV/nhp32NUf9] HՅ~el (ZE*|Aؕ>vDSb "Jl{OþHIEqgg@R D{+-l X:&Ox '`E/(TEEb1T+R! "ꅯ~b テtvl K~HYW6ǐ淁H7|^RqʋTń=b Htΐ `zmd^S:76EQbyUEwŊOyڰLg9mvYgGL@:S̒er'd}AV1Вfݩ~3.Yrn TZnWrcE2HIm1PH};~(ϟ i@͞ST-& 65+@HU^pX*/&N@-"5hj^HSż`L@4QҤE+`acc47#^t>_8.n4_ 0TCN\[,Rljb&|-^If3mhf~TB;61KbHM,)"p%&`4Jai S>=hÄ6:ɯd.D<{/γ<_1eXY6]`og=3~ T^vAoQjVwx'nߔ*B +(>FR]2i7y}*%?',R2&0plY|qiVׁBM MಏZfwotѣ8]2,QR)7v<H58s/DGDlZxw<=Q)ؤH8?!&O8>=?B.]:}6^^<{GZ?0]HՅ?@ \nW ʝ;W$Z <[WڵCQbuՎ8߰!lC5#SvE)GJѸ7f D5E b%pR%?v %oGʫhAxx }-GodغHUB&`FZ+>>F{Z53=w @ȣG8۴iE҈Q㋋&k)=} Kkk#0̍0&@<(֡~D+m[̖fF!{^=[##q0kV|+V b}eLTӊ' (@8^("?~M;f(4NYǏQe(lڨolrݻ0*nnj H5sי{^^yEV2TP$My +1SQbNzooTǐ{M^nTkP-Tz)u흢As&E@Q|{`<2i*VD= ĤwE>'/Ѹи1 B'i&J0ʑaa(w Ryy ;B,RU4v ޽h!ڨAֵ+,Yغ 7b0,R bE@тT,B5so!ڨӽ{8/DE TsX3`7l /۷i~o݊L / 9E@-Q -q#2m"+Wr|HZ6̓@(EϚ޽ 6[.(x*^%JJb "UT٦t6n F oZTjPzrzO3 ĮZTI{# yoGAwdxnQԼh׭'[*AN{D@S![6TSuA7lQR5g,R9*;Te[SˋZΥJDVraF&{(xmdotk4t"Nff? "*HUV۶ի,G]ڴraF&"ɲg7G7b\jv2ÇTwl,RyH}F=!}z_dlb&9s_8MmTS:):2R -[׮v͔T3 ں"UYӈgV኏*M 4ʊ{FW@8'O/Ƶn+*ݺKkk-LXhP Դ6 *͵PFY߾?..CW`<PqTj˗(~=\[?&"G*'R_~c3x6ҧFU0~D78:oΚ {0{zܺV(Z(kJ GO\D]2er>;ū^EkXt~? TB_[)FFFbp͔:6A`G橅0>o8:m 0Q6-RW6NX^q#+T|le[{s3̟_mbۮê>Tx!V*^H66:_L@g\"E` Qq{`<2jք׾}:scLHq qhz«+GV.J勡JHk7$j_#R3f{bpq`T\viK#""{Y^oޯHm[JT6)RbLXnGsj0fki߹xqc!vMT )w%3箉wfj.ZJKuƽhiT=!f ƕSbeY߼ޭsQ'RU?;}p9J,(~/j6M]F=ϔBw1 !aw&S5>( \7G tT <׾غ0,--n\?5%$%?v"*E=\;%pY=8ɤ'RkTȨ2k7;TH;i)MZ k'G=^lXTU $v ;paCRm}wG<<`ae%Q%ϝۀ)S$"j}Kx\e?2eLԏgy!|GN7xx#44D6}]zMPH^\8F]eHIx%+OH^wj3 U%R_>  EʥS&8KL@g4;ajQ[.(x ـy`jWM4h#epuIcˎC5/o&XcWwYRh}+m~{ ܲfBʥp/; p`+"u 5p`Lm}£'/ҧK(8]+QxhdiUG"UcLkƇ6'K|Q..F7f,R=3=KW`%TЇOBVT#uDl1V݅74_x~JvSpϖ3&򵻰i?9:"5** ?wu+m:W899Ëc`g8Y B!1Mf,R6vN!L6j|OWǎ!A;yB"nT5F }N̚T3Ģ.592"K+"Uoٰ0ڨ;}4:ggTmT&]H5inG',Ru§Qab? TRCkV|) oͻ7$Rv6mǐ!C女HVVVIm DGF/_Uum9`#DX?L~ C=D8exp $P!Tr凝ON2F+M:u $6O<3bpssý{йsgz ɓ'ܹsQL\t ۷'^xٳgm۶SN8/_b޼yYo„ XfVZ3gĬYQisi69ʅwݲmX?&"G*HoD-6E#NEmE~K@S'4Yp[kJ\lYL&D+ ԼyUVȞ=EEnЩS'? 4Gp].]7o7np믿 6JwΝ:t(N>-n&MPre+?PqVD` Jlߎ $ ?cXquVZ'{V 6"5AD|FW]tqsΉSb_n݂w"صk/^ĸq/_>|!N%0}tI%KħOH-[AAAƵkPn]JgZm&5)F޽{L+m\XhtES4OTʠ>OYThYA p)"s@ȦF̑#HS .XB55aʬUh޸6h0F6N耏"cJbN\6YjK7ڨ Mm'O"200;oEkǎ^Ų.T;HW&?kfXY]r#{sp.)6JY9'F7 صQi&Ξ'$R)I&%bXb߿?ZloߢW^Xt)?~g[JƎ+󶶶Al?t c%* ϟs⺘g͈T3 4 8!z(<_GBRSvi,R7jFWTY~!g̘Nj?K.xX{ڷo_QJL*5qDZ ȝ;7/_ѣNQVys۰A'[`j>VuO*R9c[Kd̐MWŨ(|c#x_dq̀.ocJV ¡݋0jx 0#]:4k^ޤ BoHU;/@bjJnRu>ݻ#]\TvX9IC,+"#ժWnGY4m'aɜڀoP'b±5H T¥wQܫ5+]G e/*$ T~, hΪ6YӾx?:1o H1 ILs9 Vӽ`}?ˑ?;~2Jd?'sLɿFU/>_YOBewp(l^=MTEHH<5'R9+֡~BţU$Ǟ3IF Tv|QMZwѣ8]2,E.To6)"uSI/g{#-ukI̗}7~%RN]e$v[QOF[lCX;~f}RD*7tfSoT}}.Y',֝Ѭ`un->,)ԧ-&CJi~: ߣh֨:6d]=Oo}t(wd\KE4lH4s:}-$xPP~wAرchڴ)6l%K>|۷E߼yiӊy] IDATb_J5Vc'd+:2RW@fن `jA5.%Ufs;KIR)?@SO?Gn?m FLXev Sƴxt}W"trS֡X:@֪]g&뷟k|8^~-l\фD>3ٳqO8ʅwԤ"?`XtxMsIJ%pB<9Qhq8::c SH!>| .]{P0;ʕ̅y,X_> mRAMWt ,R#e*#)*whӧOQP!?9sǑ8{,͛qƉݿ*i*>[l(_s H_|Vt OQ~X9)aE^qFeg:JOOO56R?~ϏW͐!ȀRbŊ brƫ*U|%RoSwG×(*>+|8{`C(Raҵ/YMCL)&Te &j^:ykoٲGf*6OFD*{cJTu֭C@@ȔҕКTcgRNj-ZFdnEVTp5C`jh^Mc]35`FQ!djȈr[J"ʂJ^T/\%`ae%ۻ3ΖTMEg>ΫMC\ѧiS'c6z ,R +@ڨeAJ̗|v~`ݽd &"Ĺ$PH] \F\[u]ܺv Nb!)FuȖM귰0nOYT7,,R&jTu۾kѣc9gL4[9e TH٠ ZU]4'x,Nn\X*#E"R'ۍTN M,Yt>ľ=1:,R#e ' 6»ht^l؀K-[.S&T}V[Woβ""5Q&cPHv)]{VNht6m]kii${5+Qh&#TjEjRsj% 6Zn(##E9Qp"uj`[_PH]  $)|$N=zbTfhܸqCtzK'j&ʺX"vB@FmT՘~>Y׺uc\t,md,Rn>q RӧOOrsĉ0a(M"D1b6 v< tHD"56 6Ic'BCQ/_pmBi`EOq#t)$TcԡCsu/^ #.fzE4lHLCpyJ;eb(u8^&$a㇘@H(7cǎ58aÆv! Yn H"Q%40KTʟ? *7a ,RA4 ϟ?͛ ZihѢ\|kcIy6p#"Ul2H[nϚ޽;;3d L@*OpUn݂uʔRm1&G #rw#jzkxɆe$v[jJ6#YQ po89Gǘ1pd*$9>s۶(r {.HQ?KΈؐ`jbeQɚrrB'O`#a*s2gά5ٳgZ˖-Y~ (MS5c>^A/ٳqO8ʅwBV`Ȱ_fIޘ1=b<$MZse52~@4eYԨ h\\R{"; ,Ry 0Eո$OvrΤ^&L Yk֬A,Y@%:`ڵB^Я_?tVٲe=˗%~ XM.]d0Hmx0e WjJոX?b;wG.FR+WWWܼyҥ -^[nŴipRW[l7o{F6mtqeF%Q_oP C3gKoma`j @Ǐb-jd` ĺVUN"cgR?~'''akXb8v aڧO3()`qh.8 Q}xqkW|wG×(*yiT`F@(zM՞}N7oތ K/.DٳgcJPM4IZ|+yuEyś{2E kR.uԤcJq9 G!t(SIZ>-Pf>&}L=ilؐaH5 gn $DR܍RيU\`_\5r^y騎^H`th(r#K,)4ב2?n(,R EaZ0HMUt)}]rED-zaHUfM rו۔XySv0*}\YX3 m0- Hng`+TuV8ժ<'%y" T.D"=H^$lFX.fI$ Cҋyȑ(*O';wDtt4*Ue˖ZbK.P_m&u„ ?8UjU̜9Ii="Uy '*MZ1կGHUt$ CkN>}o>|GGGXZZ"88XLt777!}|,R5 褶 ;d?xvdoX\Nu:ٜl,Ree{L@"vBXX}Q&u}Ȥ>~'zedϞ]̤tN< nVhԼ;t@+7G U f?đhݮ; i PIK /|]H?vRw_ap4c8ua$SIDw v T憘@_???§iS-XҦ)'0]b4i"bUΝ??f,_ș3',Y+ R3dʂ^ry-!?!lGN RuSya1[l}Rs>_0z;٨ ևc)C!c7I 3Z 0j,(cbRի)S!63)(+ʾ~"ʗ1pTH;q@,=QdQOlTT?/&!vd~*$Kn5"T3~fT 2CQ$+ռ>heshmې)S&4kL)wn"=^ {Qp CBfNq6*C^]]8BΝAۇJlT|flwRe˶Y+@SÇG˖-ו+WĴX&ptHL~/ZTg:!նqcSMNM mDf|+2JM/f̘!vӚSYW``8vg&YptH%8͗%L5}:TRplg2m>, 7C荫H;~z:{ IDAT6` o\rETyVΝ;b)5|(UGWANyQx>d,5C8s{6N9٨ ]-qIm]& [Y: zm8v4СCy_oߞC!=bL$O :rh{^FcӑUe e 1?~rN,HuQRm{JS._ [!Ul݉ǑңFeNG%eWʗ 8*շSsgǦرy=RL"ׅř#udžK K֯gRlTTuF~*/&cAY>36ݰNRuq.he#LJ]$7G’e6afX}:V`HQln9sP7n܈nݺO.& GԈ%vKl_B&аicvfO?~߇gO!ADțDj95Hڸ~7HK 9r|XTY>3)O-T}tVHzhZ49Ulׯ_Ǯ]ēGGT}Ҿ٨&B ;Qb1ET>xYv@{|m 0j"`=ԩS\يl\|YTϓ'X6,Y2[̉:VB%}ƹg 0/(,ٰ$[ %[fH]=Zp毱LTͤdC0g|7VGЫW/l޼9R===1ydIjϝ;رu 0Z5"jB-ao {+m Nd\k{5R|ג cV=ڴz{.dɂUhѢɓ'{nyގ;^F@Wٳg+]T۵SSr6K/UϻT#eHUeZG sڪ`HU-!`>(p߿۷W,ǏQT)БQFM옶,]T{?RR7oU&%WTFe)x~bHUWgNw+~||/$K VC*2+4U"E 1ݯj۶-֮]sEV[lt͛ u/^@ڵemP!ѬvuF٨aa"9(Czު-BΞ|ϻw{qSYJ}ϜCXteEsέdΜYlj)}%W piܻwOdU^>>>8q!RgcH'#ivpexCG[ՙ/T޷,4ȦN᱿t= :*ao7bT!5F+L#GqȘ1 t*eEǏ]*3uT 2Dd_Ɋ_~uC\}NugN>vz6jDRWzd| j |DzY`HU$bbVO>$I\i0x`o([VNh+رcѽ{wEP!&NMTtSZb<._fG-ung>!Ui(/~9hi![ ݋d=7ʫYTz+pygcͧGo6F1c`Ȕ)hvO۠(#J $ךk$oxcM殾>2V!U_߅MkF\rG*5|d8٨ 0qأH;y  l{wk\ RsgX] _>})ΤZ 5 EJE'ȤNM5 `H\NTB,RC/V\ E`>?:(tPvKw/ g?}.3ײJTT:rf45YE 5rFIyTW32F.%Cf!~lĊ#Y6r;c@ 9ߧqzx~"W#nԶ5ĵR!*=0:X%KWV|Ri>-/RHS|sE:][W̅ dMw#+n\n[i13ǷOnKOY]9}8ImT=t sޱ!u"m..\DzB꟧N"5ԮZHQߔbHeHU'2(on\t q6$fMa!Uh-=@ǚEuѱTZ)a}G}Ί4)+ Q7XYQRS׼P;Tv< JDFtGc%vC_v#~v֋!U zBs= Ӧ 1J!to!&L8q(۶mTN)zUʕcl cU ]ǐʐ(%߽^2riϝOBk2ɐh3ozxa8rq+aK*bsC"e?~E?~kR*]4ʔ)QGŊ ԩŋ+O/\#hfjxNVx޲ N bW,Jwz x9s^/_|N Mb AԩSq 5={փ̞)R9MVvUF<3Z.nPaЯ.X@@L^M͐ʐ*-ȰA!Չ`*#R dN R1r&9Jw<#7[fHeH\NdXƠΐDd[ s2w1 /tߺy>uS ]^:Cz k鬀2y>_Ri„ۥt@{cHeH+!13:dd3C)\ϝ4+^ˆѴYskL$~x#v!!U@vB2uT' $ܲxfH5s+`fH_O}?ԬUٳBmfdx5RRu 8mLƠΐbے &pD#C꧷e0SNI2&RR &딌A!dA@ݕ  |+AGO1t<!M/PV %e6g-.sqA0w+Taѡ#gP"{{(^ ?鋘;u : ~F>Pf9Mw7wv̛6 u-E *@Ѥ`D̤~+s@;`H2220M):Cɂ+#R(@Vo+PʷȕK8u+,-GN|WA!b¦5kJ!u-he$ʆW!(m!:z<@l b3[жHѾgx,QB*eQ橉P/nK$s-C*C-Ay)}%J;N:Ȗ-)/cPgH%2mn2!նZ:+| e0ldH6 2䪎,9m[l(eE=rgœCЪpaE׸M)PF6 WХ}#̚OWY?lz JH2v \ݜ}pGՎ9TԘm۶'Z`&z<==R5CޤFրI^MǃxfHU+\ RiP^=CQZ)+ *)ĉ U,;/([(~h3'PAسy6*/x)K 44 ;6LY^;YTQMdn0CB*ۺuktO *aÆ!~w&O,^O<9~'/^?xpj4!zx >zj|ؘw .\2ډ%W﫯, J"Ly; 5,0HE ~ NNMb O< ؠAM6x-hBdG+jժxu Pݽ{7hڴL2X|9֮]sغu H=<݋-[H0`jԨ!ާ>@9/ec)kċ!^@*dzz_ȈgΤ [A qH6%ڴޓu8 _eAzjx5BfE=`ҍ`n>RYx2A-kJ Z咰s=Qq/lgzeb;j(CJpr 9AieM02RƲe˖"IIYԊ+*m[e2檁{XἸ{ӇWy;/Z^Ϛp?eyMa& R[ji.ipqqq{:tZt)'^xAZ ,\/_v6-)Ν;ᅬݻw H/1}tEݑ1s&:w[ :"+-#R-蠀-y嬆7oBqDx*/3[: ~c{#w6-c WYDtĸR8vo%˼pGw/BxxsVCX[b<ԭSw=bH!.ք3A%I>1bߏ+V|AYfhРw.24muElG+SL]v}%Xx1~gM6v3f( 5[lx&cPgH[Ɛ^/@ ; zhj%ZE>drB|vti,Ɏ '3&EkGUۊ߃E„HzR(ފB?i…l2k׮bӧbMSĴ>)e9)+JimENjuc IDAT~ʤ&I.]ZZ4j.lM3xM[ i: 2rոqȊZ.qǐaxԯSQٴ 5+ rYtn ;NkWZ[" yis'EiOD;&֖RL2i"E|q .Z.>OE.C3dz5QĐjZ\֡R:Zz BSt27HNC:]{sGnز842Hݴf,'9Tk'~Imu$™T@e7 2%d <ݯDy.#C̙Tb+` Қ K4(x;iԟg/a訹:;:Zaذy?sd?g~Y֤FG!{ г8) GAO<|!U(0ATH=13̐\1dڻRf{)VjU_EEu4j9@l{\ "KJO߳%F{uR>MӴ?Y^@o׸qիZ9?qj S!00EGd pCvRF<3:d8M jҌXl3n>@/5tBdnbM[!foBQzi̚CGâ囑.mJܼ5JHljۮ)$K4K@Z`zrÐjeH5s:C='s8ʨ~i@s1`ƚ#0:jvlȐ h t3wʙ2|86 Æ!3Ka{RM'4F\xUgަxfHU#[`4U!US9u5Ɛj<ۮ&Cz ^ITV@sR5T7 K̓1Nk eHU![`4W!UsIu3Ȑj<ۮCz^QTV@sR5T7 K̓1Nk eHU![`4W!UsIu3Ȑj<ۮCz^QTV@sR5T7 K̓1Nk eHU![`4W!UsIu3Ȑj<ۮCz^QTV@sR5T7 K̓1Nk eHU![`4W!UsIu3Ȑj<ۮCz^QTV@sR5T7 K̓1Nk eHU![`4W!UsIu3Ȑj<ۮCz^QTV@sR5T7 K̓1Nk eHU![`4W!UsIu3Ȑj<ۮCz^QTV@sR5T7 K̓1Nk eHU![`4W!UsIu3Ȑj<ۮCz^QTV@sR5T7 K̓1Nk eHU![`4W!UsIu3ȐL_Vm\\Dxn !6h̸A}fr)LJge:Y[!ZŸ<+ :, ԕ e ^}H.åIk9F\Cڥ1B37+2N\!>xԮSc- d߽w/?zՖ:%2*U :o{ RE<vh┭G=srN\!~x^pHޤ"+ ؤI#@?)xW@ZiR*SlxeXɒ#EU(qPxp<+WJyITZqIV@7RK`G<+UC9ާQ]ENO:9+ 1)vP!UZJ{ăR>{W}pg9jTZxSiԘY;(^tk=A]R*o\{ ޠ:9&g5CvZ%V@3RK`G<+Ur} /_,:r&6ʹ񬝢 iɖX`HU/%Cz @iwr CCu]dzm}Z!U + zV#ԕ*q9O禾z ΢ڦ!gRmM(ʐlTTr2Po oy!tZTە:.}lv 5d 0TZixPW޿b%Jl!'us<L϶kǐ^; HS!UZJ{>ɫҦ[` ݜ}FwZ=dz:p<ӏ3ڬR˪`G2S*m˙L={ dAjEwesSǢZ. HV!U 5d 1YN]Id3CSߤ`HU-T R[\̐ LTaHU![A!U߸TVi`HUzT 0ט[O̙T-`HU$SRk+ cPL|q I`VTgHU![C|ϜI+HTE2q&ULl 9jg:q2!Չoݘ 0 gRk+ cPgH7n9XU!URk+*_cnA?d3gR (R!UL<ݯ^&`gd ISy̐ŷnLR35d 13* 5©S[(QBu۶mC޼y5kVն0:/rݦB&5L,1lwRm׎kQ!URk_=z}h֬6j(ٳ_R۴i-[ [ɒ%ːW{gTg9˓~ϟ}tW9Elu LS=e(UrMV` 0wփ9nOg9mmwj6OqP'mh mrO~~~iSM>|Xlt5+Vϟ_'knDƔ&M*^p6l@ΝߣUVGGڵ 9s&N>-Z~`cd Z=3dz>*'#&ՒI7}150:$}Az=<狪W#&E3c1b7鮣>Ȓ+k&R kL$*MZ`:nӧ...([D?e:  V,/V&L} `%P%HW\͛7QT)U%[ǏGPP(Gk^]]]1o}x:T=p 9r"HݻS\ōWٹs'dɂ t3\2Rcejx-[6|?A=bȑ#":ujVU}UVs΅|VZ |WWWQ(^8Ə/'2dȖhӺ؈z,]4~ľӴ?Ae7m{ETQqo6HUo*62!Uز 8ipŋ[,_SՕƐh*~̘1"ҤI#*۷Oe?A qɒ%bC۷// /&zޤI3OF^§===*U*xyyEk$X]x1~gM#H(٧eʔRgRD֕KKĉn?cƌ1lx̐ ꧀Y ٳg1ch vҥ 'N,e˖a͚5ϒ6mqt4i>}ĺ<5}EܸqE;i*ʕ+ >i2I4ih]]ǎs-}Vz[ft]ѧL&MHz}ذa8wj֬)l*mu'ObڞP#ؤL~߾}X/J}%~\~]I$lYˊIM>iZ3K-Oh+}^~)s[pa9ݺuSz=99 l̐j0 vU |SN( A*M3LRr&$K޼y СCx9PdIqe#,;(֭[Oand|1JtD=C&nv#2!i78)Q[ uR5#Rw!)-WteB*=4[-XxP._n F2S ( #Rz@˗/ӡzlȑ#Aj޽R4nܸΝ;%KɓG?&ťK 6[K&588fѣG{4n͚5CvcPXbнtIdqT@3gܹL2r:]k׮ŦMҥK?@@e|9 HS|#GfԩZU%-6VZ%Ν;bJ R[j%]]]Eׯ_x?~xrȐ!"[JMb#B3gtpNŖ^...ؽ{TO3JyPW&TjeY 5d :) Ri*~̘14i҈ڷoM˔TJd!r}K=joҤIӧOW^H*5Oz.^?3ҦMRfr2eʈL)TR"J q 3J4CTyMaunbHUV8+ɐ^C!@;vlqWNB>}§ R&Mz}tap9ԬYSSETZJ:'O %-F}}}Ŵ=eQ 6i#Aeo.֋R_ (i(N$I@`i9.+b&5}i,yT־҆*m…l2v[nR=͐*U^SA]RkgJ2א-褀LHڵkÇ#ʐt+VLd CBB>cHA) @dU-ۋiy%#&`e!%褩|:3f[1OT.*Gk>='Mf x,:-}:UXCLuau~bHUV8+ɐ^C2!U[fQ!Ãu1^C,pn^\ pn>qReClپ*ܺC{!$ǕCT!|>3ʎT }u%|lÕST!|>3ʎT }X2w &(Y.V Cb!|>3ʎT } ٱ zz=Aq=. |Cb!|>3ʎT 9VE3ʎT ({.% fXM`HDF]0*77&YgmfHFGb' sau66gW!|ƒ|=L`H0H k]m;F^CXV@ Rdj!Ul\g8!UJ ?zPƟ0ĉX3V@ ҤfuiҲa;( VP 9}$=w>֊Ct5ou%evTYRё|w8B+ IYC_1ꕻzvx6 ƋrZ 0pDw 8.QpW.c}`{^A \>:FWEy] ̐*; wRॏȐj>YcTk[!Ul ǘ^|Q_D;g>(jH`H5Ϭ1C-ϐ*W_nGfLg=5cOiVsRCݑ&u <;1g2z(,#:"i-nصߺcOt=!o`H5OyP7?T{)yI5?7*8!qGBb~b$*qUV@ r:C9fyTc!XؠN^so 諀3@GO1t<!M/PV %|6g-.sqA0w+TTB9t I&z+/bԁئ>f/]L@ݚгKt7 WA1o@,K}=[6 (U*+I<ݯpE!U͹E.22a+ m68vjTr~)РnEby´5Si"(8Ռ+6$^S KVnA.#'W6 Ao 3}gˈNo@ܸqx:RY<^ @w1C7t A*dzcH_snQΟq 8mѶ+/_-} ߰0 ҥF  #88 gAۖu(JYQqzŐl64\8g-5.{y4-Mpti&}8~~ظCõrāep* һWëWdZ5-u1 n7sb~΂{!%o)^W*5ڍ{aRёè YQgHj4 l\\}tZC*M,TAA!AUdH oņAkFK1hlċu*S?=pR߽i*-ZHzY2CŰ %N$wΔb#RH1ozx{H <'Ҙ'N9G񣛊 R9{I^"/^ٳgQdI~fψ9ņX{*Jڞx/ xR`rEտ-~!\bƼb*M+Qeh7>eX\E/3b蟰dVq/퉞]*ԷoߢXz83V2h٤&7Dxq0C=?vl;~gp:}TU5S $$XգCO0j&5vX93dM:mc8mjN9{1ZL*Cj2Ci]DT=fHV19*W_ ɦC]`uRtR2Tc{ Cɐj>YcTk[!Ul]CqOCgԔkR hŐj>YcTk[!Ul]CS= ]n(S={jq!PUTE2Cǐj,poL-,ϣfgΤ,3]YT u?PAa]]]w ]f;:4ydDž֩Y uƄֱxQx zx w1 nRE6; 93 FrR9y ̐*̐j*w9\gRTxGȨ.3Wƭ"+j6>7;W(X0%r$I"~hfgϞƿW!G6*rX0rʶBnlfWdHU,cdH 2+VĞ={0j(CYQQʬzի#O<6mZJYZR0` >k`f}|9ʠ~ RJ| C,+Pz?Ǩ]ad2ꚕcHU'%8Cr$CF̟?8\zyy!GR۴i-[&KL, *ʐRij-VWn8^fښl죥0۶mAѬ^1[dsTR9ŀRUA3qZV-_F5Ć+үP-q!$$DdYiC*CUo? 'oD˖?"gΜ ~bʕ+Xr9{C7}6Z1s!YmmWH]fφshݾuM4Gێmc)-!_Ț-+6m،`΢Yu~-/x8 IDAT[=/kSOEbE|R?ҁC ;jիb-\~ugO|}7i ȇ歚Zj'}$ҹ"r={9Z鬯X[ I}qJ6T Iyԡ.1nxEr瘣٘?YJDm$Y8Ie5F+'bGRLGuqݦoHjV1}ZMm O*zNGl{AHpR&']DZPvIDh_xmb)"۷{?T3:5)b~;CLj~t;'UCR[m)ݶ`5xT,WB7:1T7@0r_~kN[`aB!1EY'HX1hܬ>A$u%ظf~2ďw,[LR@te0IU?Iݼh߫oOA(=Iv?tllyvv"K:S{׻ r<(H.$O~x56$(l^$UIB@~Cp}?{TIZ]@I]KMukp$U5LRMRg/;ۘDegϞȡ=kc蘤JT-$Y8Ih 1e4lmmE)5.Ǝ{sE %""}'HR+T#'rM4.B{SgMFIKNt>jqyMGO0{\q!WN۽OD.)уG⸝rg;v퀛o''Uڭ}w}šPP̘7 FLO1axTRQsR_XI]>OKVae)sVpN?y,޾+}ѱS_<1^Y.TKٲy#*Ɇ}BIA&RIefcG+NR}||1w\ܹuWš!#C!t=kAsl*vzVQq5,\Pi+/N*_0{JR}vhױ8z'2MđJ8t@P<_CH.A$_g`G[ 9(M>=6l]',dɒF[?I8x$Jks z!o޼N ֮] ~~~-*UPd'MO~\?ܚTZgϞw^(+(8IzIʍ'PBM>G%Q,X,Y?un]?~]kR}&Q@RٟXъT}ᣨJ:T!*MYzZJ#XƎ %|}?k6l|$uغu+ڶm+^׹q:$RA~MO$עj׫>3=mJy{{/Q|2= ///ɣ@Ǝsz`* N5Tgi6{ɐԿN-"M[4Au0oqjV&@B$52IKrT|8uꔈN6MH1H"Ç&KǗc.mC6mDVI;wN3k;w3|}}EdJCk߿ǎ^~+WD gΜR۶mك&$wxӧA>JU/ӧOGn)[?EQx_IMHhy0c DD5Tf˖Miӿk֭֬[SN<@;&;'r\c'RK/^\Y":(Oiz;.Y{ jC"Et4Esʅʕ+#}]ZZijEUumå'1W]]$؏Ij?K* eZ:I1cVF |$5wٳ"9sf|-[i*V8|"=z j(DJ0g9 &h)mʋMR]&R5cND5|'MTgBa3IU'Ip/uݎ锂~y"_8pNh"}m֬NcӫWsVL\1 udBnTgiUb4T%PULK't?sLY&>q #H* 69D 5mȑ BxIAGEM$Ht ZI[ϔ⢝|Rԓcd͚JQOիWRғ)JRe8DWb3IU'I1e+F%j[/^,.$矠_uiDN鄃e>}bޤNI!TgiUb4T%PULK'GA&QNۈ#GDR顇-[~caɓAeo4i"TQ4FIettJ :(*M ԐT:?x%]PR(Ai "<ؑٳ 2M9Ji҅*:mr@9:h EI:IUG1`L/^Ѕ=jC_5yӧw"aD d" &:Ie6=djz6I,QuOr$UɟXd:Ie6̮Jb$*m$UEf2[Uç!5GRDLNLB>TgiUb4T%PUL&*4$U$ucs]m\RCR)Ϛ˗&/޽+Ob`z LRuM?K* e2IUHe&${_EQ\yј$+)I2d$8~,LRAˌ2I5c`iLR&l>6:L'5>w1?.Dž`GemŲ(3G:D~|qJ'⌤>Zc LREL3I5SêdYLRUbIΝ;eq_ݺz$^]>h)ߗIb&0*$U*Tjdɒ:-RгÔJjP̙3F15z^+tm R5 n>?냖}**f` 3LRk;wrhT[T)7F@؟AKLRX30IUVI&6-7jHqc ,=2IKUKbj^y&7X1j(}A… 1o<'ωoW&oЀIIbВԨ(D}@_D|3{D}D{D|?YȾIbКgb-i0uT0~x1obd/'4 F9I& LB&&aUb|Ϟ ½=qHݰ9r+[e uΝ;ZU_͞=bbsڝIjo2 X"8SaLտHۭ/Z$ILR1Bic LJSnb9 "/bg*d$U:#r|laDd9)AyLRH>}tPBGoNZv,sfejr&X|&Ȫuoz m"IU-i///4i哬1AUgc 0I5.&;T5)-wmfIҤET`{WFNaߴR}IHi ՝@4iPD QFg%3Ppp0ZjuPuF;ʍ܈-I6陘y,Nxosk϶d=L-r6oS;jD&2D4ϝ;'&EU˖-)S^XU)ה>k׮(Yx.7F`V zTF&MFd,ϐ J)g~@x6;7Ǚ'E#=mD[GWKF. 6f`M===! C)14iӧGڴi+W.ϟE5ᕰjLRu+` XܦF4!C.9wj|gӟ#d8 &_td$BN kr()>Lj اWS(4y2 NJr *Z0I<8JJqED*&m:+YwUZXYG +#U#ZĻRͮxq8:;ásg$MS ySWX",c0IGUI2!""B*cj .>.k%h>i!} AԒ" kJX0*JlTÇppp{-/֭[X?LRQuR،S`2eΊ| :nB̕GuaɒMj.Nk"cT DWvm:N"Ħ닌3"I<?ĵ*&ܥ?ca&J)ǥs;oz̘8 5i a%rU1CG?:%={&eec,͚ š~շ^sXM=v$3f Y7oFΜ9E=eDFFb>|8bTzqjժ?lpFYʃjj?5[&Уծ\+A-[a {W R:RHjHHxuɉ OV؟Typ4[)o0e0~-Ql 3t%Gm"xճJh>JԳg.Hѣ1Kő'иqcnZ؍L0AX{eJ-00ӧǏE*7F@)؟B`'Y<0a(j7h&11HfmQ_ݾ}" :Z|d6-:uUE 7"(sM(0vOtl<<&OFѣa̜ͿtYϟA7ի;v20#l0t d DA_6]*M]};30&Il'^╛||TI]ަ S>sxt<8Q,6kV'=Lӭ[Z M&Òy f2e ,L8~x/c 3&H,Y`tD|ST=rAѡ R)NDѧSҡ^QTS\+d?+cc&RE+O@▽1c&WkAV4eYV4iBJ$ӏ&f0V'^؟w&c  +)OQCH6 C]M"HtU* JqDh*Ȫt?͛7KTO>5AX%SDY~0IS{j70h c()6n#Etn'M^lLMhSl M*3T%ѵ<ڜIx4X6*6Y"lMQ܍ S'UDGBkg~P.+$$kZt[J{S\ Ү(*wqq/FQ~*?|pQذaطoPfM[666<_fxjĈ3fTڵpB$Tuʩ,/LRœ@Ч@QݛVRCܕՐXK !k?IU`LtkWflf8q"L][)SPEݻwc޼y8}4BCCQdIڵ ߿ǘ1cp5A2+TcǢ}3DRhSwwwtQ[ V 3gbӦMGadϞTe=gAg<< \&CD%dō K!A4JtI m,٣_M?9̓'O@73f(Hfbe&]EEݻVUV"ʍH ؟:Ta3ɀMv3Osai$5˕+u+"eQCDWu$FIQ7oހ.i.'I;J8pr̉Ν;Kc`2IJ']'VuM,5x^EI6Z[k2 g׮=`U::2e u&n?&Mi%`Vݸe3IMyV X}x6O]  &1S]}]ֲ%S^ҥK-{9UtAiX#x$5eBݛ2iҊjY8`c`~Ż}Dt@th6-:uUE%?jWF1Q53sښIjϳˈ0e6lqS(E & [,/]] a>>*UuW)wӃ.5-x:7v8q"t39 $5mȌ5K0e J1IPOQ 2R &C0J$#FTӰk]x"j׮ *jnb|Ј+e[!TiPFGFU+AVjIRijU$T7 6 ,Y"^:2i"؟MLRMI<Ig mT fбTӴMh~=>xUҮxq]u ֬AӦM%A *VVV39rD4ō0z.$U~LYH% "eDI`*(crsÛ?fN;)^zaǎBff^~[lAʕ}BUAXN\"5?Zcʋ'KS& k"b!tT#OR:Hv69ѣH.>5ݺu կ_?CE8 E`ʕ([,؟IՈ&!LRk]bʕG>dՌ3pUAR˗/*'5fAرcb e@D~ I$1g`sTydi !$U!`MD,T1jܹs'OD>}DPicMR I]]]ѠA8$%x`6=s1I5=F?@IyTuw޽Ȑ!85)ER){4kPx!lzgjz6aZ0IUɩSjPHIw.]de g­dLRu;%6IMl (;?TeUJiЮ];888mEmSbĈQzGR/4nX\jڶm޽+"t1EP)Ǖ6=t;`UyI?&uuH S\u`fL53Ti6FBINix7i ].夶lGO[S Pdo߾8pIݱ0dǨaSm*,Hjg&ḷZIj͑7o^,ZHQhC/^U0LRܛuP" GǏGdP`ADFFӧGaM p(:{I YϠ?M]Ū@4#J16j%.\@TO?)khB/(6*e˽=|Fr Z0E6m¹s焌ի[njAri?W.#S4_`Tæ.bU YLR٘G ؑ]vI& ~~~prrSQ.] nݺR#N֭Vر*+gj$7p3;@A"ur4YE ^IPN4lJÏG3Źk& .D%1'En߾͛7uvҥìYW\),}?.J<<<|rANfʔIu$8&{S'ZsZ"$.0nXKNLReOva e* ?%IHjڵŭӧ/*6kذ[xq$"R0fL2Ų5';Wmfcm$)JQO5Eԃ$ګW/G+]Ԁ"LRLR^x;w5 Oi#ώr&YjX*Ͼܹc$dܐK!Tgȑ CFą+:үU*T ^⡢e&LRCM査 5i%*Y$vcGaDF$UvH% dLR٘G K!iҤapE}ѣ޼y#.N]rGABl2qф4h@<#'O#YEi8'U>,㓤Ԧ;8x5BeTyre]5l/ڄ?K3I4h#!`)$JI=~/^@jDT5y䂈Ι3!!!"-@S[@ˉҥ,5&ƱR:iTU;M{]M'OWc*A+'oQc`ggB2.y.e(5l-+zFٟLR|Zw,ƾ8;:$86TzS i `YPYƏ.Urf VʟJa~[ƈ O J"k4 DIq`WjSكYWߏID`&$Iq!֟B1u:u"*Q?~HlmEiG3\xz :E9#`eD 4[:I8"$ըp}2&Ɓ\M]W7hҴ9˧8Q"OTY<}0I-ϟg`em#Wfq*]c$ոxl"`,yG)׫WO+O߷_bڵ믿'8T"JCQ )MO~\hnSi={޽{ţ׮  & K!>{?"ML(Q+Eݻs&Ъ2uPRIjBs ϐ4]Tر+"؟HLRe)Hرcc]N$ߺu+ڶm+DuK '_IkQtUSkLRcT->|sWνȗ//ʖ+)S'P)}}׮]QX^Tx h7dɜ>JFP^RkH>Tܽ) ^pԙIA c#` ͛c8uꔈN6M':|pAL)R>|(ZؘRsӦM[mڴ[M$6n;wh׮:w gggZYY }h-ؑׯcʕBΜ9E%Kmۆ={ ?A%m$UIt/[ʦ.yˏ~ 2iҤFZTsgDтM$ T3P~v'HdkQ\&eʸ Tepe2#` JOΚ5 8}4(:?u]:uꈈw @Fϟ$?ZdA"O>h'=J:Y Ɗ+}vuem9r @nDEZV^ƍ;*T`gn䟅ID}9*"++FB8X?3IM O9F$u̘1x cI&i#"IԷoߊQ5Ԅk@9p͛3fH&"R7[lXw͚5Ѻukt +:J%;'r\c'RK/^\Y":(OizNLRuJb7}7M&NwѓY2G˦0}bJp XO1nxԯs鯳K"j/TjuwjX +sѢIM #~5Oyx|p]<*,ҩ”kj.|E:ѪYmt5%ǟ5܆u(i6ԫ j^T6+A@i9 [5Gc޽{gϊf̙E.52l"ƮZJ\0#y:'ڣGAH8?YdbHXX*U9sω\N0ADKhS^llz5i֝k.{N4)73I5Ϻ>z\U .BzUQ`nA(_-jc1lMLk Pvt%6C_h5_-uëDz}=0&=ǩ/,7LR^FEW@Ee+[$JT:9s&,eɒEx A65GqT"6ljȑ#Aɓ%$_3?6zU 6L{L2E;U#'cǎȚ57$"$W."gjDԕkkk|ruD&"%z\]H,)ޜ/2gAlѿwk!G .Zq h"pvIƭУ!ܱuZQ _.4iP 5.Z#ub&oNg)g_G}D/O:kHC,xV=5c{W/`2#ph奶mQ>7k%,st4N['7kb}SIj8.Oj~(IR(Yf"sʔ 5X: cyD.(QVP}ȏ-# PH'q۷HXt).^HqOԗ#9}_'8MYGDiJaʁU1IU˖JRI+;E35rQ)zٽSSl~'"E [|9ssVͽxG/SywJw/Erőޱ‰ \!RűPi GR^F%.kRL(̑T;.Oh~(IR-Iql&Ih'.\GbS"y{Fn!!忥}>w 5:;zg2Zso)M$5>Zv%I&e$8eY~TrA~dӡ:g6t/NwJl&IjK%D:lY3WZWl{ҩ( 5@hh6tA;x&ָyl"fqC` =Tv.$A*0 V,-d4k7 aj2,s% H-Sz?qѝ'4O]5bjJ%t^LK|A#{&<{]{OrF@䶘 㦬m2j^ ?=QFyP> ]~z/q%إN%ʅcE,]IR?0x|$kdΔ>ώIE b ?po"mk:yL T\I,&m{&ƱTJZ^f? Xf³TRi7&1Ti8aSBu~s'nt邨0Zdա ifjBêčT&Ʊ/Ti8aSBB4 [)o+0)LRMeX`j޾$8e* g5lVh#qm[> IQ AH'p鏀IvD݈S2I5LRᬆM] MstӧҤ =BLP!-_f*U4s5\gcg"-;!22sq`jcX6yx }ٟY#ь#`DGc][Y}4 ~/yrH۩[wB)ˑĉ>5k7_2x,J< O\UVy 00C-E/*+7^{38`?ujRo=@9Qx6oX@aPl4Ie vHpF0xosó-k{{o^i/XYJ {vHD\1I5>I D k8<΃S_[9B> (V$/$3'Et쵨WY.])< "{:&^"""}ZϟPV~$ՐD(/Im~NtJI$UQxY8#@x6;7̓"}a^#p^)ldu[t,ЩvcѨ`'K4^A2 ŋÝKۿ!KĠ~]yw)SƔ";x&ָy0IURK gg߾|/ ?0@`-&ь#po/x6T ےqbD? [!3m?wG-c%7G΢iۡ//#zjtl5<vq-ml(R([9I|h( 7P{HjӰ}GRU,R=g$UZ<`8{x@5theho=<&X%KlNN"Vz֔)g4G& bMM}88}J,b.Ƶ:Dxxm&'56I|fSQ)@i'$}?gB~"YssQa酩6I5U˰^# >oa%Nh.NզMZAiǦ̛zF^`9N2͡:3|",\Uoٴ}TP玭}жX[[cpxE4I$=f !I%tO$ߩ/~ Ѷe]l8KQ3aSWyW7mDyLu(؟Af*<`Lxk͎ Z[ K&"Ax_2eꭒқ:]t3n Wo!}S:}BMk:rqY*k86Xi/e͈wIR){t ҦIZ*ߴau߾PoLM]o?/ W:rejgi0J1fD TAAxu+<׭CkZ;8 WϞps0UIWIM]-A )!u+npZ_ٟA}LR٘G3 "kOwUx$I^=]ڬKM]%հK[L($E-(:w'f*<`L]IFPپ]_]m,ٽRo,M] Z_ ؟A#ь#Ȅ$5sjrwGǏ1YY!C͚"U+$IS^Im7uic?~rB$UZ<`BR5*P*aE>> DGfȀ]_?.THui83I??A9iʕC}<{vi'0Yjg>fc0&$5B==񒢫nn{NQ*UDt5{vNV%ԥH 6ܹx0v(ПcGrs3iaҌR?3Ifc0&$UH8 rW}254i朻ؗ(aĨě4ӨaSBFG~]]RT9soH,<./ <0(ERckx_/B)[VDW:uuԆ.AqKIT͛B߾jgJ1fD$U(;&eԬSiDXUd(. jԥPJM^b*m<`C`КFWڰ^!vŋDWvEҴifBԹIC:G+]?a ߃Y~*ީ0# +KDWB@ԗ/BvE +"jԐu>(@T ig^_5p!$Uu&cF@MզM"tVT ±wo2fTӒXW C૿?i'O"-~Z^\scFI|F`E%]׭"CBw&EEt5Sݺn !.7h*f-*:4Kz#$ cC 28n^*"wnKDXmf5=Y#B _kVBEflQb&?0;w*HkD`` ҨfnV/<5 'L0z~c3m}X;F"CCfvնٳ#Wp)r4x7Qt\6,y-&|F0=B>U*k%2թ\+S5R5P_#$UvHY #0 @P +~8u b`L[7]M?<FӢґ#[x&aւ`x՞k aoj^]foFmggDGF"sÆ(HjoȎT!e#( Et 2RL4]:8t ~`Wr dA|СxlXSѣQd,.f6VB߆FP޽dkzQRV(9:tuʔ/;>@?9#"7oxn)!$Ք0#`x RCUr c.oF5%1I5SF2j^6jZKU.]`cgg ԄT5YueF@>ݽQ_DWSD6maM_Ҹx<}:*9:vD)77$ILb&fl\^#0dj& kН;ZPR)"j=4mZL;t5b#!fZ^9!$՜kaF /_ڵxMvjtq& owz "=Hٝ;ţ5 $U VbF`xHzU+ ;={6sfgeqD _i~~H]*9sSTI`F`ԏ;wz5nED@X=iS]\>$jA+@;`:!K5y #Ȁ@TXl.~i%&ϙz!WH# 3w /WS3Efg"$UQxY8#0D Sx WTJ$IA](:gZs~35/I0@Bo'OElfUr FݻҤxy6[6TRV>b| kW8+nsSSє)"{w\ +;`$ h`sD ݻ }RtUm:E s\z.D~KTxrF@nʍ(cFagef& :uc~/Q}/w/2Ԩ!<,Hl&x~F` M<vu/IUa5; :76Rp6#0j@3"wͮ]El*ro/.[XQ 0 _Z(u M,0IU\0#@D` ^k:|}[ ]"J(5mggڸQ|X`8> =LRļ@F`L ˗YgXBC9t邔y󚖲&' [{@$ːa, &en^,#0#0@I:Z2#0#`Q0I(sbF`FPLRa'֒`F`BIE0#0:`;#0#XLR-ܼXF`F`ԁTu؉dF`Fምq BIENDB`signal-estimator-0.0.9/doc/flow.drawio000066400000000000000000000233701452044147100177340ustar00rootroot00000000000000 signal-estimator-0.0.9/doc/flow.drawio.png000066400000000000000000001771631452044147100205310ustar00rootroot00000000000000PNG  IHDRSK!sRGB@tEXtmxfile%3Cmxfile%20host%3D%22Electron%22%20modified%3D%222023-09-16T16%3A44%3A54.255Z%22%20agent%3D%22Mozilla%2F5.0%20(X11%3B%20Linux%20x86_64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20draw.io%2F21.7.5%20Chrome%2F114.0.5735.289%20Electron%2F25.8.1%20Safari%2F537.36%22%20etag%3D%22Y6mteIWMy1sJ53It1Mus%22%20version%3D%2221.7.5%22%20type%3D%22device%22%3E%0A%20%20%3Cdiagram%20name%3D%22Page-1%22%20id%3D%22aOeR4vwD-BXEJHeXq91-%22%3E%0A%20%20%20%20%3CmxGraphModel%20dx%3D%222092%22%20dy%3D%221965%22%20grid%3D%221%22%20gridSize%3D%2210%22%20guides%3D%221%22%20tooltips%3D%221%22%20connect%3D%221%22%20arrows%3D%221%22%20fold%3D%221%22%20page%3D%221%22%20pageScale%3D%221%22%20pageWidth%3D%22850%22%20pageHeight%3D%221100%22%20math%3D%220%22%20shadow%3D%220%22%3E%0A%20%20%20%20%20%20%3Croot%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%220%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%221%22%20parent%3D%220%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%229tubdVezAiOULwdNUIrU-17%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23f5f5f5%3BfontColor%3D%23333333%3BstrokeColor%3D%23666666%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22460%22%20width%3D%22320%22%20height%3D%22250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%229tubdVezAiOULwdNUIrU-16%22%20value%3D%22%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23f5f5f5%3BfontColor%3D%23333333%3BstrokeColor%3D%23666666%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22-70%22%20width%3D%22340%22%20height%3D%22250%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%229tubdVezAiOULwdNUIrU-1%22%20value%3D%22%26lt%3Bb%26gt%3BIGenerator%26lt%3B%2Fb%26gt%3B%26lt%3Bbr%26gt%3B(output%20impulse%20generator)%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22130%22%20y%3D%22160%22%20width%3D%22120%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%229tubdVezAiOULwdNUIrU-2%22%20value%3D%22%26lt%3Bb%26gt%3BIReporter%26lt%3Bbr%26gt%3B%26lt%3B%2Fb%26gt%3B(results%20reporter)%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22310%22%20y%3D%22280%22%20width%3D%22120%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%229tubdVezAiOULwdNUIrU-3%22%20value%3D%22%26lt%3Bb%26gt%3BIEstimator%26lt%3B%2Fb%26gt%3B%26lt%3Bbr%26gt%3B(latency%20or%20loss%20estimator)%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22310%22%20y%3D%22160%22%20width%3D%22120%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%229tubdVezAiOULwdNUIrU-4%22%20value%3D%22%26lt%3Bb%26gt%3BIDeviceReader%26lt%3B%2Fb%26gt%3B%26lt%3Bbr%26gt%3B(input%20device%20reader)%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22480%22%20y%3D%2220%22%20width%3D%22120%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%229tubdVezAiOULwdNUIrU-5%22%20value%3D%22%26lt%3Bb%26gt%3BIDumper%26lt%3B%2Fb%26gt%3B%26lt%3Bbr%26gt%3B(output%20stream%20dumper)%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22-50%22%20y%3D%22160%22%20width%3D%22120%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%229tubdVezAiOULwdNUIrU-6%22%20value%3D%22%26lt%3Bb%26gt%3BIDeviceWriter%26lt%3B%2Fb%26gt%3B%26lt%3Bbr%26gt%3B(output%20device%20writer)%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22130%22%20y%3D%2220%22%20width%3D%22120%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%229tubdVezAiOULwdNUIrU-8%22%20value%3D%22%26lt%3Bb%26gt%3BIDumper%26lt%3B%2Fb%26gt%3B%26lt%3Bbr%26gt%3B(input%20stream%20dumper)%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22580%22%20y%3D%22160%22%20width%3D%22120%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%229tubdVezAiOULwdNUIrU-9%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfontFamily%3DCourier%20New%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%229tubdVezAiOULwdNUIrU-1%22%20target%3D%229tubdVezAiOULwdNUIrU-5%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22380%22%20y%3D%22470%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22430%22%20y%3D%22420%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%229tubdVezAiOULwdNUIrU-10%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfontFamily%3DCourier%20New%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%229tubdVezAiOULwdNUIrU-1%22%20target%3D%229tubdVezAiOULwdNUIrU-6%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22380%22%20y%3D%22470%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22430%22%20y%3D%22420%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%229tubdVezAiOULwdNUIrU-11%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfontFamily%3DCourier%20New%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%229tubdVezAiOULwdNUIrU-1%22%20target%3D%229tubdVezAiOULwdNUIrU-3%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22390%22%20y%3D%22470%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22300%22%20y%3D%22190%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%229tubdVezAiOULwdNUIrU-12%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfontFamily%3DCourier%20New%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%229tubdVezAiOULwdNUIrU-4%22%20target%3D%229tubdVezAiOULwdNUIrU-3%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22400%22%20y%3D%22470%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22450%22%20y%3D%22420%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%229tubdVezAiOULwdNUIrU-13%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfontFamily%3DCourier%20New%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%229tubdVezAiOULwdNUIrU-4%22%20target%3D%229tubdVezAiOULwdNUIrU-8%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22410%22%20y%3D%22470%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22460%22%20y%3D%22420%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%229tubdVezAiOULwdNUIrU-14%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfontFamily%3DCourier%20New%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%229tubdVezAiOULwdNUIrU-3%22%20target%3D%229tubdVezAiOULwdNUIrU-2%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22400%22%20y%3D%22470%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22450%22%20y%3D%22420%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%229tubdVezAiOULwdNUIrU-15%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3BfontFamily%3DCourier%20New%3Bdashed%3D1%3B%22%20edge%3D%221%22%20parent%3D%221%22%20source%3D%229tubdVezAiOULwdNUIrU-6%22%20target%3D%229tubdVezAiOULwdNUIrU-4%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22460%22%20y%3D%22230%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22510%22%20y%3D%22180%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CArray%20as%3D%22points%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22190%22%20y%3D%22-80%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22540%22%20y%3D%22-80%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FArray%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%229tubdVezAiOULwdNUIrU-18%22%20value%3D%22frames%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontFamily%3DCourier%20New%3BfontStyle%3D2%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22190%22%20y%3D%22110%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%229tubdVezAiOULwdNUIrU-19%22%20value%3D%22frames%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontFamily%3DCourier%20New%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22250%22%20y%3D%22160%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%229tubdVezAiOULwdNUIrU-20%22%20value%3D%22frames%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontFamily%3DCourier%20New%3BfontStyle%3D2%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%2270%22%20y%3D%22160%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%229tubdVezAiOULwdNUIrU-21%22%20value%3D%22frames%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontFamily%3DCourier%20New%3BfontStyle%3D2%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22470%22%20y%3D%22100%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%229tubdVezAiOULwdNUIrU-22%22%20value%3D%22frames%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontFamily%3DCourier%20New%3BfontStyle%3D2%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22580%22%20y%3D%2290%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%229tubdVezAiOULwdNUIrU-23%22%20value%3D%22results%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontFamily%3DCourier%20New%3BfontStyle%3D2%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22370%22%20y%3D%22230%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%229tubdVezAiOULwdNUIrU-26%22%20value%3D%22%22%20style%3D%22ellipse%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontFamily%3DCourier%20New%3BfillColor%3D%23fff2cc%3BstrokeColor%3D%23d6b656%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22320%22%20y%3D%22-120%22%20width%3D%2280%22%20height%3D%2280%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%229tubdVezAiOULwdNUIrU-29%22%20value%3D%22loopback%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontFamily%3DCourier%20New%3BfontStyle%3D1%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22330%22%20y%3D%22-95%22%20width%3D%2260%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%229tubdVezAiOULwdNUIrU-30%22%20value%3D%22output%20thread%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontFamily%3DCourier%20New%3BfontStyle%3D1%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22-60%22%20y%3D%2210%22%20width%3D%22100%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%229tubdVezAiOULwdNUIrU-31%22%20value%3D%22input%20thread%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontFamily%3DCourier%20New%3BfontStyle%3D1%22%20vertex%3D%221%22%20parent%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22670%22%20y%3D%2210%22%20width%3D%22100%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%3C%2Froot%3E%0A%20%20%20%20%3C%2FmxGraphModel%3E%0A%20%20%3C%2Fdiagram%3E%0A%3C%2Fmxfile%3E%0A[ IDATx^xT_$h N/V(P!PݡxkhS 9%{wwޙ99̜۷`"  xB^G+?GHc~7:e@г{pK[BODpKg7Hkh 3C1eHHijG(Ȍo ~Ĉݒ"~!w_ n<|z җ{RpOSh% PLe4HO $GxISfGT9*&ׯK|r/=]Q$K_i!^w  S$@$@v#s<8A0I*ʁdr!Nx6!44O.ٓ+~D)r#]ֈ?d$@$@Ab5V <8+nnG#CwGH`$@$@'@1e~$@$`hː6ۧHal}t^ߋt#W=ECHHCb<$@$`*vHZ'6A.lA$@$@%@1e\2 0-۾?.R{C<ĆoGx|8ބƅgn Ŕ1@+HHi\="EL&ɽQal$@$@'@1e欑H@гELƠ9*NBB̦m ' =)3f $@$n+hhrb1nMl (gIH</"SN7!Iӵ " NbJ;C@$@.Kux2 ^܆D #{m#F$@$`)1 <xoSH\Yr[\ D$@1A$@$`1 6q$9#2(El` pS.h6H$pvs_" _8w` \fx[i }PLه3k! ! Hyf:e=ܻ7*|omG$@$D(șl ؚmipOڔx<U$! 0)):f  }p=v SAL g " )fM$@$`jj\; [bSCCʉESuű   2h6 ؓk*gJLWw#{Y ŔA[HH$z_'NZhކSY# Ŕa\ACHH q>C̥iztBBh& p)Gg$@$`o^?ǥ o&1&;8 y*Cck% p)g$@$`|wOD#Ca "( 2vHHQ(E ?ÍÑHK[xle![C HHFbnY xqo/<|n.`Y)<+8vVI$@$(S"zIHn=2!y=}xO#s>7 ؍ŔP" 0[#_ٞ7 wo^W7*IHEbQY/ @Óxrd4i4#i2֐ ،Ŕв` 0/g!Q8XԼOCpH|dkfu$@$@"@1(H L^&32-8(7ά@~4aHHf(l 9 \ţK9/Y6"m޶H7gg|y[UK!QbZݪD$@$`.S% xp~y4Yƪ{ڍ;ܹȥtHI!  s2h= NΩYH$ R/dQٕjuƹ "2z6/^rE1kdL>qJɳSf-A:74Nmhۼ.M8qhu4:1O;tJ۷8u zҘ3}0RJwWRJb[+'vnncI!cAVbU1" p)`g$@$`\7Ey*EFF&}C1-9J–U? ~mwbܰ.5h n};7+$DZ| VߥʬQ,~ް|~\'n܍mPnhylR?FPN%p1u.^EbٓpYJu>H$@$`^S-' /Mr}3 f CV_ \3y&S25w8yN"Z6gj#9/ZNb9T8j~ {Gjjիg?UȮE(Yc {w$a  s2h5 ،H+OnQ^U+3\g"f[kg֣ħlޣJLv:VlECx(T,[Ta:bq#x橉aXd=FO"$Mx943:郶mKMmA&͒:8|C*,gIHLJbʤ$`KFȑ#U#ԿaT]r߹L. O=Ty[ʵ;~2grJԢ9кYmLMŻ+SmŸFy{<ӧPVU(^+Ϳ!iÖs!}29ץ+pw5ݓXUVv_8nz c-h|H( A b1|H+]H=oS6ɇ~VDeLNǢFXOꒈ)935jpg:7oǝ[TLL ?%7+{\))|>t3xݨnյ9-Ч[K/Smʟe#xkt8:WsYMmL$@$@1eNj N6jB=3uEu&J"%LArG[kT\3'G),LLV]^6'fkhH=p.^CN5a.&\ti=觑t&NY2׵*E?C,YbJei;V"K #L z]v07)s֓8ӴYOfJRzmӲϦxppJQ.Dbʅͦ@L8D5>)=鄉Nzm˲xϔ-l 0) C < qC#Mìb[:aX1 PLُ5k" Sxr} N!C*HF޽RGF2w94bAb* Na<% <)E%-]Ϫng!@1,d;H@uE ~E|5ms6_$Jվ6kZpP(H pRgg#pq^ &'XǍ3+ٱH~?0/)8Դw>Ry5mm>joY PL9<% #|tO.-G֏4?&O $M]Pv  [L$@&pnK )q7u;a|`\8<jjX'r&(\l4 DN:{ƻn@$+ϪZPL%4G{xo2܈ʦ7ݳ2Rx7]48G#@1A$N:;ûƑ*܌`b pw xnIȊ,"$`8Ss "8F9H0><21ɝ~ tt-4HH(˛  yK;F޲=Le==w`*T]ڳZE$@$`SpM  #xp~)C,elCl{x i4uH#>d \Ŕk'8CDEWĉKHG 44@KȄ&VcF0)CF1pR7h+x >5yޕ]H#U]ܻ^}dm110h: b7 'I!\1MGKcϑ@xV5FD| Mbq$`_̵ [ǾCb l|l2I=-LJI :w?H(?ZOम+N/,>ىLy?4sW/#?oڬNL%%H(ZE!I!]7_ q<N qH*V $8/ٓ+x+ ា(%\> pՋ$!r wJ$Iݐnq ?:g Q$rψ* `}/Dyq!(>ӗ@4u`FwoPL/ `AϮ z'y%O$I?a OBD'5ܒGdY@$@$(l mPLن+K%    pG@ ŔCH8ۗ7k# Ue s2h= J8Y Hn ŔCH8ۗ7k# ` s2h= J8Y rry$@$@$@$@$@!@1e,HHHb$1"$`hSv#n_ެHxV}Mb$+Nda$@$#1"$`hSv#n_ެH#}Mb$+Nda$@$@$@NNb ؆ŔmT   wĈ PL=4K}y6 YU07)s֓8늓 @8ƈ PL=4K}y6 07)s֓8늓 89)'w0G$@$@$@$@$`SRIHHH F#">@&@1eh8/NHHgUH(?ZOम+NF$@1#">@&@1eh8/NHH;H(?ZOम+NF$@$@$(l mPLن+K%    pG@ ŔCH8ۗ7k# Ue s2h= J8Y Hn ŔCH8ۗ7k# ` s2h= J8Y rry$@$@$@$@$@!@1e,HHHb$1"$`hSv#n_ެHxV}Mb$+Nda$@$#1"$`hSv#n_ެH#}Mb$+Nda$@$@$@NNb ؆ŔmT   wĈ PL=4K}y6 YU078oZO$s[\9sdh%йsgm-縫DA$ԩSh&0 IF1tv Ss H@#8~x <Hadާr~VL#I]O(cns2h5 vS '@1(\l3 b?   PLEŔ6WqG6~M$@1H H6PLi$@1o<s# PL9>&म)S19 PLi]mIbʑY7 'umNƏIbJ߸#@?&Gr$}M$I]S(cns2h5 vS '@1(\l3 b?   PLEŔ6WqG6~M$@1H H6PLi$@1o<s# PL9>&म)S19 PLY;vuA-6.YŋQJ $@!@1쬔KbJo(cnsoRB/^<-[ׯ3Y^ s 8ŔCR0.n)mۜ(,ۤI0f E@1tPH!( 8+)g,)Gԩ9a„xu1 CPL9;+%pVSYbJ>0yd:%ԪT߾}% ،Ŕв`0'n7)mۜ2eV*e=C$Gr$}M$ڜB1sŔ~թѣGcذa\#s8LLݺu yKbطoEeFeѣG_(WEep2e?zrH JS:Ŕ6~mNSMufB /9]={cر۬}믿D/&///|ذa포ףiӦРA68LL] ޺)_TTPLic/`#o% 8uJhcI?;s)@1Jd"z)WwMjLs(C[H(uG~Thh(ƍt IDAT[S %ݻyqػw/%JFaԨQ} 6Tw&ܹsG5hѢ:.o`M;֭ygϞ:u*~x'NTe?~+VT?Xbڶms޾})S&dKH–V^=!CJ[ҕgmۦa$j>}j*H'WfΜxjÇѸqcny+SYTLݛW(6KBIb<⸫Vg+{<==U}ILɻK0;wjժ˟%ܾ… #{\*TE,Y2ףk?2eᑂ * I)TΝ9s?@֬Yvjٚ5kk.Ν[.-+ TAޝ$I !f=TRga&I9'V1V/ r )"!:1%K RBB4,GJ믐eAq4zJ\t /^VL={V&%I9"PK&D kN9WlzZ$mڴA,YyQPtܻwB&kעjժ+W>U[.\H>?r˗/@-S/b1Uޓ:Ŕ:uJ v=:<+;ʻ%YtUˇ`*rرc{D}=ٽ{;͚5SX]?bJdJXԭ[7|w}9W\H&-ZPbyyN+'ޢ=Ν;ŋ㫯RuJ}ƌjCޣ (ީeD÷="Zj~)^Q9G'<ɠ,buJu*%))W@,=3=aG8T.qjU2m4%޽dӧJ IJ.:tϟ+$L(t R^% !I:Ŕ>cťPLYT)L~)@H1z.M533SabJP8z(>S%:Dy"bdH-ex(;ٙ)Hr,GJ6->3%dG,DzHn\YQY$+WTѲ0!޲&*%+^[lQ7W´?8\L(Y$z%YL"TSrX|R"D$D,SQ&D/_^ GYy(K}gʔ)jR+!{Eވr10E.u/(xpĈ kCٲe/Z~N1eC(ZIbN v'@1ew䦮Pq0,4>:1%_yG -&bJ+o߮jwQ9>rc2[ee)*1%7nTň`{KޕeDVϻI!dD#!ѫWy6!?U |ѤINj)???dΜYȪ(Kwء6oެnd헌ILIeN) 8PLeȐA #vfJJLEJL]p!Pq,Q֩SG-%V¡J*'O3W&D2.]:Lk)l =SLı4î(= VLIYLY1wE&dy71k׮a֭_vŽlq [ $"V<)WVdU+S QǎSըqaҤIo·0X9'IƄ T Yq=r)l[rʶ7QrNIRly$Y2eeTI5jPJ[ʼnG-m.=G󋭘:Zl[Xk׮jK΀ӥqKۄ-dKcyf*_]|N1eF)UIb($@1eOKqDbn ֹ'N3S" +d1!)'"%a_W}=&eQAA}^ʖEyG[F3g'!3f̈ 3`r>J޹%#2"d۟!u # SOJ=J%N!tYB AdMN I:DJ\ɲ9 SP eD|U1mRvX\tU7)UT)&Gi1%Δ.X!GU;ٯ)M: dJ΋9rDq(! PLٟ=k{RXQPLCqfedD *&1%KlڴI_Bi!G+lc1 ^vn5YpQrJV._)ly BĦߩS'@D759잩 SQ1 PL9_Ibʶb$@1eL*](v.-Y#+L0 Y" XFb2^f{ZIbl=AbJS됳把 @Z1U¸x{}wz{&uZLYѰi|sn7| ,Ef`ܰ8rRz /^(]|fg_낙Xg))EhFS0/wI#w>0VD4hѮ FL[)Hq76u3SĔmIr֊U,G8zrʋۣpR(QbD٭pޱNAng8 $ǖ+1Sf.VZSy"dR_\X% dM߷}}P|.WMQ3G\8wFDȚN1e"a}WLɜ<0/WAAu RNKw*4(lCZ1FHVe*~V m 8Q#=~#*Q0m\ >CϿIs(qbȊPX\_je]4j۷S2)]7"nhԬzꌬ;o0׵HGr\L4k1jm"9qpwO 8=5GgO*qߓ:6[)~9b@W,[4vž[ݨJ,\];4W;U #9ӰKȜ%;Ϛ1(T$n\?4Y15gG[0g$FMfm:DZJac_p1,X_(H2^.?魢y6nAt?tn] & .QjcTbHٲBZ!q߸Ub*lDMLyܕq.LLɜs gwoQAStvSwɘ,R4Rz(Ym[[oyŔa!6[DY2_Gp$)Ggݦ `15yP̙VlڏQr[Ϙ!=դwm<~kбSѺc74SO?_E`%YQTTy,\UM"ҥ0"SVdEs ?SCg"UhX,NA"iTg>:y HpɋiISZ1/ ŔwL _Y2fHl#Io۸vh{ϨvX XObzv"(zOS_:)w[HzSֳcN!@1܎{RrQLh'"@skTQn#ObϐGqeH[i*K/QNCuw$KM=ǯHzOS0 Cj%U\y?K"N?ڻpt\<.wIu+R^zI@OSzdYNIR1~2|jn<&SL>{?S4٩м}G!Amf'uؒsDhbjh߯]|;#"vqb },r؅=: @R1UR 5 ?6`ax*H];vOJ I*Qz,߸ټr.evG ? 7H(ws"Nܸw6Njs"MY=v8eؑ[7} U괪FIˎ1wo- (\ ^+S?M5+~_WS/~||Z,;|f.BgO=Dbٰyd̔mWW߼>~]2%L/S Ng=;|Bnh޶3Zc;{R5z>D$߻: c H#|T\~ydSFX 7_EHHf/\xglp*4:/Eaʄa'z >N1+|IL 9rEn,S2~x/q?S ©Ye$Mn]xY{zlxSEܟ~ "*Kϓ '.ߴie*7!m9·E&D@f慯Tu Rb*q$юte]kl`ЋŔ^$YDL͝KΪ ݴ`dwW<V>-b}6w*!;_*qF,^+Ԣ4hĔId"N28~ia69Gpm5Q_:{ߴ|oDy/~VFL>N1+|ILI5Fæm#TTۢELiT /@9E;.УSS,[1|YJLpxN^laU5Yڲ~%y .$2k,,Cdbʻe=TY/1vg]K$')=i,$zeJ+ /o6T[+TI-$agczO0iD. ڋ?-Q͟5 ;~m~4n,*WS)65s}aqYȝׯ\RGOoz2ueJ +egJ[)r3/kV+SsɑW$IR\.2f·}$&SaŘtcE·r2u{ФnEq dldbjpNȒ 5{vK㮥yГŔ4YSDL}!6[${U^ sz,pAҭpTQWMڮ:&d[jE7$uO'9,LxEJo:%Ĩp^k9N]Ԥ/d% ԖZtP0j\2fʊ& w+̔0- \MyA߻{ gO05{R '$`$1տ{;ʓ?/uYJqul`n?iȖE~ϞP'JLɹ?V}TN?~ň~/R'*x&L=@0 t$_ Uu4[ڥw-ϓ(ɲ%bJ2w_w)㇪Kz3$}7&RV|6[ V g|-}u(z *{w"?{Z 'H۾$콗 5mpƦ >1PB$žDɶRZhФ+[EDI|¸s>cr[7۷n=aV/U|$r';dE,'b3[ҭw-ϒ(&򜎀%b۷i! ; >bs"N?g.y]Zޓ:Ŕ+:FS":V./rITueL{*BsKĔ`+,:^r!T'u)\ÂLDHbJ67YZjcZb#K$HSϺMAR1%Ьjm۴S=SLi K0)sA%9%QLiy^]-d${Sg']5bEQzOS4Z#)av{ܵ,%@1B1r.N1{%w-ϒ(&Ŕӹ4B)uS =j%(gǜ.BԸay;$N0,Bt=\ܹXZGqN1X peJ"R]mܵ(2Ŕj+'*4 dorU4PuKX{W-.N> Ŕ\BLH."\}Ճ? k PLYK\QT`3(=N]}x߳s+Q4"g 8.h.cUq)Q#tH,*{џې;?M5+~Sz [}Y?H<%v Sె7Ss 2!gSэsW/_~HGM @ɣmk\zY}k+ׯ_ch8od̂|F hKrIі0+Ɋev#CxiapynZY(.).x]eLܶ> ,9wjb%ʢC> о_ȁ_6iݕ){0Ogl;pvyb.Ypv18ehش-Z}%$LcDHk8 NAFqcIh ,[GƵ˫U`su_6ϩPL9;[0jݰ*1n^ء=˘9i rAչ$IFR1%/K!c1JI=}`̖G>@peRLYI 9\T;@O $$!_#QĊY(>'{lxSwE!@1e_R09[_lg(P8VCO| ƺǢeK;_m_${SL^ǤUJK+gy2j) cR.ΞLe/^`ظi]Z3~~j^x|NMQlElU7{\|Q)&E.Ib%F[BHbJܻ{Gό1w8vx?~]3eQbJMش_71%ߞfΚLyɐwx)gou ">J~e׽м~ EsəҋJLSmaLϞ*1qY~3W @1 ^f50ڻk ? пDEL?N-o y:em}% T]_蠸FLq.$`x*1MTDZiko\zvjaՊTϊ*ߛ7!pwOl9rcڿU?xsT/L :`d%>C aH1SC{17P+ׯUׯoߢc׾j%JȪie@ՙOWJԫYPR5ܻs M_ru_6PL9K IL6{7jPw'C!UeᙩX$%gSft+fmvSKF(}p.Rj$`hSrƢOk\ŔyŔ"d;WdJX*m韛+S3eGbX>wqXir52PL]4֠( kf,!@1"f3'@1e=;3{Rght3x6MbJo]sbNb}'@1p'u)ŔAcPw L"(\l(ggzOSf:mԛŔD<]Ŕ=DNb.zOS6u 7():Ơf=4EPLL PLY 9)uڨ7):wyzM3:){9Ŕ]`S)l.nPSuA{5h3irGr=SLQoSzuw[gtSFs8)=SL],ܠ&^~ 777t~w[hdSFm3SLM`bR5bJ7,Dl!ld6pKVUg#QH5!y=]C6F )q5J1ok1w\~k3HbV04hO>{ @X~=\l# 8ŔCR0&ɓ'c̘1:t(kL# nŔDlBbJ̙3Qzu00b/^DƍkDh 8)p#AH*^z OB])s8YL۷M4#G)S&جYpu\`){Pf$`*5vX+15dNY7)+1 UL͙3V֭[MXK t UVR DBb݂H@[ ):Ŕuܘ(wcʔ)憫o߾EdCi,H]S$@4iƍV&Mϟթ_~$d) `Q!`41UJ4o:tpZ"sa+uZb~ ObH[˄ Ν;Ș1#$_@@6S PLŞtFSr6HM]eʔq:wț7:D$)}80-;wM6prfW-[c…oybGb*vs0ڴi:)&ݝ ata(U qN:@HH \Lu(\&h1+b s nȬ¥PLX@ؙbpES.Ҏ9[fK 3@(1H"!(cnsp UFftgNEbʩƐvSRLi$`o1ui+WNm˟?99jKwXrW!$)m)cnsZt)f̘Cft9Ŕi]GI6(qƏI^bjȐ!>ϟoNP d*Sr%ƘbJ?6'{RJٳ9!jK7sh PLE4KbJo)mۜl)TٳgZjdp.y&@1eh8?)m)cnsڻwL\MxzzIft8fŔ\BH(ƏIb꧟~š5kesB1 nBdr h Ŕ6PLi$֭$Hɓ'I#\7o0h Xȑ#=jR"4b&@13#>A.EbJ)cnsSLU\-[D Vk .̙?iӦ8q☜'bH )mbJ?6'=ԵkTףt$V[.˨Z*8qb$LPј;w 2e|]x9 6mڨ DӦMh"k׮EzjM0f*pBd͚U}&I˗8p Zh$^b3Bb($`SA1sV1qF+&d br<kå-['N'|#FUЮ];|JōW=Ӽys.\ Pbiȑ8qV3f?@VDU^"N< BVr̩>֭[7G!!!A}v-%H쉠;Ƀ={(VgϮ*Sʒ͛~޹s*[V (n{wC' 1c H '4={Vz1f]aM4 Yd3g"E l۶ CppZ7n$$ )Q%Df}t9SYJ1e*wX=)m)cns-}r&<9[V[.uiDbʕͶ@,PLR4PLi$s7}zʹAaŊ* \9&6\,f$`{SgHT(bJ?6'ԓ'OTs-NJ5%FLlb=k¥*@%@1X GbJK(cnsLLIk9#&@1sbJZn]bB $0qDuлIraA7n\>(\'biȑ8qV"߯!jի;NK]H$ :vVdL;yyyA,T<6,Է\+Ha]z17n,WO =S$@PLiS1iժ:K$"F$ŋ?~|_+*1~UN:)[duJDQfMԮ][/l|:+W*6yd̞=[Vh2˔)OԩSFB h`tӻ HbJ#@f'g#@1ͣS1O^h+ l㓀&'D 3f@^%ޖ-[pYuvJJ;vLYsXr+K,8s RHm۶_~V+_ƍ~zP¯KdAoooo^K7 (4dvp6SV2\:rUϳ$KĔVuF.*ɡq" bm;$ӧ/_pS'ZpJbU=v1%ካV $NX#4w\TVM]f)2dȠu߽{WXΝ[+r[.ŔmڴQM(^}KիW弄l) TMg͚U}&IK2rnމbY,^ӦMSOSatcنŔmT0-KVĉ].#F@B]3XQܸq#rp*#GBa%߯˷"W9y G,&$<+I"rt\͜9S:{'){g} зo_E|YQåOR?SdI$b+TtTdԩSGh{.]%K|$((H+#QD޽[]٭[7:tWg0RLc׮]Jɝ1=zPe}6r "ٖ-[arzVl#B\ӧO5PLIet:f[Eb*lDK bJժUK*W.&9 Ut˪"ٲ'JBɓ{QW>eϞ] 0777UUR%̛7OsNU#GPJuK.w7qg+rAlMS%)[y2\9F#@1e7"%[1%dˏl{7 FW;vTMP;yyyA)T3l\)Ha}%yc%Pf;QLٛ8Y # 4!1% z>wSLn@lŔ/^`J~:*VIV:uVZ)IG͚5Qvmu*^xRN^4|pu*W\*Uɓ'cjJDYL|N:5j*T`w?SL9+ԙ\|fD1[Rå]Sy4)YAm|P$d[5O/lقgϪSTرc*̺Ú4idɂ3g Eضm`Mq 0$_^EY۷w)D@Uӧ[T"ŔE\aKwWtC)\l< |H +Sd9) ]z+,MSs.u|-rUϳ$)m]bJ?? "#&Tҥ2b*l.].P)t;MQ;(cnQr MS֒s| :vRL^Ŕ.B1sۏ1cTիWkbJ3B/ҝ.@)u=N3(cnѣubJN_å;]S.v6&@1wPLiܶ%ku>JhԨnQL btw5b\@()mvdKDQyյ")]q:ua uQLhʔŔȲ\--Zxl(lAydt+b6@42{PLiӧ?~ _H1e3N[0å;k]aS.r6'@1PLi^:j֬ yqe%]-ҝ׷2)W6J @1 Hm@Ց.]: <~dbPL$tKI1%d5H@+SΑrNÇjԈ#PZ5C290<.+hJPL̬$ 8NbqVŤr3g7o^?*eʔD1e8x|x\Ǜ42YQpŔcŢr 0e>}ڰx( k.KhS15+JrŔscOb=XSnoly\ Up$5)rf9~|(Qe˖Ŕ- x\ 0ȩ[ͳZҒ&"/ @1)g/^CN賄G&,Yŋ{)02qEş[nylXp!@1=dMH@Sarٞ!/_>޽[U}Ϟ=S:h"vbcLޠA+V >}“'O<>,[&$ )0RL9LOˬT6m:th)0a6o'<Ŕ'YsZ\9ܽ{7nP327n\ϭK(Œ hGb9S3ɓ'͛7!B/_ŃG"HyD ۷x|x-"G˗H"Q{ PLymY3`a{b9~fyz߾}]H5jT5>m4TR#PLy<3gD=?Ǐ~eQ5zh1; PL>&r(S3Ӆ UWD\T*^zbʣ呅| f̘aŔؒ5!MPL9b9~fxZN&˖-^|+te SڴiѶm[h£PPLy<_|A!Yrd#G<>,w;$)PRL9 O%2.K͋%KfէXydeylNC[H\"z<:1onS\䎅Y1T -b~2k޾~O#r\ir.IVS#5C޽Apte᭙iz+#krPX^:iDZ')w3Ŕ]5c;.u;O Ŕql1%1KFc\3Xڟ)e>g)`2?ln25^:6"8ڟ) llbFvCYjXtCdE1e3xV!ұ, jigZ$@1%Me!vл}AvлiqfluI}ұq&Qb05eA(LivW5AV sf ==KtlDciϊ BPyXp!^x … UbQLyQC_Ai+bj5мw+\έ~1̋nF"MLcA74(/ݲe0sL^?~?jc?KW7"O}|W9˶`Rx)j Lp׸5:thnqP([RLWFÇ2eJ9sɓ'Z-Θ1ðwK/ϙEś7+P$.jU։Рj1 =u#Hzơғyru;cqmK|^Lݾy{wlpn4h'D㖝sJL)Pɒƪes>|l=x ?}|xyn޼ŋٳg><† 5kJ(?'x޿_XH=B۶mq5~GF2d@ڵ@=a  ֭SoݺCūWx[`%J~۷իիg׬nD޽};|L*VF Ր aoV;6Eus߽3\ VFV,BώMSz lGe˖ؾ};_D20lLmTso Bƨ sp {ݹΞ*T (ߞ3gM$2; 6 ]v{)rȡSq%5 >/ΤIϗ+W.&W)KgM)RǪG+kو Mߒ$|;35OGܾy w1cgbjbkA$W;b_Z:jwD1z!f2c_ {Xhڦ+n߸'chR :'aŨ\> /ޝ"C3,ۚ|˗/JI׭GSu,e-gBH}~f3gFǎU[lQZ BL֯__u| z5"u>ϝ>Z yc?2d(%2M={8dȔ m@ͺM!S˺صm=*VR嫡kHgy)?;kF,[8{oā3(%QuǶMl> &G0}GAf"De͑oyWɼiTB(ר‡wT?S2X BK+)_%3QFĘЊڿ?,Y ilӼy?~l߾},;wICFS=F,$tقjI딹=FL\!c-IoqI ƟblLV}uĿ/\x?SLSlЫ S9Fvбb1%EPTd)_:Ǭ%'}<,\ W-, sZjҦqU޾oĄ1UxJ ܲC œiХPېK'ϲe˪YhѢ)#Y25f޽[Lٗ"Y'jԩyA%Ο?F$I:H$JUpa̞=[w^ɓ'QX1*FvՈ&އFKSj)eǯj\jdŻCv¶p=IܺaX?FzqQ`ϟYѢcҹ׵%݃\y 2HgX:LU(E6=שE%.΃KOM5G^v*BP̔$?+d@A?zZ*"H' $PR"e H ߧUU "ƏD,tZb*)ZΟVQled̒}[zgJLVRW/+L1ׁX#b:Lj::bQL}#yx3%T{QdO=1%оR&Y`lXT7ҿ{kX<[ދ"D/j֬%Px=g {/,㓽MT q%:{,ŋ7uΤ\!B4kL6R@4iRԩS3f_.] UThܸF+bZ /jԨ,{AF$01u([(\6o _: "9~V#7{G|nP3?;6{oj߮-k)~vBL? /_h {U{\ QwɬӱMO5S˱N_{l$?ۚ1%3G"S2$>-GfCey{SSVO\lWJjetl dSt|"hW)?eydd*6}˒51u ]E(_ݵm^bkA$W;b9"دsc/7b2k4i9R3&L2 {,3SӷTu*سc>qZ$qX?Q\,b?'^Cz/t"߼y#F,Q}#"j޼94hFE$Y2~k2dHAݶmJ*Prš(t|e^KI'SD;wnuD1x`%T@Ո&DhI,JF:eqM%T,u[-!62mXS.8~(ɚ":̇y+cҹj&1UhVz{OPEY69XCN 6SO,/7D;wDUKf9C¦Mr+#rj֤IxW7"N?9Ϝ˪z4UڌJ\-? Czw@#Ւ80n"TpPĐl=`Ԡۭ4n a„1ePu9r5cHL@,_#ŔnY*d! 2(`kҡC_P%d"ote2X K\ei/zfʞ?v_PиEGuk0w"F=ˡWղ[2;+{#._g#ľC}!sv衽|I-5eR57C#S=a 1O_Ti2tm\I_4YJuzt%xr5{HtXNj铜Wl3"d_,Uz_dɑG?)C 7W-=i䴴nQ>G͊;u _m:QDkÇ[:rZŔiK{s`L̤,?KEd:~H}wf̊~C}.cVߚovėXЪ.og)GVsAG!د -RL9ɴb9<{ڲE賷tFjD͗Pb65sxiﺺdu ){̔;dy,P SΧ+˪EfoD`h4g)#[F16vG _<)\`+t.$ވ.YSL邙DbJ'& u&s Vb*кitfoDng˧?sfYygPL9CZ#vл}Cvлi}_;)Y\c#8 b6A(L`d7T똥E7DVSC Q/Yl>}:Zj%jsc㚦ן7Ցf.4]W%fΑFDӥ![X$zvh[7;FM߽UwO#|fK*%?szW^ʈ s:mFܺq }DԨݿP^,]0 S;t{EѢEI#kD TwC#!}:5U^*-_W._@5Qr-=yϟ?S%eGɼi'DTV5Zt?4DZC{q?z1DQֺco9<|gro["P^S\2`1߬u'mWwH c&/z/={fj׮](Qb&}m@FwgOVHN H|EH]|Q@!Qhi֫W/{qq uD&m~is[}-Xq~_۷o}r_;KN~nTry=;\Uaá[(TJV{!}3SXqJ^;h+F™uZEj־hm{r(p}ќ)x ve=оp`6|e*@"9~VvlZVzc咹H,_5պ jbƵQra@]Hj <2MX:[F]:fnfJ:r1×18J6Z G/ ϝW/cա};YnE LI'6j?TeNtDfd6Of 3/YBPHTʼn#1gܹ}; IDATÑ wѵmϔ]5"D:t2d"D{ȑ|^#ұymd͙wWDHUG_ 2{%Ĕ-~7esVd*ؽ}#&{:^8oѾY-b[ۆ=&VF5JإѶIulS #yO+V.yv:*T(,3.^VOwQ nݺ}Wb7``G(- vqeJȞ;?Zᗟ p-^给+!KF彘8kG^M{!^DcE6 KS¹V{(EPBuJ/~ ߹CBlT v䝑8ŔtDlʠ ]"W):Ѣǀ–[C1e/(쵃Ғ M&h-h{w4v>rI =ܹe5;N[4}Zdʚ $Fa ][d^H '~Pu;! e ]`Xr#CH8s_5錘 WT޿K5kw ڰz)L#'!s<m%΃ˠ}s~x-s7;t0jFcjfK:"W-Ck_$dύ֍bKtND԰aÔȓÄ P`22H${Xr+q\)1f|d˙O;5 댘R2'.~l+"g1R GP[S9B<ѤvY=b+l~f-Wrmbωv;S4kW,ݿnFݦje&ΖQ6jdKςY1aDߥs##2& +T޽}wުSMS- ҩM)Y:GtÚd)SDԛ7oԣ?#OG8[^BDI)sXTYsj1ըzIo']G"n~/151%K2gC.[?LhZ,*T5[LI:ļ>SVcĄ"zj݈[LYǏLETu]APX["&d]=G Ǐ _3/]kb*[ʘ1Jl-WT"j)Oеp%ڻ|{*X;Hbjhհ2V{a-QL9j {p2kZƁF&m1vֻg(3 tﯭ̰ˡO=#D}٪TS};ۅ32f78A1u;xSgd2c8{RyS=dCBQԲ*[dssBֳ },M%=TΈ)<.6&;%x)*X?Wټu+{̛vBȅj)իW~ً8bo 9K5ƒsV˚n{x_|k|Br)-V< {͂+/\9,dI,Ԣr/ [ߚ׫e+;gR^_2r@W  GOU kuߨNX} 6,4hpi9-dfX!KX޿琘w'SKU[bOH8)ZwOxJ_ѰZqqRuCzO%]S}uGfjˏ֝zoC`5߷;Ŕa0rW;(;oĔ3Wm=r[þ]Zc,T+QU)Gx>q.@m$( ,{Vl:mfĽ;6a]9NEAmfV,bJC0ah)2† F>eІ=gT#,CȞ>CƫSd}(?B601%YҵmN4'H**ѮIuROLm\ s(A'3H_>Lo!_.N-%.;u+cɐNoE RW8oɓ̔fE#`PN z#!|'U|͚OT,ڇ%Ssܩjjߙ‘MpŔH5o^GٱMĈ#Y(ؽ(bJӖd$,8o7wĔZ3̔|wdLuzԟ 2(6O}_jFҟSY"Ojt3\{[%AIGCيcKL!=ƃP=/)֧͐廥o=BLKAdf DI퐎gѤNY9~]-^})Gb\Έ~Aiһ̔51e{ئqUdU{>^ѹPTp=5Ϲ]Lq2#E$> Q ;C ۨA'n|S[7”6;_8{[ǿ smV˭>zh,P%TБg(- Y.#[7DСIQ2`/y\ݙ_`q!_Dل-KX+iL ZFEح:r2~C} Y#K^v9;5S{v2-sUOTqϔ$&@!#zŅ'IF-ѰY{͞Y S2Srmڶ^N鎖Z}/ltZwo۠N{oi}1b`Wu"e~-Vŋgd?L{9BfeAp"jW(9mω?T~ZBK r oLYDTpϔo< ^~ *4cǍz[s{}W,#)!v)vcdY'Zz[*V.Fkeސ홓Aj-f[~H_)mn9d4 Ye~d6Abhֶ;֭X rhs?_ܫ="E}Ǵ| G#"%".RM'K r>pquqm-QI[UJk_R[m| QN;Ǡ^!Er/ s:mFz<…G(Q7) Μ=7.VeKkwDMpU,[E]:l L™% 5g)߽5=.3xP\ׯУ}cܼ~(Q2D=9>z'RJW/_d4hf~;3չU=DCq^O~ "DbJO2ѣ PB~\A9zW SO] Eĉ@5N+̥Ñ wѵmϔ}ؒ# /tG :b3'Vl>HCZȚ=骼G:'@=PV#oLߧTbn+8tz4"e f@.Pr-̝6>+GCF嫕΍#C}G /A"]?Ǝ=9dANQRM̞:'ǜe[|S˺N3S23=bܲ.%M.g3,"c SUg)j\V1ΟF N1tt5h5oG4k &Q^p|we?%=6D1QR 4Q.Me2x3Ŕ.SeG;(P%x=czےp)4)?|-B !Ccj&[aoML 'EN}ދq`Sjp26/neظ.n?]L29$ԮPTFf-L#'!s< S9B<ѤvY=n+]e+րbJO2qu;cqn{byZ::هsV*]ߧHȔ4 6=۞خ߽ Q= A$hѮG"bJt l)chnD$ɗ=%Y~]Ǯ*1%MGOLYs}Ė ̛vBq~|=*Lڷ(!b}(XŔ՗>J;\$>.6&;%S6?SLl]uAX\)8YbFBĉZQ-%r]RTS3O)?%'%Jڋ%k @`e}yҹSQ^S#bsl-֣)#9f@P1C{?{p.FO#?Vĕ-1\?lXNMqxNtaªٱ'QFdYߪG-j+v駞uDLq}ZScPfn=T{Jʒ Jj־](WڸfNQS2#gk{L@bʵSףt+ur<ŔbJ*=k,9Q:ְY{Q#N괩WaUiof衽v<-KbI+yz%Rˈg!v)9ݭO<9i={Իbo޼ưpANiwa„)r,z"njN=wfj  gOsCu<(GK3 !t,'Y a1%.{#d&:`BNA?лss<}X`qٲJYW/_PP%du 4?g=F,}1b`WXSe+4?SL1qzA~]PhُK1eS! ip$NYӑ"EF׾]3sG#"M10)k=F"%ul=S̓2q?SLyxHQꍆz#(iʀ˫L>*K{DZz4"r4`DXf=D<7u;OVf)P.#w3Ŕ\֣ty%d~Tp}b*\ɝ,rab`eitYA5JXFDڶ!dC,HsШJųcܕH!nڟ93 ;bЮᑅӣt7(S%g|ڟ)\i-m3Ŕ=J=g׺;_Z).tlDŵg)׎bL9ZjAGxSbIa冬g)7Y3AWP5NZƩ>%҇WbWwڟ)_^;)[3v3hn[QLy%u^:6"::ڟ)`Dfə)K t)^'u; \){Cvf{؈xZL1bqfL9ZjAGxSbIa冬g)7Yrf>Rl]kB:bJgސ^:6"൜h3`̔_]9_5c) =tlD۩gLyvSFggRk:s@GF4M҈0x7-Ĕw[NXʼT֧l\lYw1厊0O 0)#0ҳ ?~g̫e˖5eYi s2Y{  PLi (Sb4 #@1u&eHIbʝϛbJ{PLÙ Ŕl x0)cbJ{PLÙ Ŕl x0)cbJ{PLÙ Ŕl x0)cbJ{PLÙ Ŕl x0)cbJ{PLÙ Ŕl x0)cbJ{PLÙ Ŕl x0)cbJ{PLÙ Ŕl x0)cbJ{PLÙ Ŕl x0)cbJ{PLÙ Ŕl x0)cbJ{PLÙ Ŕl x0)cbkIDATJ{PLÙ Ŕl x0)cbJ{PLÙ Ŕl x0)cbJ{PLÙ Ŕl x0)cbJ{PLÙ Ŕl x0)cbJ{PLÙ Ŕl x0)cbJ{PLÙ Ŕl x0)chb*UTx!RHSN T^;w4DJC1$F!JS^iVVH](E>|"~ gŋq̘1E<})͑2A !@1!b1I<ŔdML8q[ƨQЩS'ܹs"rZh*0rH,X>|@ܹh"Zyf >22dH̟?ٲeS%HvB4i &֭[!C?07F9жm[ѣ&Mp©nwR+VH(V^hѢ6ŔaL LbJg̎H PL˾Ĕ,QSD L0ѣGǗ/_"DLJ6mT˗/K… ꐉ?_W\QMw,߿?~W%F 4Ŕ HbJG̊H PLT PvmԫW_wءfXDR SLjjKE6mZ5f .TWZ/IJrŖ-[lxK)PL, (ͼHŔLlML%Iۃ!ׯ_W{D(~'sE%޿RJaƍ%*T]yB?WR",رc-?׫V0BjKW͛7OJ2w^C29X  PLY x?)c801%Pz }ߖzĈj<+Bx?2h L!{dɝ& 2kԭ[7dɒE.!{vޭf,AUըQC$ѵkWt]$G%NX^so߾UgKVʔ)()b H@oSzg~$@^MbX =S*gbʳҒ hGbJ;LHinr51PLc)}83 S+KD$@Ib8v"HH~WV& ^Sk[֌HBb(`9HH4%@1)N&F$@$) WJR$@$`(S2 C$@$)H2  k($@$@^Ib+J PL, V("tHH83E  0)S% ̔[3S  Wr5aO$@$@1E  JS^iVVH EbP`aHH"@1IC$@$`}HH+ PLyYY) 0)C! ЊŔV$ g$@$@"@1e*s$@$r vfJ$@$jS&IH($@$@^Ib+J PL, V("tHHo x%)4++E$@"@1e(s0$@$@ZҊ$! }HHT(LenVHB3SnLIH\MbՄ> }HH+ PLyYY) 0)C! .]vVZEF`S .DNb ,Y29  HHk QFEȐ!q}č?~ċ/{'+B$@$` SưKA$@$QF"G/_"TP2dzALHHHH޽SذaUeeHHJbʭ9 dvjjy_СլT^Ά ($@$@^G2;Y)3-+D$@"@1e(s0$@$@Z:t(g4HH%@1E  :įYf={6„ ucHHAbv`)HHwy&w.0w 0)%0/S0//e@1FfH Gbp&aHH5(\(RL, PLڬ+ PLy)۾ 1 PL., hNbJsJbP`aHLBb$f5IHbʻ}bʻڑ Ŕ1R (4Gj) eH$(LbhVH((۾ 1 PL., hNbJsJbP`aHLBb$f5IHbʻ}bʻڑ Ŕ1R S{w#S\XNCzB nhڦJEs@PDo;N|6QI2fADI~bS3!R|Gu7ȑq}hT-kq$I[\mj16O7o^,ϦѵMnB%3o!$L y ս(tHHb>@$@f"`D1e/K6k^mh٠ ['ș' =uTKdӷ rfd/V"Y+=JS:ضi5.~fJE }o!bH̿u*?2},Т~/\~6rzfL$`b\gb$@"`D1պS\"Du ig ѫcS !CTF١fmǀQJLʼn7Pʗ>}žב+]$JVj cߩj)CH(^_lX-~'hVZ(K(E ŔϺ Ŕ왊?!΄b+*#{,nFT~69*bQ~fLU,^S7sŽkqWj6KTMԾW;e!*U6rzfL$`bS&6>N$`.z)GN@Ѫae٩dSd45:ťsfB ;sWb{c>9Bf:Ggdg*N׵%))sWw6Ŕ}Tr{lb\kK$@? I-g"Μ<: -NxQ@&mмmwe)2?9oK9JT%|F{-XFLB슩ϟ?chߎغa_$f-٨U)@& BbnA$@&!rV%% ]Ge~i6H PLyY| pWopb- Ŕ2 PL21X 2YQ 1ev;Z?=H'@1?sH$@n!@1eJ1jfD$@~( $@$`FSϟ=E9IySu?]F%kTD]mϛ 3Aɘb*(H!@1 GB$@'`1կ[+;.:th\?4xԞir)[ \۱$@$$FS3a-_?}l)b`Γ١ nݸe`Ĺ*\ƻ~߹F!>6{浘4v0|#ciH>q-G8irw |S"l? rمw"Et'mW)$Y QF =̙)2= Ob>#   `1tt9iɼi5Z Yr˗/"܌1CzbÈ9 :4i tqqYĎ'SGѪcoĔ<|L^e~׮\BqY  LF$?pn)g$@&%@1eRó$@#`1ճc$K -JAeоɲxMߏ؍)㇪& sBڍP/j!3SԽAbY1|,(Z #F23QL , PL. y AL5[e*@ڍ3DТ}(SomWřG{Ψxo^WH$9\!$Cvb ?}y S*znu.)g$@&%@1eRó$@# bJf -8zADIТ]F3fbT.ߪ~Zԯ// AJ5ΟV3R &98n$L?3'0))&0#EYn?JWDZSG1嵦eH LbaHH@KFSZ։i)z ObJ̑HBb-u˔bJ7̈HPLHH$(Sm_֎H(iH4'@1M 3iWnp$&^iAIb*(H!@1 GB$@'`1Wuᮞ<؄Mk;-˗/V::hzV//)`g$@&'@1er`IC@o1'dKkwDMpU,[&UފÇ/Fx oSB뎽qn>6n'ҧΝ>!CrhաV"l? r*;"U:@$@f!.1%2,Z-W`ElKELM_YsU[w(\3S㧏5p ,O[b^yDLɾU[PLa=IH\$F! o `$1ɿ(] Z:mF\QBkĹȞ]1q2̝5ۏݻ3D{qTLq7) 8NbqVI$@MHbJ@9T'E G~bVe xLWa ۫W/1g[\8{!CBF-ѰY{?2?k3Sϟ=EqD}\Y[qDL}SĮW;n|}tG IH$@$`Se+3SE$?7 ݟ۾iڿra )܂ gL> yxZ'M#߫Ƀv]^ I$@҆#S! rM31yJeb'eL =3&01)U'0OS沌6҆#S!  -% &@1sS@b ИŔ@ ŔQ-M(THH ((BqIH PLy(:ŔH4&@11P&G$@F%@1eThS.)m82  b\ `Sl<N1$F!  PLi ɑ Q PL2ڔbJLHBb*(H<ŔρSL9QHH@cSer$@$`TSF6墘҆#S!  -% & b L\ػ+ڑ ?֖eIENDB`signal-estimator-0.0.9/doc/gui_screenshot.png000066400000000000000000006665261452044147100213250ustar00rootroot00000000000000PNG  IHDRsBITO IDATxuXTKK7*]vw{v׮{m_kcw^;PVY6?Ų</kԷw)#JR): QDGgF&Sk3CY~p]̴6:{ sgfK9:X,O_ofiFDp]^?5m;MR¦I"`@P1T #913tr/o` ߁%O_?4762Һr 5v`0 MLSLE0BD2,4ЗJ98a Q)gL-LC Bh;҄YifWQc*B3㌁a:fL-Fi) (A_#M8cfŸb?s!(4*A_#MÚ 31Ș~p]" /#M~&\=^Qgh0_>@Qy tiފfrn7 C~tX"*]ϱD"#uv 4$7Pb??mblNz;w&[75l@M f||QgA4sΝo߹I˖-Ə۠~@~INN J(acc]ɓtUB |3˯t]EN& 7=<D"$%%d .^xc̙ӧe?m6VDD ϧ(gO!匌$=== sWggM8nFOXxxdTt\|L*355quq-ʨqq8l>t|]HRHBg. @lhhX~a+4\41˃1skoq@Nm[{P{"ޯC?T8dg[MCwws-.\:yڬ\~]:P~ DSgΟ|[>2.SNwҩ^Q-4$,<|Ddaamg4iҤI& -Yvy̝׭[ןUBUxO:+[!v=pS'3x@eJNOϘhsRQ;t͘:I_?z߹ڷڹCXlV£cPOZ/JMK۱e}Q6eKO7׭]Ņbi/H}pJ(Yd\%''J#"#\nɒ%u'_2maȰ>|d[Nvm[׬VJ&^{_zRt#o<{q~[w/WFa}%_LjUzMի%^"""_BDR,Ie˔.O3X"!"SSݺ4i41))8$'.^aNK?o@vt4>a6lm5rn߸jnnur!Ǐ֩]+)Ox.Y3DBD}z5v<>}N}._~-]Wbbb/Yvd樅пx̞ӧ6l|} ]n@Ndbb@d [mQ@ ܽ{׉Ǖ(a| N.^aia!?jgg[b1sk6;x6n^fMf> Rt”L˚G.Nk9̚P Hzfԙۜ/~6_M ׻w9*~>1D"%;,;"[mڶn9qܘ=xD,OaogW %⥗v;cH$fБ'2cXX,YRRn޺}SS}~TTt킂ЀIHHXa#qӖ90ilssHzs.޾q&e+V-[R_}P$JCB6l|k/+W6xD"8u&cңk+h?cL&L&[vNDhhhPd\HHL&"{[[33''DdddXZZږ*@!X" F2aiiJD{LLLN;P:wt7xX,}KWu!fL٪KMM9 11B̶-b82*:!!AsIҨ.ccmM(RRRbqBBcH$ HȰ-enfZZXXdFFҾ{~&DEǤ*Y2W+"bzLlm̨)))\x𑣓HOO/{ޘw3Gs;=w~ʿ._}ezug={1166޶yc $f̚??g߳Kudm{z|*"rrt\lIMLLbߎw=|X8ʥq׮s ?Il6a5P20(xӶ?JLJbjU+دk 'w?1-ۺeon߽QUf&׮YC9!Drc'NY++6ZL3V!|CC˗+sxk7o[,'7/8;3aR鹋;|U\!C{ 4C$ܳٞ7{Ziw7gթUcF۴6mѥc{y.\d"Z]{pH7樁~gNdo1$R ?|Y"Ю¹a\.[ ?xK~&&ƍ3bXjU{g/Gr9:whf!V*rlYe);tzpH|'ǫW߃l'GzY~ƥ3U69155խ=wִ**_5?|pZs|[\5x*9%o?Z1Nvt{ D4fСCfOE&]vo|1c֨^A۷m_*8}.:&\{ aW-[Ժcw>?];}qS>QQ1Ng  ]z{b1suz*D:}mǞ;˕)ݣ[Kih[}H&͞3A7oS^\q3DgϜ f111?~M`,6bbb==^t>8c#A?&ح۷so% ѝ#TV̴&_H)PL<۶lڥ3F˭X†ukFNDx{>/%Sg.0o#h"20П;kZLgtM/^ILJ20wrtJ>&O=jdlV,'$&ؽoic:d2k~}A!Ĥ~y_'LVގ?yUnO<)&#&Ld'HLw̹o|JR=== ss󗯳-;qy[t("rt٭6 {1zSty-X1a3.]޹g?K@$ cX GtgպL~JJ[wkAS|~xxdLll><*J}Sf(qCGݽ1gUܳ}^RGtk;O  =3aѲULHE,/_VfS%1edd0~=~)ӽ^{K$SSg'GcXIM__?u5mWܿ/}RSbP?^uG,`Ason޾`oeeID_W~ Vh7Z :Md9lXkL>y̝_aza^$RsSd/_!".;qx:vh׮ʼɍ1| 'iW_wx vYCCV-ZD"yNs#=ݕ?Ǭ RJ婮'H^ɼұNq|׿3bSS5+x\xqDtνWg?E>e+nԡ羾}4nHD"h͆dc'MzZ6ލK/y|['{ #7Qa% O۵b o͊͵Țe7o%2O=ś?y?߳}=]yy)g/2Mұ#ڶjl?x)dq'ڶnqO/:yx3 ..~ꬹL']ݹrB=sѝkfOאH$:j\@`u^O=sW-373dV{Q8le3Μ&]맟_|xlղ̽w_{Oy~Ddogm-7/3vppАKW2TT>/?u''+W4]~s͆-?|R"ILJŗS9gkcWuif҅s_>w8ycd^څWWHDVV֮|ѝk<߿yMDIS FO8֠A}N>94oզt'N6Q͚5T;3h@1tAy]֌* cF:u0i℥K*URR/ȟcΝZZZ֨^M>KA`f-@ L6{bTpڳ[˕ݿk[*S_gtg.׭*[ƝX,ViwW1_v`Onz424գ3?|,?ʵLΪ ڷi r8ʔ^`KJII} թUcɂ9nL[255ܱݩ#5Ջʵ۷ֹ#s]9t䙔ԣvթ]bX:kΞ>9ysmyYK;83_/L vvG]3*bխSȁ]̕!f4V'+Bw?0e*U(odhcx}6D$wb&{o}fX%llƍ9e8&< M$1l6{έ;:yƵu""owWTrhtVm۶n۶uHh?xٳ̑籱i񓎣3aAv,ԴI#ffWo|;M|NϞ>Y ssͣ|>6J;RN6l6[*޹0[|x\ +{M4TYd ӤI ,9D"II^=|7E*4mhDꍏQ"4$"NMUpZhV^H$ү_} }-.F r\Xe79 0-AN]}@iii7o8s IDATYjT*|ࡣCTK,==F1oJQٷ}޾جyzzzzz_|Bѽ{Zl~Y&Ѓ2oﻺ8K%+W_[44G_|*voRrH$o2%brlKabL$\(']jeQd"J PO2ʖQn5~#̃\ g.{Żxg.јIxNQ#CCo0bdܱ}KW'ҫW[6]iGsU/w+/먝Q}/M lٳA2_wB,ʤݿ%mI )s!Q[*AWgg/((8n gXhD/Qkw  MNNfzCt(4-oGddd4kt6t "pN%?"''Qf:8zk\'8,^luGz˗z<|H$f Ytq\3քUX #P`>CCmlV-1{ =;ޮq͛Ѽi GVׯZ۳.˴8|ժQiFm[tsuɯyQ '%%3}>$_dGU$'g*Q} (l+Y1m$$dN  %DUZ5M >LIpp`9g_ /\JD͛7۵?a sf֩SNӦ;ppժ5mmGڵkC։49?0PlC&*,< 窨SSS-2_9f*6!hyz\i:scR2vsu416r\.WYj'"rvrdXA /ʘbI9ScIq%c32Q?M&>O]`d@bQ]ڷ^/]G8K9Mѡ/^vWoRP(| U65kxnj_.E(Զ5Dk1ڴ%Oii?\Eh5=@50(󗑳‰,PelCO}ZրJ}^`rӥrh~ki _iѣFjBT?T_>Kmko<&aeeILdW^˿N--S>}ZD3kM9WoudOs! V Ғ|M<>FZF%)Þ2a}LL5WyjU+?y^xܱgg+^Qgb13󎁮叩32|C*30cY|}xWo|bq||¥+C͙oS)l6[ݺt<}ǞϘua?|{s*ZiKBiіTX3H`PpL,3LMkud2T _F\c2ԯ $^n?Q(r:-9,Stيkolظ9-5MCHуʕ-}R*ܙ_~2[V 9\9/\I+(0߾LIFL$ͥ)Z IfOuBv_124tasbiX$1!K -:|$qcƌjbl IiiGc&+7tmNIINssV('Ĥ ȳ*]ϏS=Ҧ eo5U?zı?=mx5}}m+UYGWnU󏵕UW-Yε2&&%[\z!|W:c1o1T\\f[277*5ii124}y-k܅+)6maNTw fY|?V5u )omWSzMhRre" 0o>1wݧw/ qxV-[QzF>{ۜ]TR̆۷ ml`VJ>~VC/]Be x\5A:S| =W/[yL݇OF.&'0QZ5KQRr2PHv? oPrude֩c| u䑥C=fL%"LvHpX:j޻'*L\.3kZZZXx0~ۖ}{`6<"I#'N1{2 3ǭk]k|fQ[)==[X8YZ*YBT4(i’asX۶l422";w֬[oђ%? OMKIIM ~Ƅɓh<*::uЩS|O{BٷdkքGHtg%UMKunU|-1;6ovfg0M6KMMY"s;wjr劍6 #G7BQWΘIDݻuP^ڍ'NOLϻʑ7_smu'>|'=FFժT&_}U! eι`jj|бV105q&<{9s[w!"q*~흚|WSTTQ +ﷰ(W } P0gթ]S2Qᑑ*˗kMNIѦU@sb@[wJ[w >vfcd=+^jZAvBpt{hEYcK|HgC/_޸uQ(Wuӱ][D"6zed.\g;U32R)O>ln\_OOHT?+=1lW>zÏ>Q+U(M*}۬m Sf>fI\8L9c'M Q>*H?}JD!^΍{XWV[ڽF.*:sDu{ŒbL{5^ȗȨa{,--,.Σ'N)G~d"jԠ^9brUh-7"(H$wa=4Сt4IeԪsU6rU5[fwo]߼aWӳn,5=ujbgdΟw9 s ,3yT];>O蘀@Tֹc7Wjú5&&&DנuQ9;9=G!PH:kw~}X겭f4899ڶ̌0|̄'ϼ ˓v܅D|񼾽{#aY=f0vԸIg_E[d;?evl:֙y٘ CB^~3p(fNk0-[쌏ACG׮Uo{2?kV,_ ™svg_ ;;u\f$|MdʔvΝ{ lO:Ysn5Wbg٭;Doaa>Ȁ)NDWoܚxybR"_,]|e "bsgMK/WnDt!E";w.YIDm[!E&}hsQA{X,;h+B$ wS5];gYKN3*չff{ρCiĤĄuTP 6l`oJD73ݸzYC*svʅ{!99D w77sssy{gxx/]lɢoi<ں\r:/tGjV?{9 _z#=x<_UUfS&|2 [6o1e%'L=vvRS11x smXfM/3ߦ5CFs{mK266IɚKƌ>}:vL跰_|[fog+HcR5޽"Zlڷi5z?p-k7nwD"WD0S'2vvnʵ7nDDAڱ9(8$*:}Ddaay<έ qκ8soᩩDp.SV J4<2*̹g]424JQ1gpK{?|0*;=d`?"jXQö˟4m6ö466JJNϛ[JiSz_:7q-"ھk]hnjKhȨGOzݲ}7''3SӨX> зWQ.ܶucw!<{T[e *V&V.q{-eee '/BֹC@@{""SƺdIIDTZu+h~si"*/_C#Ts c[&&& Wwf;:jruuqu\9{>yzGO U\?4ܡ]:x@jU6m4@>GYmG3A|Ce>(Uc8|٨Ȩ(5ݳGΊԘf[T*eV435֥q̚7cH$?|jXy*O7k}z8r ʔvж~,?ȏG&][7lز3_}l6I >A>['kڸı*U6ŢR.9u{B==?47fDʕtK()֨^m}o|J$X>_/зW P/ZeUs:c'کk2_cX C}=m:z̾GCBCC'V\iڶjtQjU?uꍳ.z-524lҸA߿zɬx>fTZnw/]oy X[o*B#)֩Us߾{d=mrh~sկy+x:b=%UgFp9{ԙztA!-YFDfLo筸1*ADw.!ڍ[RVۨd2ٷ4Uɒ%LM!55/ 0!!аTv7]PpHdTP(HX?DRKKD$ cb6 ( MNNaXfffn.f9Lpqє cǎFD"/ 0&)LD" MJJprt`V#ʑT*H$eKfV_L Oq--K祴}?RAjjj@Pp||X"162rqv0NzG5ĠPAooaiiiffn..y"(0(8ah``[Fp8_߾dDEDŽ~ KKKPԭ l<1Wrh| ti"+'PLZFFF׮ sVTYҒk7p@[qggn*#cjU+5qqqrq>on*QºD kumkk+k8?3L&esʗQ!6}f)^{nO̝<=-wQLWzG5~s U+-[tٲ:K2yȒ%mJ& ¬Fa -%4m׮M\Z-[6/S4y8sŋ<?2kK<~Tuk7K (E۽sDׯ~z͋W a}Rqi#}o&yOx<^%ԮղEZO4EQ ݐ!~b dJiFlKul׆f ͟M+S&Evۜ&xVV~IժUٰf* hԉoTe#M'T 2\+is{|;s8~E0p]&ݸeQg r%@qf MLK9YV|L6^=Ӳf;!6R BY|;+sHQg@K.e*r9#HzL¯'(b?*x~4W)X=|\8ځߜU0+ҠE'Cx~t\LίzvsbM-lNTX{Ʀf|J.FdRirK %9SiTJD\Ieã@tNi:MT@ 4P&*@tNi:MT@ 4P&*@tNi:MT@ 4P&*@tNi:MTuiDBDIX"28OGODV6DdJD" nJ:/?`"-e[dN{PEB(~,͝ǏDdjbV+"̾ǫP|&=Mo߈ښY8d ,j*:}y_i-"2ϏJeff:SNzFN=.~f4Xq= +^vaeesM*1oBP*Upzzb 37͝3{ELG3w^=Zbr6JBr*yXfML]\\\T֯ʕ fhǬo߾5n'u΄fg?t\H,^,{{/>h*C(T ~&HK+UTJ9rX,́/=]f,x9J{2,#ClkyŋMHDkV5rp_ZFc*"}}}uad2YoAAAIbP)֥ ߿E"D"-$S?x}O޽vڡ{^v|uw W8dooױCÆ-SHV܄GT^Ky?25507Tbuڷk[|/ؼ;\&~~.tH$d٭[=f:*724pss_^lG$;yɊU3̉1YX3[|5h7{O=ܽs;we(Қl|W~@޾rJڶ/C͙ F̻ݻu=Q({T_xfpiPdIsN_?H]e{(H*noBBB; ttбsgϞW6h9 7mJDkV5rrݾ+T2EeddZFn]:i:/=7anͪÇTBjj=xKDϦ.ajLLKr__\|%..N˭_r=N4*ӳ._\f6OT*^63ֶԧo5dww7>ODOy~U]Izz?n]ٻayέ 7|zi+Uʯ8s+$4tǼǨd2YRRRRRRHh7.Y֢xTx!hӪ9:8U@{W^gpAz:_ܑJ7oݽw=w+ iAxDOu7TPaifʗ5s:5nܰk7 b cO<~|311H$III2,%%K/]5s\ld\-QF򑡑f\]]$hACb5hBKHo*PWg>4fX</###M 8~w_TЯMJ}d>u>z{o(:MT(FXp;gϙ+lSSS6,bO'Μ=|`* D"QDddDdW\xB}vڸycBDQoԱnQÇƲYysw-iw?o6ߥs:jٔd111_x;፷T*ݾso'K 1|M7O>z:ӥ[K/7#C_x.7w̨hݪeV-$wok?{P($ݺN?b ROW}H$=flzu' ot%I|Bbdd䋗^oE"ѧϟ3[֭50ȷRU(_nYY.6 \ɲm*?9˃m2y҄Ɠ'?<^620(6( |P8Q!hYLIʕ,ZG</((x-Q>[Qcˊb٣FFE=|L&zգgnVūoxPW߻^zթS;䉪t5>ϜED\.wİ}zZ2zX,ˉSlO,_~c7W4$J|zAz3lzCVUٽg/99: |>:!G 3b꺆oi"JXZZضEյ^ݺǎ9u)S/G{p>-̏c*Z^_|a}TynيU7o Ep#dz(/XߘW'3 ={ϛ3;ҹ2#"6oٶmTzԴۿ{Ń;7]\~040I?4^xuhݻvQ׿ ҭW_ߴ[]2<{<3jzi3=;xpa#EW_Q2o߸*e&7m ޱswaww__}gÚh>$,fW`{{wAWz/{IBrΘ\BPe=zM쌦h/OGxjȰl{h轀 TTH$!N?t`=8}O+Mlg 9WMNoKΣ|sgNfoGቶ#e1ص}3o(4IJN~ 8III4SԢ'Ny? '$a7]F=SkoV>(p8q߾fffVJ!?-[4rw}5߿ #}aaatt̷i8vfVVhXXXxxQQ<̭L HJNkdtt)+;1/+KHL۷Ќ̬ ӓ OIM<-44:&")? Pq:Gw{2K*nݺ[l}󺆆ܾw7dsJ>)-TVPXLyW^TK>8)Y<-4v---i4 WHzm t%22b0Oy^tJj<NnBCed('OW"~YYrJߢc_NJn)doʕj&Sn'O{ 5ήZBWW8Y_4}:u8q3}Vџ_Pp-pv֢E +NjO{ZF pĤ$4^ϯTbce}v[O022|B2߻y PݝA 4b0> U1r##?/+57HmQpCGm[65mDv흖.^w+t*6-cb)mݮ} >џ=icbYωS˯b{طp;MliݴSn.=mZ:ur%dt ׸A CG[o73:Mv>(Ăs' eeelL}|7llԩk7-4k`1>H]{ EYݪm{6 lCW}I,1޽w?Jٵs ۺp??z}哒HM`u[vΩc}ˆcM@G%y(14oնK.΍mloڼjƮݖ`V:tڳh'O5lԴS6[Z 1 *rkV6uʂs)M4ivYJ9~b՛2uwvAgB4!hhղM{hҪ(wߋ& CrNm?q2J[|T'JsH.2FMu"FWg6vN:S;Uk։***Zbuۖmuֽ};vF0IdBטq 5k,eC2P"3vl8aO144$˘= p5vl׮[.koWsESD 32N):f?ؾS&N:wuvqhҪ1mm;v*wS[&?NMMK ϑ\2k4}y 3++3+/Ct6c$3+󅗳VfVVB|BTTt^}x<=}EW}G7ϧB 8l̬̬,-xlVvdp{'GϿt)AYْe+ RZkذ|{}db;;]̬O$'S>+;+,&ض-q'M.FMʳ|.vaA|^}{LM323l>b'ϔV u55KK cc#XaKϔ_ON@_X~--qw Be.֢OF5223S^bЫa(/(A/z\AfNN.eMNJe͑QQ`bbliiVTT^^ *L޶m߉6]k`\`Gwy/ΰaC~V{Х|V- *sOI  ,1qʴo@^߼ =;X,c֭[KN@:Y(YZ&"W'{yVZr|t3'S}|#5u(" lJyz uu7c֜?M޼}vF OLKILLM~jLl,r} crBG XvU(?F]CɇN{v_EEHEWWwZXXZX^(b} Ǐ551hK-XBJHGL&P^ܓYqpwyw#kkt\CCc'6q-1Sqq񃇏^ݺʐ+?}ݵIF***zz<;w)J }x=-_>IERݺaf=|`&@ư;{-rE?q4۴aZP@ҢEW/;~%**B!OrJC._cH`C(/Z0}55&:޶m[ׁF+2M5tϾ`0ƌ=պM >|}V\. e֥}]2c8XܸyA=OϑrRHF=/4kpU'vt]]]ѱW57o} SZTO)"_cesqL )-=t#GU'OT4^z dǎ":ԝ=+ 2ER{Oٳzqt}W/_=򞔿}u }K/C VXh|(,,ܱkOdFY`N_zs$SN^zuVplXDV"Fؔ($%7r^zҐD򠚺SΟ(Tl"1ϚV9M2e gǍMDb8sGU ~^t]شit\GWgy7%Wgf e!,單XTTT_4l`A;u?|u|+Qd̪щ7olnƗ_sy\oK-M5 6oZPDSn=1CZ5ҥ3'$ȐO47dR'OA:}z:yܲ:Tcxx ?{$d՚u'*V,k :.1Y|iGmQdCirXGLJJz$4p@61fL^ˣ^S yff\rYh۶l߯OV-oؿ_9`襋uMSSSMگo~}{S w@F['xyӋ%qúg O, }ucnnN 77:{uV.344|¸tAOvI)))hџc;rћ]0o渱cԘuyҢV;Xnv݆Y75#?|svŪ5'O#'?Ⱥ5cw飼)}90Lϑ?>hjj"|IOC4#"̘]7 Ep֭zyĄ2z7n VU e%zg©aC$/Xl q%t6W"Cdr^WG[ZSOG1C*JuAi|>􃢨&0kԆukQyVV{`ѠQ6oI0Ñ>g akcvm99[խw[y GȖAÛn/_3'͚1USCCCO^F&ϸz=G%Lʷ;wDyh7Wµ Nnm(BZJrOy3_]6CmdURIK! oG,/F4}lGݻy{?}󍍍-Y4bPE?v)p._pPer]:u`ee(gτ {{Q Эk/~bZ)}mB2p^|{ϾGZY7Y'2pߓio^+/0P`ȫ`33<\pǕʙ2%dY7sv.z(In9.~I r2Oͣ(MHw|%hw#G4~1*IQ*̴04odm)-(j:9hMvm45f0j@"VZP Y>I=(Q߼}g?zjM Z#JL0P4EUC4ORX,qNN;\:S{*GIpMA-khP kf OnH,1v& 2H$AHzzzȕbo_iQka316&Oeg;߱Q$ޢEs8~dw^ O_$rmlЦu+{@2ġkkZVa7ii뇈(yETJi[CKKʒILA#IZ[+7OHjV4iy*i{CrڸQu6h8gB%<Yh{ &vs$"0JS#LΎ29&N`o}Dld虓E. 6`Q}Jz֦u+bпottt lQ!oDD#>Ԙ#G̬ Z pYaMgddRbRo"CW't5]]" tQ!7 ٧(PMK%]˃#/r2tw616ξϦ ANnP}; eܼc{ntLA&161L'504A^=ׯ0SWS2EsE)((@ְt:][[ 2g)lzznnw}-&6EEG#~}IRh޾Ңʃܓ'c Mann>yɓ&@l\oC>x  Qѱ~n۶lr>eێW߸(H^ //?07YRc,[d_+;gDΊDedZH{˓THN\d_ PU"J6_ʕZɒhjjTZbvy0A--*\*n;6} Μ-Km d^n~:|wmI7t`;+;7Ϟ LIo޾&70n8 >x\4mh/p칁kR+@Ady)3 Nn^>fZ[,MHEfbb.֭6Zy$hȳ$"RV6V/AHvypey] EӑԴ"ne55e}9”aҢ>X%ŸƔoߜ:v޵g_Tt4A۵måw/Ȝf2(fdUT}iLΞs攢'蟵l*Q*Fy@;ntӱbEZ,ʈ!i^Q4yЯ+-Ew^~}%p۷@Vv¥Khjb׳W\[cJ_zDY~$+TuHPk3YWW8%F~Aayb^yD5};^~SA6v߾lz0Y*06a0RF211~CICxgbl<۷~ԉH~&`0 t5:^VVp2.WU|AoNO1K ]O,>!A!$A&٣F#J~v_Mm4iݺZk.o =Z!(Є kn1*hp4lukVR_V1bRfߺڥxHCCrUVQ_4?#vNiqɌakW0MA~#rtq 2VL 98o(ߤub)0j%a6h`t#zߺsgɢN:.ݻIG(fy甖ʓ'U:R9iYRR\ Kijj(~555V,[Bۺ}'ߝ8~QyKJJpϴ4 ssH JStH DFj9ĴQqQZs]סL%8J5#/k+Q1Cd!=7jd]ɷC6}r5}B=l2}ꔛL ))?=FIE}o#DM~R:="qd4}Ѡtpzu x<.Ő޶k!OSSS_yݭk%c'xِ6x|dPQ冩 LNN;,9{2`6iF+FAGcOryzΝܩ7Bl[~~}юY[Z*V*LƐAΜ iڤ_b`af0<Oε`U ̄ѓ+/FZ%J9}9Kd13+rSҤF<3lmmD{ 4gpH؎eeK-6?.*(+nZ v%rf2iA)_~hX0qyIT/mlp='sD3o߾xSZzӧ) TZFCliM.ߨdgj*&OxM2>y}%@,--lvvvvݺ.,"!Ǵ &Ha)ۧ˽pI-RHT E"+-JзwAAG/]\%G{ΝD46RPN;::RiBz$ʖTd1x<…Ç %C٪?By>89:"fff.ݝ+ֆF!m UPPkh`@+)j ľܕcXx8wdG>#m|,L@AM&yICKJ(IS\߭vv_A~ ͵Y3?䦧dǰ3g}E ,5RL(ނoY,VBbbK,+11I__@NTFTJD^PϞr)~c;>H]% AɘjL('*ijh. < -@ xejjڃiiiuCt l%'ya jYYD~&e: 3#"+UwW"{{hMSe% *DP2'aa?}fȞ=Vڵs%N˖-2'!Ǐ2##L&eU MKv;td8Ϲ~ʯl6A?>hM'P /U98ؿz#ZDJ&p8Hehh`ffVa1Y5l[XX=4E`Ah#yKW~Ag9_BH3S 'WX 4+*\E?#@YY7nξ0d@tT|ZA&E!GgKG 3S;->Mh4KƓW?.\z)HAC|R,P>`0vS)-=orݯzr򔖖V֭ &6., ʳ/P5622%Jzz o2R>{᧻%f΋/)%-ء=j b} l*i-T"yJ9DPz ɦpѴx"333ݭlMVF֝:vh@fJ^DWTT+b*#!OQء}{9) tv2&6Eh#%3􍛷\~k_~?RcАc)_:~)ɸrg}|ɃHI*ddRr4/ uAb0P{&0d9KҴ\9f89:& #> y*vmvN}(N:ʗ89ɕo*((n]:lFhiXxdtʦ^>,CK~] 4ȡuM@^ncDR.w9]]:ucgaaޱC{xɽAϑAvٺC썧@444r=rbdhػdfe{b'vHKR|Cƞ$̜:c6E5 'NːNNs*773JHKK6skP 6er޽D>v;@a˶ od@I?||UBb"(RICGYx<*F[J]~# \X޸no.]ZZ )وȨ57}54,l<(яyIΝQfH%vm KoCxxɛdKBbjb 222(Y$UU` +Kwg_^e;y/ pQlH({%ߓ=$ CmI![P ,^u=\rhOtqcb%-v^V,=ǚ[w:4~-Sa&]bHb_~/@>h^`޳{#W>$Y|>Ch/9)E 硰Mwn&>DDEEc%;  e\N9/#$@WHNnQkݪ9^#]CV-7`l֥s'h5ZD YA>U;;Zr-yAC4 ,;'g-[@!1ԘLԝDEE,r9ryH}vv޳[od]`0>8?kFlۦ5<3~xݠ!ÑÐ)͌_}?{ڴn% |4mCR3O# 󗯾.1jL2 eиqpH7oA,Z MM)K"~+޼ea=QF[[eKEeeedc*r0wq))?PPUU%'O"l h׮mlڰ}@Z92\BQQіm;=fff ϓ+m[ .]JJUXXxБIS%W\fݪ5"""I\y͙lff"gfft{_nn~݈Q^H۱C{ϕD{]jBbb.|Gw⼻C vy=wؿ+W:iR.F!=_tL,ZTn;~wIekדz=s^c)wG"//s4i䛙~16m^cCD7)&NAե;R+Wk+n IDAT{wsq;q={.⊆[ܵs֬\]_p?0!1bedd|zw~5XZXXR/_ڳo¤-8!3+Qc'h4=$ T XnCAyԪ|E &G,_Ipy<޵7͜***۶l &O/_I)ϖm=)iD ƺ5+OBlY7?LQaa!ս>~laaω]E-} :vd2n\<ó˭_QZz)`)."4,խ @`fgg 1^G 8g .ekSSZcvl3--}(rX^]-- a *VXXԾ|S&OLtŪS;;cb *,:::l6|}z9sR7l ) EY%[Oii!߽MMM>oldtVo^y49MlUxpii`iE_'֬߈>555ׯWRRzdsާ9+*Q.u B>oK}`S< , f͙uʳvwn%%%VM@UU5+M1gp9/ 111ٿgWg+5k%6`̙5c-.~zv,_ioزibushiihrf7^qh #=Dx';|*9Awr7gq`3˝J+eێ=|um۴|+\*+rdEX6t( eddL1[ҚLvm}ΜSeS.>A@vvGhѼ499Zry>2l֪jϹ MTUU |^^^>F;|p_DDԡ#G7!dV' j&&%t:}Wd:bc~+_>-@Upo\߹m;N\,M@ܼqgLJ[Ʀ򥋿~z7cTiՏ?cT49K{;;4ufbOhհEdѥs{;971151پu䬝WIKLkVط )ƺ5+E .wltc9f<7 WXuyxohNjjZtt RC8:;zGaK8`2}!7~I9IQQ37sۖ>gXVFD>< `0 5&mڴqG&OAQ흌ށFEEi+lڰ}? ,Ef7]TTTtttF{:2>LƙǏ=`oyyQQhװA˗޿{G~OZ/9?y֡s8=s'"TRTE+/}0p =Gz?zhg*+9&v^B𠇏IgL"Mdp8.󳷳BįEMMKS'ODVlh ^nO6iT,jY/w罹VTT=4,**M4Yȣ*15R߽ݙ`XԴ2}}I?y(#,f2F;vlQMΟ}1I%124>ug@biapܗςiLw6}jjju9wzo^]RƄ\r4r>eB:OSS wh\RRJ7v߭H Bkm00߭+:5u7Q`^ NTTT233|96{>Ad0hWC.^X$dBtrGf333[/ק7zZMM޽|Μ '1H>O֘ ܐAL55599wǍٻkVVV`ossfJ2<5s!Nj /..Vc2v @B:K12 i4^ƍkp8Cs,`1|>n:diBIEizzzBbRII.1))>>L [̦iSyHMKѵظ4.kbbR~d#"3h@ ψIőQѹy6M>L=4J/@ HMMUL}+#"---WPTTlhh4kG*[jbbbog`T>z|6yyjj[5l gfeX,ҒmpZ[5Vа<}}F+p""rrrtMӦ DqqqTTLn^f:uW蛰2JԩkrKb{r 89SH`5!!11%%֩cִI# GjzFFI K[[J[5}yy,بiƔIrrsKJJLLLl6 q%:UBdffgdee5nd-M@ HNIIMM+..--ͺu6 -E&SܼUC0W S DEGgdd|CCC;[*'7msZs1`a&]iR@Ju`ȯ4`01ڌ ɜy /^U @pWJE TT`0S $A‰ȋXeaX p=` pWPWZ|a0 ->zM0O5 j\EEyM0n Z`2Y> `0 :PR6 R#C+AYY0t-M0 - `0 iee<>444j `K &@ @ MIPTɨ^!`0 `0L y `K )VNP/j5`0 n44u ? H4`0 `0 S>M0ORPS¼`0 `(L&xRgQ`K `0 `0 CZZzvN4Ԭnq(T$""Uv-JaaaBb"1cjjRNMK=rr#"#@_O,++ mm++ꔯfP-(33+=#],Ra%@z?SqWsdFGǰ9lּY3_T\,z\yY1QD\IѪ[T NWUU`N{w:wnqj MMM344LQZ,066nAKK er2JUU1H7֮YlGȅ׬]'z||>/@ p<(|~LLljZZqQy tS*(--EVU~gyHII pG;;}OǕHg}|6UHzu#CC)ßfTbDEEfvjjl'h8*QZE*y`ӧMEL!٣E4A$$$$455֭cmm!tQ3++; sqYJyE!O1+Maao޾'[jY^RSZ>^򸦆UN=\;wZ%S2U XYYikiovW-[X]Y8yR -kgRJ{V^={޽G.[Hŷj<3JJIDKϢ2+ LMyhO<<jhK ;~ߓIIIAM lټL  ױCىׯxؽsiS$(HMoNDiհaV-VMǹss-@{w:eҷR <;wSºN}K@:h1{/77WNo4iÇI =OPalddcԥ稺uTk!Zj}1 U.wA9Tj)UNNW*XiRHJN^zMuWVVA&%'>.֬nقt524K ?q6hT <z$8ԉC }l˽ڮX>Q666+W,Ν;V 28oKwqg.;{WGLvYYYaa!Aw^b2&9ҸxٲNgIodwdee+w*DCS VqcǏ:tcjlKr{ Nh4&YZZb/_{{ٔB CC_خ]ۋ)|7}\u(M(ÅupUk|JQQ/^|7x0T㥥<6oHHcܭS&eeg*=h'''a#< V.^zp?TE__o䟥Ĥ7GDD_ܰnSLbEpӵZ]m 7a!͟;VPVmǮGx3gwr_^eBmް-++/HOOϟy<^xD; /&RE`Q{/(ػw{gG EE{EJ%! 5&P']vggξyVMMe%CE畊\mLTb->񂅋giֶpy/_+W54VD B03+7<^rJJ=SFQ+:~4mw3gLS5 Zɶ揪3؈T-MhÏ̛hLYݭ͎ݱkG233 yA%,Q+*L]]_iV̶֮/_ _rx͛/[hj>ΞUBE?U.[LqcxnD gΝ߽P|cμoanmD"Qn^^Dddഴt.7g|c!*+KKy^=#A'+rV]#4xu:лmtm>_h2uuc.,_hLczk˖ώ3.e.weKUEegG,3)9y{+N:];rwpWTHLJ:xܿs;[;wv+W6Xty}hGobRR~#8ή={nި/]"V ]xItt̑cfL7$؈IdTcP^7(XulۺYΎcccG;PY]0_KsO#OCW-b855QQ|%x_?| MKK\y^*D5+Nj*V+߾{U+N,ƾ}ChhjZz KHJ=!44Bک䗗O5jXblY3ܞ<}~efaanKkiiˁ;vQ!W5:1B%r##}LTzܻ҇OZ0_ky.Z8ښ`<= IDATOa*QV+J=}pQر ::&{ IIo .pꗔ!4Oɩ哧8>!Q $eUڈW_ wБbXbE *~wJ׶m1cFL=W6srs/\ 5lݪ\W21>|LNM.pqqdSZ%h}7jأGwyvLFOPI Mo!DпH$:_Eu@\L_VvvXD<5)Ҥ2Yvs#F;5kؠG'/׶6cOJNN:ˣs.=z@tL17wm۾cgƮm܎<%O.4}&GHFM{^yKzt۟11F@qqe#~<ԩֽ}.wj8c֜$ɔG"@ߴEkFMrjzr֫os-o'<<۵Tcߠ\yQɥ5-IbRҴ3]5uЩkuMӡkY4lݣc[7zN W^[}p5HOϨTi vkۺۺ{v*ݐ^uoѬeֶ%J%| 'N?c_&FFwKB'rSL<ٽloݶ=//O6MHȽYձmܬ{N6=˗B?}"rDoE5fIsq}R)b:xzYթ۲U[7k{^j!tD餧g KLkI1߽nܸWqqv&yiK% пdrC̙;<ʨ(`R6MjH$94rؠq3;M2;;[AHLJ=g^}Gm<ڴk_ѹ᜹hL#˄ISl987lѱkkKN^]Ϟ;/F߰o==ݺ$Iɒ,.KESժGu}%V JNIri2"VƤrNXpXɵu;ڣ>~$h2C,wlܬ[]4޸y QɢW}SAfddm[U;v;&PufYg6o\5*kTĘ#UUT} 'n]-ZwweaOk_ &LBJRu٣Wy}GVmm][sҨma#FU1BXqwJʤX7bk7$$$jjj">?r`מƑȨ]{\$ȢV/Z"yPXrZI 9-񲙖NMȨXxQ5G|P@NNn~g͙Xlfffeeb223Ouw?*q.^iN}7߼y;&66-=edn3??ܗd(HIIԥcbcH$z.Y%Q "\:-aJ k)=~ĵu~d"~;xpQ*]t=㩩DRr򖿷!b߸y bJw̿_M 5jܺ}Kݧj,R?c#93glٸ~Y mhh #rfgg+s!酩eԿ_+זsC90($^Q___N.|㦧Wo89ꥥ߹{7!>ZW^KKKg-7Wzw)|MCEK'?/ܢ*QzT?$V>CCŋOUvoNv6IRV-],С#> ׫۲E F\(>mr4#f(&H===b  {"y-"$$eNIMUWW]V- uujTЈ@,>{\ngΞԴ622D/_?qE"WmDJTrԇߥe~11вEsu554Z'O%e(yirJ]}A]_˴v- Uk#~dG;%==6i Ryssr\073LMK[n!>)X;wz-PSC×XѱsBBZONР_Tt}}c#sEܼ<`X&*Ձ+WɰC 5--(:)<N:I 1̢mqqn;X:"2LMM454\ɫ{d2 7l"?=CghR`cٹU?PiRM[s7d9&G'bMTB-">HI}x|bSw[TD7/>}XRi^?ࠊ)A޽vȽoX{_"nڠp|G-haQӭ][y=(V Rqqc1G>0=9>:*`CG- 1)iP|--ukVEf_r@ ǟCٛ<{bbXGGȡ _"ӒܻKJ/{Aa-Z0K,5goZ..ˇ7?߽0?ұ+ÇF+GI߼u~kF2!sgll`/]ғI9Xp9B/]"5C 6c$gvmoe&$ݾԦu+x߅UUԟ{v*]{nCoO9w\[|t9(3g酳?x*!ߑCEE(ׯC,((PWW_xQtTxwD|Z0o1*)9姐׈>zB$_Xj >?!ǷF}| 9z<-2?e+w;Ξ44*Kb' %{FN*QJdCf>h@o^}u|K߸yGd32U*M*RwgΞ߹m@]]ݭ7ě÷~cF035e0fffsfX={+"%ͶUˢ"yB>ŋo..^O;RΎ;fԁ}{\:e @7f*((q6Ԫe]<'Oy-=USS30ۻٓllش2N)yq#G)WNrUX1ff qZ6m?xZ,(XM]QϞ235ˁy)jj%UE{!ϛ=wIm.RDg͘4io޼Y`y`0JL+AS+*ںm;X|$5m䄿 E +T/^P;7m j @JӳKpP@N= ,.\D{. )fF2 \.?ڂbjjjl3u?}*kRA֮Po 㘶;v +*ڵw={IƍQ6>{ dGvЏ=/D/[Nv:sN1Y~}{=}P cUSUzvoڤ1\~>z`ws_OKϝ5SꐓGȨr ={t٣jꊐ{W 5Oկo+5޽{J?|Sw9olfB,_ "&M/S&V6%3w~Xx9u jSٽWuciid2 ++:z̟-gdd(u# 9%vJƺu+WxMl]RBB³/e j'ɓ1O9"mm#kh-j|UEl{KR OaKhӮP;vy굒s -3n"1jl^}/Yރ]zYSC8ˁf A[[勍rO Af\(5mūY߸f̦5;"_iCۈdo`b̛bĉSd܈W~BtkKS|:y讚!FP)]_vvd7fa#Fus5jXtMT,-=kаaIG*ڶ! 2YJSq]Nns ٚ0ixCC||Zٝ%QWW'5Mu`˖;wwʦn^}W]nS&G%1vtn=tXFFf '> F&Ԉa IScƒ e#uѬiS%:7raodod /*M=h޾L&L鼗iila*f@-*u"pHΖ&V%t|5jAL||lvtmEks I4~ΜO '|V2+[={+*˪bYLf었Sc0^=kUMMeO!O >{JO"iWvY*s;~<ڻ/]rt)@bqvVIѻGwSu-CjRҟ@|t= ;:zx^w%Ň5|XEDUmȭlCgO'o̬7-_eڌYaaeqŀK/G٬ 1yJ5ٳ?@n] %.q=rH ^ƃo׶-)]:{`iզ<}*<;ud1Yh 啪<+ֈO^t ҍHW̏SXHkhhK% OG,/Ft}\O߻po޼ &&`˛գKRPP=s7[[ꡙ)QIKm 9#жMS*g(,(3 S051Ңvu)<ׇ|\YbvEпIb1O\I!-jukAW>}uӆ޽zP222o1m,CÀ}%ݻuiԨ!gn=DG(/56y6hִ3\!|lѷ̊ꚜ奩_!<"RYUAeVښfA\(߶>\XP`揧]T׿__Ξ\bUf-6()H$"ZރJBTK2 &D@SCȣSpqv:rp1̗Z\/(ƀCt$?YMA[r 1ۧk;wCĘg`<Ӄ|2T :K:ψDTVo@K,; :ZZ8ĘfU#rIM-1_O \#[|7)dYW$/14N%\k;v}TV3>>aͺgΝ?q=n޾}z|cݺ^sIш,ߊ$^:H*dvVEMe>;ھW$пY'$$/wzQ9rrkA.{fe{)[2K̦^Fd#+;TSC_Ts?REIu`ςP[s*uBـJ"ؘdII_Vh9)jjrZup KnA> 4RYZ֮inbX,VdddDds,pGUO7o McT)Qllp*P+z&+.R++,JzUUh%I];vv|}8{7m*<}z1F*i==ӧϚ3/=#cG(N]ӥ{ (m?Y3UR|(ىwF#ۈ@ޕR|-d===FNn^ib]^qDYYYPp1O;̳Z=}sWpcᮏRN%g[=,+O"_&&{ݫuk.^'1ݻ7oɜ84{c["RLꍦfI(INƯmcB@IuA,D"Z32!Z?VpUʵUC6lBJ$KDiLM__OqnZ&?EdJ^«AvvNsfM';/\5kءyJ.m"eʤ"Gnݠ&- *7d\[[K竭`l55ƺ 1FUn}}._YXXxz0%~!)lv!!=;*RiVF +%ϒ!Q :o*>4")wn^\@9u/ۈ*ԉ>~\mDyFݺv|:TWTW֮ʮO.&p.\ ?v+&$$޼}l F*$@]+˩ڮOrLSk(8(Caau@[:4_Z5A7>Őݭ]ȽIIIO=mT$@[X,;b}r&AfNjϓʔQ(OTT#srhW\J,зUθN(X[Ya&EE}xeݚjjj.&dl$C("VFiʭ O?)9Yi P̬/?9Jb1OlVyc~,=Cnt֠mD`\vVr7"y>PEOa%u$s3ҮOUT)-%N?z̟Exvh/ߙȇ=~+*:}Ivh[('' -N!_zFҦoT33+F2)hYuMVqq\.7##BمEԘ6&&V$//(L|}Y9W8yzтeZPT ze$VW&ՈϴJs';t╎@ WYqNNjjj"ϤC^!55W-[;xyRi鹹yzFL&V R.HK]9~ N wd?&{ʛ% J&=uɚZ(x|q`y''G-bX%X v^ z&33+%% ?$C>W^5cIߡCSprtx#É^pbc DEDEbt5nTG|>7H\pmقʇC_y]6РԘ}X,.*iki) <-/H$zqRR򍛷k, ѥ^T^(>>ֱ֦)}Zmgxaan3<ř!P_+/و(2)_} zzz.Ρ>~˥#{${ >ƍewC)^/J޹l6qIBZ]F'? L&sm /_[nMM~uu5ryKv}6dkt Oa㷲>'O@XXxH<蹌 ˬ ^u奥 %qMʵ%ONN3g߼}b.(3[ 2AfVI5.:s~*)3.\ HȸԿozq^ Bj4p%^߽JUfa"'=q4X$BWbK^'T:P(CU+*:mq_F Sttt5m|F{hyzs$$$PAxk XƵs[T\Ԫյ%[~=P7k٦s^^>`@vŋKoggK,?eg&|C<njr.QㇱC5KpwkG6\=GȵeK;pj4oT`(MpKKWڶܨ+.4nԐDH;v\Aʳ.ennm+)9y݆M7nصL=$)LAkbll*"J7IhS P_q}-ٝ G^KV֦u+= G|fK022tڧb*҈ }F$Շ߹{<3HJJw6p!VEݫib׃o*]B]%dw9dѴx"AWgŚzuڶi QDOA ]˓=]_~~OMAUn&wt[R2Oy.ۼe|?~ A,s_<}ܻ_.11h062l'''xeVåKSG8%W?S/<FFd<!'6;% ڴnd4V9zLv yޭefldD~ vCU1KsT_7ou`0naQS2{ɲ2nIStlV֏e֭׮_';}60w(Xn8!!KҢ|=V$FFݺz@ZzI|,qmقhIjtؓiii&O\(b"hAiRRRiyYfyqnݴgeeer"1W )Lp !Ǐޭd|ߖm;h<]OAu\(CI8׏?U*0ek?RA*`0,*Q.Yc Ϙ=l\D҈ݭKNN9z8dJ=x~4uZPoN[?I>C49[RǎGwݗJe|Z4oF, ?| }HϞP, i.^Jڶc'{و:v \ '< vWoD= Շ߹ǎI LV H$=oyOkmG !964"h'N$/r]{65Ǒo_4qXI|bO*Ϯ\ ͇ps[P޽q.]++ׂdYBJ橀Y3M\]^zI33TRa3b/DQ˸d˛8e*y ]&YYc'L"uiƊ?yJt M4nؠ[d냇j>HH$Zll>;1nشE荛IFe HJꂆC>|5|漅:tP8aTjrڵ7d`$22*zp+RC*p8#GIۿ`R;yu#֕,;4;tHfM ƒxog_??G.ZAc'Y&5 qs?ɇ@ wP2i"5T>Qy<^~{w`%SK+Wݶ}'=v|i$ͼ9ji}{@3gϻw*,,ܰn5y=e:e2}AH$ wwRfq\z%L˗,[(.\$Z@FZ;zZi{ԺvvS&M^}KE"@_Y:e>n┛n!2?1v-) ŪK䢥ˎ=L]q}`nn>s4$mZbѧN۱k @[[_>Ѿ,Zlђeʤ/_} ܜIKKܥGl.ŋC}JMV$+E׭!v1ٱّ<<ǎT!xuVpGQL5=;Ej.^KN\t9x'N;V~ggR+s}QFiiiWޱk]ZjqOBq0rxR-=;v j bgkww|wW=rkSѓ #6iyz,\@q<>+zpLll~~>IMM} ZjSZ0o0?޼u7s%fV;mU|SJc')c0D{(ɠJհ%VF;bOhU sQR9R:\@pʼnS55kW+!ʤ{xtه |Yap1{uul6Ӄ}ڵk'u4aGqTܹyje7n> <.U2mX[ZwO#II124415̢t: ]]&O^GMxq`тyTOp8>GQ 0I%UPT)vgيp #P(ܼu۶hWlּ95֮W&LO(0aCl eݻm߶EmsP#@֭rQc'@n]N;JvN%//] k7oZYZ{ʧOA/^mmm]]LPhbl|-0UУ[ǎ4YY Eܸykյ 1Dcjbr҈},_I>k׮UXXF 9$!/шںw {%ÆS`+G} _ eޮMZNפ;>sNiP(a0wn ܵg/}L2B9m_c&-b2cIr&m&Y+}:xЀ.ޑ*P+H t Lj'y;OʼnҤ ڵvR+זI 3S Vڹ8;\8KYeg礥._hǶ-d-Y(M`XLd2 [lo]tWX5o_[8.Y!Zlw׎ î׽kɘf)?EW[Ǝ&$Ҳkr`YQݻݽܵŔƤYΞ7޿oϸ1ɫ+==ktH,գk[e#Yt8Ybú5fff RRRy<^ .;ݵ.(oF[PSSuvr;#/=Rfطo.g'Ύ":66 Ͻ~o&J~D[[铫W,#x<RF)&ܽ,q \8[Guemhh3;Y3[ ҢyOlٴMVă&&ÇsV]262jѼI;\Xy6eu- yݽs㉍^:upZ6ȴ gOM7XFXܵ[HOQuu޽zjhh % ǏJ15R_ܱp8QQ ǎuVZHdI]~Bf0ٹ{6)[TS{뺔Ƥ9x߯wKbme5s_Ә@Uv}5k{w_pg.^XcN9 %2ZSjpWg⊮0%%U]9rİ &&&D Jkg['8WgOr4;;'#3SGGg¸1. (9Xp'\[PSSKKK{X[YZ }z?yxoՕ:f{vx}{fssލZ=-v^~_ Ҙ(F]]]__gIwo*֘\L533 223*GwXqqqzzzvva!%fR_(8ȴs?L262 4ݺܾ|%G 4K&I)JSRRbb \b⢣cE"+@=!!1)9IOW|MMMk׮U/0°t0hD 1~oi eAAADdTVVCzfiS~ _`bblgk+V$%%%驦Da)))VK5:&?ТfM /_"SSSg''hu}SmMQ'&%eghhjX֮m[Fq&/NKp8,F6Tl_1SVVmh% m`_]x<^xDdff&433u__'REDF~֮Ye*}V*mDm;Z:Ͽ/]|k* \Z$k4oo_Y{RRS 95jڪ} w]_VvvXX8511o_V KfVVddTaaC}{(H*ל\mm-KڲAD%׫k'MSH$OHHJJ.((m kcjfkXZֶdDȨ4Phdd蠠Refe;6K].Rq^?jfiJBy `T5"ɟf<}62콬A |VҤZQ &e`lxZAUH+'(Tcp8A7\!/~+=b|  ȯrrr'NAADeA~>,PcHTeBBKH$ЯO A@sJ[JT;z&&8 w?%5 KD]9 ,T  ek?dGB|溍ܸ-H=ϖ *MoxyvrvtTbHuF3@[G?Y&{SCWW 8 %88ԗj#FW_n IDAT}nѢ9>[FbO( ?Pe]J&"b#  P Y"ZSSbUѵ0zbԲKNU"  %4rdVeEuxAAAAwF F&|CCS[,oE:b|   S@Btػ4ԨN_@hi ?XpAqg˂    BҪ>f&&R`0,[$}& dAAA*[ KS@P jjLz5 ,J,55BP,FAAAbfjiiU7 AL&SGGb |Z6@EAA?fkT'篒A CSCCBH$10   O0 d2LfTPi fX?[AAA    B*MAAAAh@     4AAAA&    4AAAAT    ЀJAAAAPi    B*MAAAAh@     4AAAA&    40|GɉqAO AAA`5@,) L4AAAAg"9/قH&R](q {pjj4v Mm).czL1=czLdzyYun"...Lf5T    ?555u& xɉب%EP,dAAA) +;F/-,!BAAAAj&[@KfeSW(5   HU 9`la)~D%    i 7"¼-   f_D>J4AAAA-MߗW}€*T>sy\ѰA    *M*A$TW'Ѷ˄%~~cu_899VͰ#s,   4A&'nѢWjLzvޱ{p\S|:l[{VڷmѮG'ˁ G;xvSѵ{]7pƬ9I\s#F΍*ιryP,m6iѱG='G熫V-((L9j̸zN$:4T)..N2_&Lb[aw][[uzy7oL]K=:uoӮ}vmu紒sM[6jڼS[76[թ۹KT7o[^ Dm984j*u 1)iڌv.wµMm:GI^swtqpj@s9s'&Iד r;km6XmݳsW ;yyyGo1gނ   T)7nZqSVsZE^z>wt@ŋQ@}nܼ%/;v\lkhhq8֜:s™Sk7cǞ}oiuuu |cOVSW Y׾;%%5#3Ĺ '^HN|УO,]2 ARr򖿷]x5c8;;;-[bj[(Rٞ=w~ʟhijdee|jW.=tPCمA޾cc㛪?I4m ̂/ .%A d *" YL{。RҽW&bm2Z{ν&9ɓ3FN3&b:|m[6[?7;tzqjl6=ڣW8~o_Ls}ч6^ptZ 'Lr࡮=z%%%eUFau7mo]:u̚]a}v)]bDDFϜ5{e-K uZr"""_=Rmz??ٚgq?LTb"OHʶw@?+=M`eLݺtɴe6,ZDD<<[4`4̳|J%bY왿_tđ sǏhۦ0(3ߎ*&iﴽ{pcO9qKNcO.3ߏA7o>a._ѻ_rr_}ig. lJJLLueBgo$SR&sRӧ}՗vΝ|ʧjc>G4"aDOS0~(eD}M~%11?Dkn;ݮ[z{["ZhQÆ/\DfC?u􍋇WBlzoaZz0CD=m׺Ew߸ysTtmӪNu>pkR6(6J|ا65kΟJqcFҮmk7nZmZmӪu]Eګ#f{o6.f͚Hff晳h tIDtDLj?*"eѢ9|?2F77뉈druy DDR I"5j4n^$"4kt?YaC|||썉޽z6n$$$^VDTlX588l6HDd[Er!)+V :OYkٰO&kŜ%r(-b-C&( ={t=vdZxIZoyV=Y+P-[4ᥗjZx4;'NR/|"O?USX;~BDUӷR%j٢S #G#4iצҷp^K"YܹKIھ 4i^aسw߿n'9w7qĄDeoJJʉDze˔YdF,JկO'dd-_1hY3XJDT*U=3G32DqsG\ ZC)5mhrquqL݃'%%_]JAkW۷Q[UW!Z: 1[z0jYϚܸg>;n&"r\~5j̠)_^DoHzF7DfU{;vn޲ʕ.sf^YY;2FD2]ƻ+6mr̙s.Ԫu+uۧw>Z͡bc}BֺEqqƹ3?3Y|tgO4A!iJ3e¿/xRiբEI\C"$^y$5%UDY\'-k/;R)*gΞmdXʗ/W͚6iղEvmWzOG+ O)usf~Jb_Y7*渺o}V{>=v|Ͽ:%KNNl߲3y{]mTz:GKHJy&ez/[bo5MZZ[Dkz{&OÝgd+ ''r%"GG3-A޽zTŲtيχ}Et͚aHJTttl扽=B9lClظ铏>X~E3jp`"HJJʶɩnER /<吐" (SRKνGSN{;fܵ;W...O֪)"ׯ߰y5 ׬u˕+HZ~cddEoAJfǎ]F\uZLLL{Vm߹˺0PVq'N6!hB%Jq?LzvSjBhc 9iL'OQ;XUJbY~7L'h\V#sm woب3 ^:%Jff?M+S|֥"##ula^;~IFʬ(koy 7lԵGf3Na3z.ׯذq888 GD>x`];wge%=$2$=~gy^=+w7e}cGZ:N]^Cƍiw٫3 .I󔔔cW6ر+ke*~V'#"W,5ܞ@711q4XD:tx5zUȦ[2h4ܵS "[]\wi٢2j"Ҷu뜋F߷ow31~UFjjJφ~j?껯z|7so]IIIc0ut)]~PP5Po.^鮿w90(Ioإ{R˔Oz횒3ugL-k_~Afy%^陞("}8ĜyI1eQbgg9شy˦[ʖvrry3kKNÆ~;a,,w=SNm֮ߐܡs7///N7ne NNN˖,RCZZڪk_XoEyfV_&OeaܘA-݈oG&&&;áQ\ٔHǍ=sВT,Yjn͠jk/_riiiq.[|'9V{Ӥ޽z}+͚Ao Qc}?v:Q|WMl=oJsg?`pFF'>v| FcHe_ tww&S&(l=L5ھ] 0Aj:22JĤϨYzuڬXIJeaܷ#=--5k)o26aeD$,,<(1_޴)uI2soiE$**rҮMm?lϒ%e$T``5ԭKDR9և=xM7jAA333\r?+ھe?ARR1)_,sVY_RAʕmU֭vlԲEsVkXuX!e߲E۷o>)) AFuoݵ"w|viZoweh'$8::/_b w,rիWUVQ6\|rXX`*WlθL _HJJ,[RyafsXXsqq!!WZm lN%x)6.ѱL2˕S3d2]RT||*W; _j|>χ}wWRT󧧧h4RWvO0V'j'72"}"yfygfh IDATx>+>Q}oe;|/B%JxU˗˹=@J(QP;h4ݘ4yRo^w|J(as4#GYVD:w͍чC̙ 6z~gC: 4VdQ"b6gޡ /_}.e[|r.}w% "ZPY8 hڵguNȞݻ|{>AX!h_"-"N"a*:ڴ.$"+vܱ|r=IʕL>NQ:@HOKg7""g=J&Ν:tnrzzzA`Eq8+SID-:H\TXX!cZpT}鴴4)NA<ΌFhu:4/{bTjzߖ"R޷N"銸~Ppr2REzHT933SZƾ8} P,Kjjh4u]33&888n&BO8PTZl6HŪOj4D$)!PD"^D\\Er:F1SjNu P,tZZn4L&B2bQf~4-b"MC899iZU(GV/NfE(FT*^3M&lXXxDRT*Zh4M (ŎJ"ڢ@a0 zC6nR>`t:WWWJ%"ɫ׬mުYڵk=znBol6(٠oڼGK(z/G,YLDJ,CڵmSjZDӏ;>}̵[,cWTkY?xh11j~˖H٬R\@!gf6 a܍Ys抈ۮ[>ʕ}շzK _\`O>V[јǎ/ x(pH^=Gq$=M5ODddff6JtCXݻG~Cјxk֮[b g=KrJJdTug7~%6>N9š6Q/RA=`ڼH|B5Oh]qJNϞ:~[7*[DL>rK7o\po.")))o|`ς:{IKM˯*mI?zxϚ9j)9O?n&w^NOpJ:~u CINϜP"nu >Jz*]5fϽp_Dڴj9{*JnvڹgD߶ljJDRSS8ugQvvߏɿNmJ'4P&<_;|wߎ?qOO|ѣ>÷̹]6JY+ҬiΈ j/X$F|E)H4nT"tұ'rZ{kꝷ;"rḸ=M4j֚M9K۳w_ff態_x`=z(<-7ߴ~ٓ0}^]11,|F|IzF}`0_|={عk˶mʧ+N%͓Oּ+ Jf TZUIܫCɩ|9nj9DS@)7/"/:tdݛnKJJX,, frV{~v44%/;u`/s/O\^, VPT$J.KIw%3gIo/[C@Q[׷wN6ǟfCݱx||B.N5e{777{N?p0:6.AW>[f+JUD ub!h0 (jTV?AD֬]߿__ejXZ?t1SƏ}nڽG X21W+PѠK.V@$===rZzprt̖bdff* gau =os(Fzt$^v̑Y+"XZOHL|y-Oḽ!<7Y^'!1AIܱ`=MsVըu˖6? :u:Fp\^֭ymLzkW@YdAA#555>>!6.7ʖU7no0*[|ի5k}e|HF+zwRG嬘s=Ξ;oݸiϿ?x݂#w|viZo`+U(^Q\TXQWx;~bwB_;JݫǏ?˶?Y[WYsDeʔy3"99YD|;o j֢N2˖^bWW:>rTDBCrVca-?=h|ډ;EZ"|h́B=33_npwpNI_ұswZWcgwZҬk4I?лWgyᥦ:vߋva0+WֳdJFD4`ͳl_HDyYޙi0{{~0hl ӻM~c|m`}j cɗ.'''{ykOT("7oF?w%oݺtz_CJ5Ongg7mrZ88:XӾص} .a4_lӵnb"&Vfϯ_o;}17f# sC<hu"rOxy muVX~Zbk6<=M=D$1.ZDE$3Tu-7CyKOKgWw@i=Mlx|{$"gHE$.*];xЮH5E y5g͚6Q]mgGG5/͈G4DrDdߖ"R޷N"銴v<3REzH\]DEDh(|ۚsi`DVH""5D$)1PD"&^DJ8H*DD("z{89`[b&6<=ME$==]DTLa} J%"vvvr{v|5lk^ǷIVz8z@&64 Ml h`A@&64 Ml h`A@&64 Ml h`A@&64 Ml h`Aؠ) bILIJ02̙E]#pj;;ݳ[IJU5$%ą$uE=0gfD;89T^ԕ!DܸvJ89xw,Vu͙q1Q!)I AO{J^MZmW) Dc7`ZmPաkيU¯_^DV/ L&SxMXAl0ENjyg4L"h3v"r`N?E[Gd V}|WP7ߎZ说4qrr~RuOP71.\Oו)S_bX2 j4vvv`Rըq7R"r-4ʕ O֪꒟@,_w]:3O>Fȧ8Q?;wϚ3wǎʇJ(Ѵq}AuFϜ5bԑ c?|uJyyQ6 w?}欈Lc> ߏ|ʄDR^^_tR"mq?L$ʕ+mWLl앫Wy|ܽc'Nuc.Co IDATljJoG|YFlۦ-XQD_gᆲ=Mgoo?~ $?X /H.͝dZjή3uW.[R~=gcOTRRҗ_#"^6mx};J;c֭ZH@@M[sEA"33kgΞ;BdTLKKx?,,< w+"" gΞz|9o9{.Rprrr300h#Gv٣\`+V[/>ZGR sxyTzK'?;~?筈$&&]:{|XXxQՒt)3J OrW^9M,KDDę炂.MAzAA ݻƉHƍڴnmo(lӝ\ HLLQ40ccmF=%uֶ.5{WÏnڼEDvlݔBΞ='"~k#GNjJ3eIv݆XkNggmZ}6mjjH?Xfa}|>~oJl/O-['([ju:O8KE: &4ͦk\\rMKK1sf̛IkNR4~}ze}լ]'Ӕ|N:q(S[sS~֐/5e %"tuq۴\~Ckӵij#}SO7(-Z25-yo"2kJ朂.{H٥K*wcOfY3u;MI;v<6HhzX^tppLJJZ~ F}ᆳMNNڧ#`P:::de 0ꈈ[ l߱Z3Y4"tVn];[7>m||B>n*U^wfDtL̼Xhƍ^y Jffo\aӭjNNN  }2tǎsgϴ"#+Ѩ\ߨlc"y[~`Ro޲UDz}FFk8ovx&%%)jl0֮۰iکciӺ4YrR_^ȭROߓyd.Iu{.U u8rxiP7TmҤ],"jZiniE!--MD. z={{/<ߺkjZ+? 8yՎ]Vz;vFFFPѨT*lkN65珚v )0GUy:99c/ޱK?bD"B)?lƴ֕M&ӀAo)a={\8s䱀Ϝ8ڥs';I_kX 33Sa^vrpAğ>?rAw)SYC222t:1Ο q3'^7 8x(4)0S~7#:uxM׋]=lɢR^^"zڬ_lowIصmgC?ֵsݕ׬|YD^x).q+S~S,j>>V"&vvmڸ:u:^hiq{`ΊUn^m?S+W?jBD_s׮Q"&$$[qɢ?ݳGbafY,[gn%5-YTDd(JztoG6llo_}֒lfSܺUY3YgEu<|$\]]*X;8:8TS|9 >>.//OeSfcqgϝ>zȾA%s)[vUv_Y4'7xD$--M̜}K9mP_Uo٢nZКǧ|唴NSvٲʖJe7]m 5kd?+ԗ#TNa.]Z)RywYk>r_'[JRTe>xcG`0gj={t+yΞ;tIDڷkCED/7wἹ a|+DķRF/5|@gv-TIXʜʖ5k)txJOTLKKnh'Sm?R'T{9Qo+YO6TU}aΟ_bբvI\Z'Uسwx{=x:+ ="rCٻKy[pͲ^m7#dдicT*o11}qkR>ij4kDD.̺}޽"ҠA=eF>{p;hdc;mCTr YVŁZZZGuں½q/68A{VǁI|?r9ĪL8CԨ3O%4j0ÆxB@!-aٳ̯sOfiƅGR{Uͫd֥ }н OD\>c}X$F>8;w&!srg!Eu _E'PFx{t?ݛE`N50t:w& J1[rgTt4٠.oZdБ>v/YTT N &_ Ν;_Z,F˻CF3h+Np$H5v$%:\צ/VrZ%c?o%%>"yvI6Ӆ癛VPRBuRuqw&^.&mFi N{`0DGSظxRm𹭪"VE}7Mt }%třӧ6R@s<@bUP#^99ģKĐ!a ;*uVPP+2YUZEEŌDxgаQo>7nݺ5!зtQǪE[]e}FgPYY٢Z6m^l 蘷[x,|ڌa!e;PHIJJ UdfDgΏ)vB999X2BۃAt00x¢"j񋆰켼23!@ʺZZdZr$l&&bAgg'*4AP140 /^r\EEEa.uSZZVUU|5Djwwd{n59t=99%!1Q4_zCP a`У93'''A!!ϟ^j̹ӦLs[?.nxv afpw|^XXH-Chg''ng/4,<$4 P Mjm\\rNjjД"'J (1ΎA ֶz`o1oߑ랞xgϝpJLLLC>G׭6գŪiȏ?,&)i׮W$ּE̞9gLHKOe@`O***Bs~)_!᧒Һd(ѩ,-۟;w@Xxū7zShXxhX*$hbnnFe ZsKwZํ$&&:r'AFl0XWGㅥvע.=T*iw' %%\_ɧȴjFA!xbڌJJf%m}EvFmg$PSSwҒZJJu_6}%h-7P(޼/4Qf"Q x)rrrssn߱uu<=<{2"14i5oŎ7ŨUsjjtBRrJrrJCuplp^TTDNU\n&,<"$4M3j7щee&ѱ:NKK$s#Y&&K,c4YryO5244242ibUUտ@ xfL G?֨jIcll;vT/-- 'w$4ֵk2)RptE>H 3iϭ,m W&Hh4a' UUUEEEE*<Ѥ)SDgȺ68i}S2H(K׮]Z$Bq/^iWIIg[5hITRr_jݻeeg5y<ǎ<2ɳ^VV~;we͌FUU-.0h:jjkΘE~y5b#غ}wO:' QRy>idaZ*g'4Y|@`U$bbݷώ[X n!a$_Y5w,sCG~x)kЄjgnn߼xaUOӦ*/^"A/H6S'=!E?{oޟ=<[~RMif6N*vJ()-i .[d%iA!!!aQQoܽvwB_n?AL ToW:ĸ~vNNhXhT__ZAxU-#O=>d23j 7] 4;@ZTi׮~32q84ã:(hFTɇ-:p~VJj (h`g<$4̱9:C[|n~w؉S$ʚ?<|RTTTHb6֝ҨŲ216rrg,KMMqؐr"m޲ YǷՙ-NPyLMMZRҢ.[\#D b:c#Cc#ysgr8wmæQo>dĨǎp1~TTT4;uҲ2)#y<^J<Azdavv :627$!hBHn}'1i^wgϺqR2eܽgk0~5ª~!T_--/#;Ow7a OHL$ENP?*84 \]P /m>$̗}M7V(HOGiu_(@FffFffiiXӧ@-s}wm7fYT!ǎ$~6o|Έ 8w 9}p_=ԂzͫջWO232uCyyyͦ3.;ƕKV&]YL̫WȂ2GH^ _D;$ `X@Xx YXs~jm  jSA~A;<|Tj0`jlL6:ihXX@vNNC)Wv$mX0C4+R*uee%Y;S mUQQ i RˤgduH?q$v]^6FRYԳgchdfb}/ed7ȳS&=!cޮw077~ԧ\mJC#Ɏ<=Cʣ;wX,ZdLtw1oI֊OH g{b-Ç'O5tkdjjBv*3!_A֡ӹnb1y S9>)"0;/q1<o] U<}Rq,ZAx$6KkjA$e{R/ܽwD#3'N~V4p3 CN9'd IDAT uo$E2LR?BcӻWO)2KROmS&-_~U]kkkO:CxhiSƺ|}k90գ'%X$t-;wIB0W{Idͮ={Nڲmc̬4k,.>|B{;[xN8~>r S|>ԌD! %K\.8{XޮVw<|PtP(\j7~ii:]qyPkbO\/k#'k~?&;8eђT~:QA6ȕl;p,UΥWyUVVnߺ|,PN0,*dr*AbbҤ3^Egc--ʫJ |25H,6lmW];pH !a#}<|t>'"{i4ڎm[@(N6J,kgϛ)43뻓c'OFg14 y!al6;;'˖tub2=lɻI̞5n_z 5^z}?l۲Y&g>;}d$< >!˗x"PRR**miu~ )?p ɽ >7,cFɝ%Bv̈́D =yLC;OxbGIb; ;phk׭ϬF :d 񼲲,(5;//,^$Gh^-{; @wFr8\.c'G&ӧNiYF=k=6$4= Qo'LJ$D}K0lg3b0;lϘZZyyyK獍oܺ`eaq&O]3~.^tYSSXtx=#HeǿގNW$ņ@Xkoosn]Ed-խl6tu>ocsrl읺vѽvyb|7xo`X,]zM׮]*++QCǎgOhB۷qGC}{laIrrrS'OڵcN~)1srr8u欟BVv6y!qnn </0(̲7}d]{;UUU6]ZZ8UKcȺ9D}nϞ:;~bbb҃<|ԥJaa5cߟW.EDǼOV"0{Sfeg:8u ѱ#c:۹FlwP(2}9gxpu~ݯyy7o'' 嫡QSSC `sVǏNI262<~y9-6oݮ֞Z~Ww7WɊ&vd* kQ#DzHvQ1?Zk\t6T<'>7.>>4,{1rڻgwQ30(8QHF7}}3div3XW!^E=NWdIӧNi -B諅#MZ͑C̞Ir.232BpO`٩Ӟ];)YMΈî]`iadX.]twuk 8_]Y3<$` [~/#BwA-MiS&?yxwKf440zx :ihpܤx6͠ӇS'O1=zڱ]@Fg(**RoXuIXD}nuuu2499DLztUlÆ_FArrJaQа07kӏ4#.\}n -==?hiiuڥÈ(1)t622KW0ZZbss ګH 0̊;vi?YĤR%%%3Smm>zy.B!>>RPXGQ-HMKښdEφY\b;t055.򫿟H֢Oor 7;晚 A!B9SAB߈?,mA!B[A\rm9Y{!B!BzB}oT[ˉ| SB!Va!b~.ew>}(Yl !B!r4Aؼ93)+kܘd}hB!P B}~YK7!Bo&E!B!&!B!BR`!B!BH B!BIAB!B!)0hB!B!$MB!B! B!B!4A!B!&!B!BR`!B!BH B!BIAB!B!)0hB!B!$MB!B! B!B!4A!B!&!B!BR(|+-+c%K7!B!v`@ p\/<(+(|pӖW^ /ۘ/ `rrr_9!B_F-# ePSU]־^ז\&$&X˷Q-*/gihtieաZKB k7,ƍ=rp:~&XukC 쒑 _| B}nee+Wvp7[UU?N>[~C̝=F[]vEҚ9cڊ#8ͫO>Ψ7!ymڰޠGOj9Bs $;e/B:AN.HĤIy.n^;w"&T$=#cu&NpdzNNHCAA a#ZsSHDNNVx<ޝ=ś4P[ B:}.B!jjjVY7fBN,p'N}ztlJb쇢۷mw7q|9;$IQ^VQ^wp7ы,kZp;v@.N(͊|6n/͙=ϗ!$# $%%YY_!Bee.^G ӦLw*\!c1yx`/Ojܹ9.֟؉SW6]>yFgsE;;[y?uTkUTTm=hij>ypoԈJ ?x$KBHvӤMܼruzz2\xYB! KJKuu:AÛ&c^ݐtv*K>3UXXTt֖B!ڕwػg MVllXAuq}4y£NeFC l\ݰpq~6-u钒Rشah-99ʲWϞvi@ (,,PRY[KKKK쮏ٕ:MyCiI@ QoHVf0keo֛lgb߿7mf{ucs'7!DO>ƭےW_JrB2Q #ǎK=9SjgvNO+~662wWFf#I*fH3>c;wz:8w`Vm]ݽt72}uPKdG,{]9k|B]vٝz 9ɽmw!..&CG|Jj˅Bk=alifq<yG?~F^NsQ_IB}NaA#{X~YhR Ҳ&ϖGƭ ruԔ,`ogGVy5ky٩1%kYXeՈD[BБmؐ{'[g* ZryOC#=0KKO_tyONp5c`b>ŘQo4iM?2FAͮrEtE:Ls~;wz,`YO999.[VV~[7zHZHV+1QQQ9~P^VZzrBANFгNz:* FݯhvejkkYy<ޜy o)&&ſ}&2).mԫc|nQHݍlG5/4,y=_PCPH#Clu^Ԥ׳fN9JzTU]`9ݻgNT.^r73-)g.k׭o Oc^Θ6y1Q/njivh4yq_QC/C\nٶ]7o!g'LJn3`/^Zb)I5%IjIǓ!Z銟6pySRȆqCe 7Vl\ӻ7xYY^E&&&5z,#^?ol ܽzL&99Q"@uuPg^hImm-m˦f~vQ^V77p/Y& !mI9zcq:_QJJJ //߻W+HZ[YE_A5OZ|1'N oOMK'F]A__}^bLLAZ$0(֡Zeeett$`Oڍ[?|#~Yt׮]@nn^@`yhP^κsEnc3OUWB? +M8|aiaq={ԙĤOx?ѧvMMM~ɟZZ뫨4S4Z+WO0Cff ''gbb|ar0eRɬVV׮\STTTRRvyrM\m .^,5ƔIS&MzX'Ojjjt_̞5C4g*bW|O6Bp<Y| _ eekjkɅ:tP(B&&bAgg'*4AP140 /^r\2R w9nNnNiiYUUy1o.6ltޭ>=''$$&ϐh]NZJ; qqСe$;'&&))>,))]qTUU}Fh!9v<4,?P7n<҇Ppj֐ԴcPmi4uM9?phub'ד >j#(~H/_E__/''7 ;ӧN٫UfAa#x\aC%%'55퓖Ք"'J (1Ύ5!ip[~ :M4I`w 4az1UʼQŪ:UkbZةv2^ .=&ՌiS׭p\`\4(8ƌ,sB!-y_+ 2> p|B¼_EF&{S[#-5H5R튍u_5h4ږ?x( o (K 3(NWwv”i99y[ IDATغ}zNýRiB bnjHD^WΝ;)銊 I)) եӥd۪_VQRF6zx? LMK/**"*/dA  #A2mDAAMdtbYY ojht즯Nt2\Hl6&-욘֩t'i0p3)0ىMV._2lo&Xr +Xc~6֢??)@P <%e((٧~g5$'344:z{~fl\ܻظ^=[`ff* !Bihtܺy︉p&&=(rꦴN*vJr󗔖heUUeK,[$5-= 0($$8$=v"*̓IX7I{ If(I)#*xYyI511;'((wF &/^pi/^HP&y?hhtyh0jԢJvqk}N***r\,6M9}*YzZ1La&!eWHLNni]$%Ll\|}aԲ0'JJjԖ!m v3624627wv-s6l/xKl0qQ눩:~T'NEE,--++2㑀$A @e鵵_G! Eļ}Gҩ ;ɰB={eoFV]l07lUUU 555p6627nc۴!7m )7`ձIo]U$u540hI޽z!jOfVk65u1t>7\"?ܽ9 0h: 5ļz:~GH^ ZRRӊHЄPb0ll ,<VtttzwxwX,9 5?݆5ԩV]V~ћ\,{[o޲MдS ;''2k !B[YXj^nݚ<ёd x!Y#2]wȠ޽z6qKg қ FaФut[XCL&sTO<;/q1xx<2,'|Y2JehN<"9|<7p8XZ]?ᓺ6ȕz{Oㅻhdfu)OI53e->:rpBch4ڎm[@(N6(Pv}|FxN yC巤kzN9,..((lNie5eD3P IS">\]U{Px1x~&8yzϘ>c.]"B߹wnO:C=xujHi@ oJMKgٹy/]q.6.tuuf͘&z}]~YM6t W 3>^S=vۓS&ja._@d2Y,V.T**"C \$&JJJ}m{;jsvnJƹ46mkߙ=w cc$y6drwsUTTJII/fϚ!4k=zڱ]XTv^y]v1QUU~'tѕZeAd{䉭B}]\x2olr#$J[KENwxeKDgC>i^-~l"+B B1AmyOm1p8L1gc}衽{;zɕRuS56U  /lvl\|EE @_^-]tuMLixqjjjuuu 0L9MS'mcI)ڵU>u:%5HV۩|eiaN4e2Nwn]o&!B  32򫫫UTT'FS d<[j@jZz~~>ִ07Ch,KNNNCSSSY\#dG~sZ5u-?YA_8yC8p!B! }JJv zt>j/B!:`o\f&km-E!B!9}BB?x,~, &O0zTK=F!B?0hз)11ԟS'Oڽ/B!`oSt2{u/"B!`oS?~6_!B!D!B!BR`!B!BH B!BIAB!B!)0hB!B!$MB!B! B!B!4A!B!&!B!BR`!B!BH B!BIAB!B!)0hB!B!$MB!B! B!B!4A!B!&!B!BR`!B!BH /VeyyХn' /B!B & pB!(*(|jjk@NNA7^R(r8@銟q {wO+`Ƕ-"x<7B{WyMQ{$PSU]־^ז\&$&XroP]]W=hjvTQQiVy9+99Y^E]n-i9B5&ҥgd:8'-fX]]o/k8={s5lg=O򥛃B?UVVrkoGopUU;u, UP ̟3w,6ovrS[Kki+~ZSԴs>˥vh4wۧZ))m, PʟIF!aNN:C"&p/g3eM[} B-AN.HĤIy.n^;wnnIzF5MLF(''S$bP?Y\c_CuzLj1tR1))y+W!$; HQS[{% An.wnBEDwAxxėnB!_QSSzͺ1'jvdy;qtӻץgSc?%FܾUMM m۾CxS!O?;p3D^dXYsOJHytmpE?,/1kZyy?-*8w?qS2!dA)n޼]RR V.7Μ >Ȩ/B?ȱBpڔ4Yҕ+q`ݷw{yPKΝΙu Np߅K 0nzZYh4yyy~6ׯ\#_%arE <~ƺ|FNJؽukE aCܹAVA)N>jjjnn@Fff`Pp[\}feXZZ_VV.Yo3e?aJJNDjvTy9+11):mjZ  IbZQ\.7#3]l\QQ֦EǼMJJfXMWȇX,VJJظ/zZI;rsrb޾ʒbMmmzFFwYQE!w8}?Vi׮* Ifw*++IlIG:]qbظl9v_QQYnXN˖.!_v~()q1M6N.n\TTT76v.n=o=|>_l)ilMZA!䨵mɺff{@peûv3w]=z6I ;y =yZ1lJ23wʲe M4飫WK:5geG@?̪ ֶ M-6nЌQ&Oadi,Yqe^ֶD.\$}dO`P03k|Y_JB9;9-cf;8H-`fjB6JK˚<[nn ruԔ,`ogGVyur]jK,ʏ\<~a1R3w4x1'BБmظyYupX+W=FJ{`dr&=jf|e4!:z'N4LlmEFX[K*Y?wc2c精W^_2JIIv4uT먛O;,t5wI^߸h:ٕ\.|WPÏ?.GL&s۟;CN;LfJhFZaacSRȟʊ,lcDp8\~()2}VFf9YCGJHH$jkk銅E[xݣhEEE=޾uة> FDǼgc-z499\3fϽ{NWTQQ)++ q˖|,#bO:zt` pߕk7Μ"n5N1ԝ[+oftY\LgЙL#@II̯.++})NkGw*bEAiiny2Lv1ˤ/Ç #{jkkoUB?U YhMNMWd2vvyeIɖICcޭ6ɌxIѨ/6;p =#c i4u3&z!O { ATpܫ=^]mU;ԾjݻjֽG]m݀(" *J?1 !$}?|kn9$O=#CJ`P(222mێ?v.]W^;pFi_FD5jTaIL~/$&[nC=5mZJ>3&M^[W. u۵%={͘xxd ]uz]?-Y<0g DDVliĽ7";gV-(8$tt17o_˖q/~kW/ :3fWS=S\Eͷ{~C 5ӏ+fΞ{mÛ56 ճooZFƍΝ:~.rڜY3;n:٘,=ˈD[N1Lo3f}*VzaΟ99l`"s5mڤzzswW=~J,YV\jժ殣rN:-Zo8SqKO,]S}А[ǍMD:/:cG-a.~xSSS'L\Ƿ]}~tĽ_dJ1i;EgluN/ }_EDDhL|=r~ݺM,6hXt?EպikGdԮUM6OD+Wy~;u7i=Əпo~Y%6Y}z"{֋2;i4#W_gK$-7^'y:_BBC9JDYS q9}*iu){oDv)nC 4NDq"*Qguo=yG_ftǩgOi?^#_#&EQFQ-[ f͚< IDAT6Xz+gLbs `#FyfLP#ˋ{I&-=ER4|UX11᫕}&mwL??_,Ov__>3mP`N∡ɓ&N?_P(rʾ9qO?.&m'Ugsb"rwW_gW_Yv=&F b@_~mzzƮ={=<<<w Q,ۧwMT*NyА:nM̛#.?yOMzR:?~ҋ=V+Vc6m5++'Dtлwa^hotY3mݶݴXn[~^|33DKDWmxLDJw5={,kv1_ۋ5N:ݿ_Ot_~DNwi"j߮[g|O;5n(gkN_} ~;rXx"ؿo3Ʉc߾÷D Q#Ç^|od:ݶ;ӳOWʎO˖gei]~F>kѣFXss]ŋ7w^j+[6WI'd,?Vzs%...[fw|}LRLjժ޺u~xxffEEgOj0zl8bE"пߗ_KDoèhre/ճPsvB{wtӃ8Z5k0w9o/\ ˆH-HKOclP~Q֖꾡ݺ.]"Znizww [Q]d4رDԪezyxx\rE_ru1wwIe˔y B&$$""IIIխS[?H]._qݺZh򙔑wJr)W63ÑYC^00QF c"9e8"ՙ&%%m q _/QlEoYT*cyrZy䔔zxLD 8++kYko Κ>JN@ezef$\l[nto"*̬]/ݡB20"f2qc Ԯ}DGGUҨaK;~߶f2 7J3`5{U`۷ܸy3++puڑq&3+++33,X-!!.HO-M&lz?o:))iYt?y}|VsAVMN;uRHhhTTTٲoǎ$֭Zy7m'NMƻM<~ѣ̄5IH;׮]Tl.*^^HEC6$e$ *xژip#QQ%óVLӳWW^ѣ>lC2 hh4rw~Ss+̞6Q]YRJJʘoZh~JcUX9%ɵ9a32Bv*VsM[>tH.[`gIظ;vQ # pu63~+;w>4j0e٧OkӾ&g$$$PPZnӧ?󎝻C9o||X(k|PlJsn׹|j.fc В$ո3@"ܱ_|EDNsԇ?ڶiEDmZ:yS"Q4Y~[K^wG޾N8OW6'e$,Vz${V9ۋÇ\odX4G;WRh00@Qz@ӥݻw~&Lץ|՞ٿ1i "&5jDFF6tտ!^%#JԞY~b&L_ܼ~!mZܩӋz T@$RRR| ));k׽dârW{Ϝ=733&'Ou gxeqr +%%%Ĝ߾CVPLooRv۷$UɹO鱎>9=sigVj>tnT|V=Uy%F;y(ʋGĜ2gϝOOpwWfee 3Ya{L'uvqqRr%J3kXy 򙔑TJ dwkϥ] ׻r>~D;8$T{b:@S(jNuj:^z歟ҶM{|[Lϓ-._:xȨ("<鍹͒.XXWVǏ,e[Dqqvݵ{Ӧ>죙q-hBDV^+>Lc3QR:vxOa#j҆%*&=c8O/"[H[wh\F|+]գ%~*>=rj"Wҡ}mw5mZIK-[4|mѥ#w߸{SM3}8v(ϺzyEIyYӭr+ؤSrƤXaC\0##߶8f?#(Yw'DDVɵhXI,GD4iX:""ĂhYC<4|XF\Wa0~Jwb?33ZX.^^^='9r؉OJLLLOX|ťKp"3lDDǎ %5kN'V^cX4!`VVΝGǮ]DԸQC/#Ԟtg>q^/ib#9%r"#L/,eg]zEf9ŋgP'y.=sGtawC=zw3EGƍN9{䩖-^^^-7TӧNyL†ȰcpTQvdc=1:ʂ}_=g^rr߷gM Ν:bv}p4Msj7oիg~[uv=ՌV఑3JYzҏU#c(deeݼuʕ+k$;jUT7vtZz{fȋ.Ӳɓ(@EDD+V S೏-{yb^z=Dt1Q0fBDufOyj՜Wr+9'1?m(2:PϧT1Bsϙ~'3U`O޽'yfܱH7nmnצ mZ""qv'OQvm \ؿ'$$ ԪUSwcpTQvvbMܯ]h//&.^w?^u6 )`HݻOAu3献usՖ-Z%?1{;/"P!$w._9f|zzFRrńrnXW-m߮m-/X}^ǿ]qhBQQQ{ ҥJnĽ...Nff W<<^yE":}LJJ]{(gjt'4;wÑ4AfRΙь\8-矯+N:mV6nzya?,w~\ w/:-$&&{S6:sDh86A_brrKΆ`GX.}DjQDz ޽[ՇO(;&7r?s69;wJHH z4<11qԘ񩩩o\+g :vh/NqӖ,S[A,=VzC%?TQ pG Y!33^44zC&~^nV5\5_"JKO?r}Gn%JCڋ Gv#{}}R/+VYم9_U=7a~6ZFƍ gΞp/ΞX] TGz79k޷->qH6OݺM[~3Z7,BڹS"xNҮmkõ͚6qwWXFIg虳~ds.Y3oiߩqVy`z6'3 'd"TΝA{xڟ~^ѪF {.m}8 =}+ά?1@A)V((hډ2KDɟ-XmӲZf4zNF±qs>ݕ^gjާW[XNk9j0"7]׺ zjݺvJնhծ!'I,22*c"rp/dee^N,9+V~ #ڴnP|8׌!"-t:a#7nڢ FODz~^txXXd'rZz-%99yOą ᣶5111++Ǿr՚7'N(RlӦ5%''wO4y'۵j$kԩ][@G͙ɢ07)o߸yy"j׶ZJըaC"ǟV╣tYtD/w͛5S)8te lܨ!9zlц? ;WO^r1O+;vB|2'r6'. oٳw_ZzzTTRx2T*?iAqn#zXg"-1~ێ6v-"!?6_ԻKh^~ ܵg5w!. kxUkt:X5sTOOO":t n۾#8$4))Mйڗ+WVT(/Y:cG3f}v={t};":rXN9,N(ӥ{/7yD:5kwjjQS$}[L/Û7oGGGleff,qPsqq=jݹN<:tK =tcqv?>$-WZŚ >БDrZ_ E~}]8߿c${}2oGs&N~'''GG?Ez_kWdM7zŞ;wIJJwWDDDZzZmU+V,55\qNZ+DDoNzOyox5raC}C?fNzmoߵ{s+ŋ7ڗ^9wuޫf3}/LXw'Oxu%\]\<}7kI$L͛5JJJCTڴimt6[=w^L%dlW^{kׯ7i޺B@@6+22JVZe?^rU|K6s _ywޞkw\]]׮Zg7o`˗SQQE}|^wedb~SsMP>ڥt:ݐ}>~V)Sy֢x豯+VL(~Ygz̚3O uiҤq`o]əKFD:XϥrPuϿƌyL2m`)V.W\~ӽ^~hm}fNjxٳů MJ5hP_BDKڸnuW^2ėUc?9w'/\W+K.(&F?~v!}z&+VfO;܊a&Bn]ŏ<( .z ؿR ѱC{RrNÇYYY%J5NeKƌ)mxzV{WChެtR|?q۷ܻ+6̙5C?;KMW,/>.aڑo>5lPʼn3CB?yR>x?d1#))iR*MU ڿwgΝ1YqfȂz I[l1F ƍlo,6](bc"sS+C(ęhhI(9+));e˖P!yU,ۿ׮'&&.]rPtZHop&'''''*UJ_"rшaCZ=`۟wC+ʗ/_rtBBBRRr2y۷$''ը^PEGG߼u;3+l*U<< צ?~gtBBC>LOO (_#֤D$JGy )狿#poi" KDJwWW7{ @Lh]T1u!DVpq^ؘOwRnK6+7(AՈ() :VڻQ`İ BPuBads XMͺqB({7lu럋ZmV@`>nuB2ϑ"‚Co]S? +[G^QQ`VHOMJz Ƙ)_zMLJh"Bj5i隴ظ{2~>(c(8Q1yèGD,[JR+?ԧq|}*/PCN\4t=JhJz{{[&--QL1bJKBbVu:]ѷ(U^KKHHx"EŀnY4y0rc׮qIP`aC&R4'3gωCJ8ߴ?PEQ1^Rt*յ   F q;7H$ sSxt:Vh|||*WY*##Stb]rOqq...իW+z7,l'9z &+W}TN_NĤK./^cv(^(t(((HTxyy0k`  sĹA qn87BpuuU%KФ9NDn֤=6..ZǏyvʜ3׬_98$i3t:sK[l:gS+U~s͉Iɩڳ¹b(JooooooZꚕiFe[d}h͊uj֛/oGDڭdffovaVݷ_["#q D[8*yġ"yB qn87H$M$"]IDE֐[K8Ak֬aiDAVݳw>m۴T)33sdJII%"JEDE A!$rsĹA qn'.â]|u7oX+&.ҫgw"ZvѪGD 7nRqq'OȨ|ݹg]!_ !q;7H$ s33CH' sĹA0OEp,̇~1yB qn87H$ Q4` &| BWLgi3gyUnT  ̇~1yB qn87H$ e[4>066\=jyk ܹA qn87H˰hm[s6{̈́x"jݪ5L׺%dXXbo[iԱ#ڶp"*Y+?+'g۽N۝8Bat k$.pa.p5k$έH[8^~bgE#M\]]g͘ۓ]\r) %$$Oa4gϱ _ !q;7H$ s2,XY19M|||ZWBBBZm@@fMTl#|ff8Oȝ$ sĹa 4irMwk¤'J5vV,]bۜ&.t:Gh=ES>}缠 Ba/T7Î zҞ^0|7w z,zҞ^(hK#MOD{;!6lBog_hyB qn87H$ Y41ťsDt {Ei^^^DIwCa>!$rsĹA qn'𜬬ƍw>)oz|CH' sĹA0Ood?EDG_yUOwڴne;)N9;w,_7!]bbVǎiq|CH' sĹA0O\n#M*WgZZݻR w|:˖.?hHHhhm6iscʔ)c>|CH' sĹA0O\nEN`tV5033S,j_pCgϝ+w:su)6[d"jԨnJMZZpppRRr^U*WVTBLP0/dryB qn87H$ V4ãǕ`WpyB>a܄Iƌ'Ν:ZfpHft{ߗnt`γVtƍ~$sγϾ!$rsYsĹa8ߢIJJ <<$z<ױYrl;{gaABP}ΰN`{i-,~aO _^w{6}=58B v_<}7w9-!$rsĹA qn'ηhҫgw"ZvѪGD'{^Ͽĕ?_}:anjЧVm_x uΞiϞpe8 Fry#q>87r3ĹA0O (`:.!!BVkxaff~yԈaet[CBCkasf$۠R| Wr+ݻ(ZT9H`( Ln8OȝsNWѷ qnIۻ`yr+جB  nPL sĹA qn87ۜ&CrĹA qvn87H\P4|ff8Oȝ$ sĹa8&XbܹA qn87H扣hG(Dچ !q;7H8'm$ Q4),8{m8o}ӂz6}-U߭臭.nnJ}/4OO.궽`MOwý]$żhOD<>fysf5k$$$tONbc"g+-,]gknD y,K$_Ln%XS}ݛZx}7ŧ|r7%מ |nMO܈IZZj9a}ޜ8g֌ǏL?V]1{1a >zBi9@<7]vv3qCr;ĭ!#qw$nA 9MV\nzB쓹næ//qF(XH' sĹA0OHs\\\:wHDoܰw[Ykj,kw$ͭ+$.QEpK7V58Lh"ˋ4in;̇~1yS~ t+un\;5qnL\f{6Θo|ʊnܨ{Q26'İ~1yB q녩ۻ-3L3B0Ood?EDG_yUOwڴne;Q)6;LeF #MΝ;/_ƌzG11FNLLTcG[lG1e$΍'. w!qpF6&]N sĹa>ηhlOOϐf-x񕱯O;`PFN9leʔw3a>!$n W4QolFdĹNmq#ثߢ jzvwqq9{m>rLޭ{tfAGE #1bk682s5jT_z&--888))xq*+Tte^4ލ(8 B)`D:q2{kpfV&dÖmڑ87k8[N'&| 筑'$rskZ%3ƹA0OE‚،i6'X.7>۸)+9Mb>33CJ{,ǖ F,`y"lsĹa8&Xb(q&.-old.˭sc8=[ln\q3}6 qM _9?{Kx;pvم!dJ& Q7qP4),1r~[TCL82%rmܟ >dHcHmJ{6m\fc+l&-ثK3u;VoC|!Mk0Q4ɦIK gz$Y"$C-;ҹe?ܷcK Q؏ إ1ky(б'^|Os5jZf͞3/99|7μa<0 &S  2\h`~W!<hrW x_ںeӁ=;Ϟ:X7fΞkF._ Ye_9>֒NBↅg s _e%n;1eXs7!= r 8f;gdffovªU*WDq(g(r)h!W;.Y5?+'AG&Reaf$nN? W;C|&Zv}D4bPUm۴T)33s6a=Gf&bȖeQ쇉$s`Kscùd>:q"9f˫d`eheU IDAT2u $$j_g|ww&n'Oefk7ovGQM]fCj0͍>Wp"9~q} p0U?Lv^'.&z"{<8EmHv۸G}) s}B 9߭%F۸\rwڪ;q-$ܳ̽/g緼q^2~[IƉno$$$T*UٲeMVDD!Eݬ!qa {,K߭3YW\Ns}"_mzr4%NqsO\nPG:m^yv$'n$d$ǯ^vI^2S\r\zmjgog9bbϯZ??ud&Ces3 C9n>w҉;s%`.ȫ+Seu6W2qr7ꯥm{5%|1g sMRRRH!C塿Òā33#Kb>w.䘸ϝ͐-gF݇NVc,_ V&Le獓w?o۸w^9Z5/=!B*0/A7ۚ;%DPx ew=5`zlz+þ5qt{7{5;qtdk2?cabYcn\,.^9.vtr`\0ܷ6KdڴM<==HHդjHVz?y=!""`N=pg1}6q3f_q԰Nk+ skBvO >|ɉܭ5q3)AY1qs{uʠג[[ )rݫ[yUAɾ{ˠF۸5n. .)u\}a=<ǯti"y,6{Ɠ3@qm  pEF$ϤcJ.xr9(6k2Ymf On|&ժU#"Fe6$.U^~{W c̊e!J@u@!I~M*$gΞ5Zą-[}IFdb>3d>76og֐)sg%lDO'6s̹XUĘ>=Nl>e|&...zv'k:xpDCwwelؘHɿ|5| N,;6$yhl0sčȾdf.QRpe-[')'N~"!MJD#_̰9h=ٿIc/7;^Ox3b]4 |gDM3nBZ}zם;{_ +q~}Y[:7H$ [ 5g]4!Q#mXF!۶8rǸ.I EЯgȷ"`-֜Ϭ떎ev+ɦDĹL{rcٻף{ݻ=xV*<<(8mwލ"$cr`Kp^(dP!BÂ=Q y!$rϕ H$ 7"}Os}9Ĥ$|GѤ;QmŔ@͆|5ix.BI\@DA,$+%7k@չiF ܾ_pOsXd_c+§s2N#.w!33[\!q/˽GK,U"qT~yx& ;-MI=pny'&X4K6s\ [m$n|'CH= @6)ki٤mJH\P4o<!.tnߐ87H扣hRXbc"%sC5dQeydvi#wYu& F}^#qOy SٻoVZeMEͧggiANX4 `adh<Μbʚ_reršnYkkȵHe9/8ڑ9r;sX4O'֭Z_tk*J7}17"~pȝ$ sĹa8I|,]wnnSI$[ IHH "o{7|e2) q;7H$ s!$rsĹA qn'λhOD>>>Z6om-Oh4nB 1s7Ü&tM?_[ȯ֛!مB`^ܹA qn87HiOD<>fysf5k$$$tON|4L;NSOT}SOM9H/;z }7] Fέx7w 2 moξ Km.~Ys.ՋYu4&kjݪ^< zsY3N?2a8"Zvrؘ;<|xq!-=˗Q|t>A qDoqAG(w7R5vHv_]*U,[˻Ҭs ,lg4h{—/_}S ܵs-QD&||jƮ߸ 2|dfB qDoqA&Lj"ev' >rDԼYS)?Mc\.4a{훥]\^̘5r6>><+ DoqqgqAġBF1evl{c׫{Ƶ HnFDҨaӦ BmDtа\gʦ> ڠv™8uHRv*d2~fԠ~..sPr}@NvmѶ/W]4=;q)gҵ+BkWć όCgqEzNQ3b 9\Zh"SZ|ރ!Gx']}E "78 |NCCuRJч7ȅԇ EX4QSDd$ؔPƆK~"O; | "78<4III!"c##[4Px! "78 | #NggԹ9%'wp}x-qhWk? \{gP^;׎kϲvv>ǝΟ+-P&wq[ޚԔҔnMKM#"33,9=h!ԂOTkϕtkz]EwRčP=*W25|Y}ЅjuAJ굫s]EpR35HIMMHHȼ&))IӃؔ(ADQJfxRB'=_f ! "78 | #Cv̞9}qjzOOO"JKK +U*:ALGϫfyjϫfyjϫ.~NbŊ+V,qs-mSDdT{ty\.{թ];qPJP! "78 | #Ci/A6hמ}Y6]r5$䛡A-s}܍i|.78 | "7<8;Mh7nX[!0hD[66;(L?9*HR2Ӊ.^ʳWP\Kk ,XÕ+UuX,TœY3 >Gx'ĝoqADoxi"˳LCD2,JD-]I۹ }.0(+gNgsCsi'DwA'%mKqsQ@qA/j&ҺU֭Z~fffjldG`~^;?~^;?#kU3|v^)j&萏9Gx'ĝoqA|BG&ڒ/ՙRT .EQTNѾ^Z}(銊U#⊊U#⊊U#⊊UDŽx>{@v+DԬc" n4+RY>/Q^Fօ/]Gx'ĝoqADo 8qQaq DdiaSX#+QzT'Ɠ&[P "O; | "78<4Pj f<78?!| "78 |D[={NQO8?!| "78 |N x򥳓SnjY~AmftW49ȳISbcH_2CCþ|̴9!DwADoqyċ`I||¤ӎ;neeټYWf2!խo?[>.^.4ٳƍ]WBBOAlJi/b r\[H~P0 ZZ ,m#Pm`ju'M˕+Yd fϚνig޼uۮ=:vhߤq#Q ) X,` X,dޛyOG8vnW\p+Ww;M /B qDoqAG4IIMesy?Â:\ 'ĝoqADoxd'˼0OQX1"JOK*%d2#^Cv+VujT*  ^O?Qɒy<: EbX& 8_<78 | "7qTJD49TJ-<{"˦.Qzu '&&DJDiiipF]oq~BDoqA#.JH__WoIMKѠ!Ã>~GDF?011lKss"bN kD" J#HR2Ӊ.^ʳWPp捿TNbccܽfddm%K@͋%&&''' JKKJ%BPw4ѕ|\eb"dWJ$PN_+?`+ Zyƴ)ʗ/<*isȧO1,X,NLLCX舢i~z/2{w^~da^'+Pkkkt%&&rcc}]uLL#BbBCC}3@&J%RH$J%DdbbbddXؙ?4 %œbIjZT*MMv P(41ѭgLt脸0``o`PL,bT* z@ѣ'74ם_l񜁁LO@ t(N%0pƏʦTagx-62Pic([ʦT:/Ύ|8;?gUj^ϋ::M@ 4P&J@ trSWy ?Wy ?WWy:&J@ t(N]7DoqADi:M@ 4݂w'ĝoqADoxqt(N%i:M@ 4P&J@ t(N% ;Ód&d[[[c##Չcbc,-UH$QQQ2F_y~JHH524*YV иUGFDdm_{S?KZ4"#""rM cc\AKYBS":"-:-hiOdTTRRRKS.vG^򈈈Դ4k+?<֟|nIȽ'{X˻BB{rrs-_ë|j5v|bJ\]7rv+Sz-wus\.WLӠ!ÝʔX|jNs.b}jsqZw.^{GP?Dt_]*U,[˻ҬsxXP!]$=w~j>DDDd,EL.j DL-t766Q]"?I/=mo_3& IDATJ -۶@ R7oBC֮^k^\J\>lĨ#GאEW׭|g_999ĤzS։~Z$x!]$Go[Ba&]KuηoFnڤ#q"ڹkSrmHRr.;UxTxGa}_i){S?KZ蘘'9etULkϾ d2cc^ewYg҄q3MDZ*5#۷5m.KV.\D\$ɲV^+HokWP2-:-hiJ͈ua͚4RRR}OtttP}"uϺ#..^ xx[[YEFEQo``%cYT%ʩ}DT^3Չ L&|􉣾gN?y xg}]W.?z'L 'Lr߁G724ܿwo=ޭ624i¸>x̽7K1kN ّJVmswwQEʼ1ѹԯ%ź9ۡ][}0i2mV/>v+ϿzߩC{"ZjMh8ktX #D">rD* ~Eĵݻ-Z]|eOO6آR]ԏISBCü˕poǶ͋۵s|:uυ6|KKOmุxOO.ݿ}S/Ξ5nڵ{/8'Nȝ#G|ʦD=5[io_jE>>5/_C;AD6-SƓ ӦNWX,^~#xuD4i֭Zr+[bQD|jn剓?[YYغ"㥾ŋo߲C`FϓCf'N&_X{>xЀ+;8ثHj4f]IDSLٍ5.^Dh|JD qcF5nԐN=%c6&: j׮IDnn;::{yX.%hɉقՏxתCD;,Pj63LX7KJ5k `.;cÇضyԈኛӉ(˷,T5:,0jF#-WX=}MK."%֯UV-hiJ͈۳kڪ; mx]s7۰NɃY:DA hD +WV"\|es/?|QDꚵYmC` 2))UJRaճ;8x=rٳo?֨^MFN1qktXP DQFRAׯ!Ϟ fMHa4ZGnm۴R\\D\+Ԍx[tZѢ5#ndhإsG"ڸykr[.C^d^L^ `k'k} zIϚ@?."2llJ(n VVQQ,DĺY6^tvNȨ(33ӫMǎװ=<<^~iKK-뫪Lq y"=y'O"J֩ݨa)Tqm{ JkIjWE L[tZѢӪzpf?ݳGR:Ia Xuٚ߿`eelMOtH.w<==vkL:YRRR(.4.1K9hD(nۼnZg9obn}6[tڈ!^ĴTq$T:nW-׫N⌈kUZZHuWr1IK%מ<q5 t?ܵgsцY{h@ زq=7oOt҉(*:㿾gi7kjmee5k𛭭mvGx 0ؐc,)I cSC @D")̬[.?|wvf?o۲IF*vF5M y"۠$''4?z(R-gD\[!0跾}T{J."=yli74wG8;h[XإKWnq޽=vqvV;iђV ׬jѼ>' 4dL0md+0]$t媊#QZZҭiiD4evYJ.1hjY{p|&;싾gV.+:&{_?]41Qދ3nן[|媛әgώ3"=nٺ}ysrJ."=yli5j4"Jv.:޿lɢ,[[=w{U=b# k l*SS}wKy?цgi\ٲY6YX;8Q`GG)Q"#7IҘX.Ľ)evd]Ѣs4Z5}$:k#.ELKY{rѣM[zP^Kιk\5-gD\KF'nPX\!J."^`آR]9: `FzCC224|G@^DDFSΝVA)' :M@ceʔa DqE"G$ e?}JDT9KYx%Kf/S}?XPUrJDkG4iiiG\B彈\Υ~-.{EEGܛ9Rq谠Sg~E__̸ 5/55~8f&OUrj贇M|8b;wמظ]{?yZJ+}4' :M@cn&Ϟ+n (LɞY>Dt=Mw#";;;61K#,aaaDTV-5{Ԯõ2)lACttUdG͵4WVL,J.EXbJ5k Իwv8n̨kWey_5-g ꛛGDf^, WqMK."^ܢ}]KۢCĵ*%%[^ԯw{6>5ClѪ풥˹5zt'Qc-yh̨\IъUk߸ɭM[є;pw>r {]USWʕhμ߾f޴gG/]y# nZj C`{&~}ma!4*b~nhնEѹԯ%@#6o xZE sLLjkIHH`?_n%qBNthT*N<5"ьYsD"IhGwݧ}g֨D>;z9"z| 5؇⢔|sG5jTOLLvfrr3p)4h_uٺi2>>E024_ς?}۲q/ݺd>a#?AD5jTwvr ~gS>{MN)))VuԖ܍0ܙ̹iשKLLiV-]K$&&=g=&nJ.q#sמ [Jcnݾ#+Up֣GٲT*MNN&ŋs3M2x [V:s!D7WWnը8_KUkfgbblM *T~26V&z(ڼG\K8\tjDf~֫_rq-}nH$UEZtڡQď=>|hL`ߴqc{R׮ކ{ mx4|C v_:DWmxvDt>"^ U=w+Yv_|!۴n5P}9gޑcǯ\VVXaY5̲*x۴eۣG=zLDƎ9d,)+Wxgݺ}yvޖ?XhN)Wߵ+ /9u,ǔ)9j}z+]I۹ }.0(+gN2谠TRRRa(11[NKOsQIJ Ws_K@jjbSSSq/9[ID"X$R>Pqe#Zԏxd%XY"a_آR]4/ݺvq^tM[{e8#׫;mu o6acd2ŸsX' UXXאonwй|y屢<18855޾T);'JAbcvsuU[tL_FW*Hظ8''&˗ׯ!aaafffnFF*RjtX;u߭:w |Z|+WQ-."ZT*w޹ckvm_rqc.".HII lffZ:iІ/Jԩ?ӆǓ&PT"/utiyoouN$ 'kk6 4@K711c$-\Q&/[s_NZ4o֢y3gϝ=\Y/6 KK?g6l0nla䇆btgGG#?~/OܰA=ss>V,S}EHS#˗ZMDCTR*ƚ+YX15O>蘘6666YXH-$))T);%%%{^MYDDDDFE 66Z, IJJ)akk]L0k7n^0o5{(&n[ҫ)%%[hXJJJI[%KK.DeieiSjyB1d!!bbcMML\\\r̃T*  llllmlUBBBhhL&.@y T塡ann.j_CR ;w7-&c߾DdB_7]o߾;u /^ޕ+wb N=xW]D)ڨi l͙Duj>u+5hܧv=WkHLc:CTVQ˻R7m]ie9z7{Xڣ|ju4Y~ijΞ;?2**s8vf9HrrVRBu8װ)l[q/^V@D'Oiڢ[r6װgVm;r4s2j<&0(OekkȮQ'NV3| "JOO{.) @صg/[3z:?Z[[ 4`_ˈhݺva%IDd$)19%%HK͘8""(Vۅ4uڎa+ryZZ'o=s}d^lˌLII133Ur2Kų?Xt9_###X,>vƃ=y˛L.c''..}/_"^ >uf{d5w56T2\"ժV|q_ LLL D"7o[`CrpՎ|"Y=>r86qI[ĤĘG=?y۷*?[q3|jj*}8dH##zunwؘMi_vwoƙDv@cRRRXOG||Mʗ^uч< RRiXXx`PТ%K9zaGq6>>uommm -Yz۪xvd/^ҹ؈}V֣wZZ@ 022JOO'ƌOLLrQc?xW__$""b_n۹}˷oDSG{{+d2YHt/mް6ݻnæs@`aa,CCV^s̙Ng~t}>!!ߎ?1lhׄH&ݽwm۶lܱE_Mo*F$8NtLL~>+4m;tf]EV_8xǏle҄OI|u?kCܽw/Uoy޽[7r*?x_F?~i׶KB| {dJ(*:zR>[>[7m`O{㎎vn}Owߏ"""cx+w쩰!]NZ7n>vKf߯AF+Mvޭ!#}~pǯiFD$.^\ƌg_ڶio> vтy&&&r|Ƭ9o߾S˞T*%"rpRbw9Z,o\&8߾}j 6^z}S'O zsPC$"\ײSψضy÷/C|xqDnFyZ3֬d2x /b[^zzzǍyœG?yC`P>؀Afիݿ}g/< |jo:jӺ[8{AEDž)""bae<=N?)kWFm]t9bxR:zL,m)sлW{gaɔs>Oҍb[(1111Y0oWϢ¾~dYbQc2aCcbffcOAB|qRuC`i33s?}8史^^ 62˃;~]tf3n"_/Netv޻cpp6֬Zaժ$ɠ!XI^=߾~ɣ=حkEK|OM7"٣@g4O>eT(#֊"]eNN/NNNNǴkonrUT666600ScGlmmc;w:NN"66%X6[ܺ+;kN/[k岿ؗ'Oq(#Ddiiqڵj^ʕ9XFuœW=ޫG6{ya;zzzغet+0(ʵD`c7WWaCfLJD2l9}fx~[]V\>~dL^=sz+wྪU*vy?yjLZpkDիNO]1]K޼a-Sg#CCg''n =𓵵MlWٳf9c7耭_ 2^~{>ta&"KKC)qpsqcGs/U䶼w9vݽ_EDž?Ɇ 9֪CD 2!͇bND+Va ;nֵ ޾ԚU6Du1ԅbNDs,d ֯]5alRƌd"Ko9KD$ +Up>6ɩg2}>wΓϜ<֢y3 s@mfMQRRv@ѷgϾݵ߯}zQۛr[:}C`խS{ݚ\mu͛3DtnUPi2],ю3%@OOo3 biiѿ߯l Q#B>8ӦL~bл ˫8Y__UoYF466^x<)jiiQӧI$Obldlɢ)&LcJG]lOgCkf7nvT'V'\.W:XCnjy@ `?DQƍ2%K&>Y|xq"rvr5bb)&zϾsYOenݬ2t = ~hhΡ3ϙ?Ș1#p1uǏDTJe@f3XPN>KDn0C`+DԩC95bxvm711iڴ1I/wN;&K;& 9wl]!Cd)zzzl>5Oz(bhhи Ɍ 9y",Je𶘛v>R}P<|F]Qz߿ ͫ"m۴;zكEY[*]&L޼FiZ8\jJ*+wI(H )cD՜߇z\G3帻eٶ/@6OSjrQ㥥,,Dc<==L۔YRvBP**N;|N|`^<x~xLB2hP&&jiEezm޸nԘ񩩩l"rrrlܰ-hLxE$,VToojbi/_cwr>/.qoLqD"qBBbM3Q6DEg\Δi3L:qddƗ.k+k)a#kQbn:$p<:&-XYp'giSg~Ѡ9DdiUp7O eOKHH`]@9U4111QρC @>pu-4L!00-z6 V)m4'(0]:u^M[8ɾ?uϾ{z C Tj*<ؐHjddaiif$ O=g\oz͵Kɲaևn٦ҝ (B9 rQbx\/]ɒo߽}vfw 1TVsQX?zUDbbbQ wi*600""">C`PLL,YX}x^{<|./r& /ڍ7n=xH,GL6ӧ UX,RW6Cg7*eSҿm*Ħf/(%f fy__UQI,r,ߺQ2/"Ҕ9~ђ|9@/"]3bEs=)i_H"-=_u5}Z~,Zݚv!"uºyrQwdS?:UDLE~A-Ԯu`¸uмY3_*8q4V.k7@PF5O8>&&v=KWJKK۴e[ΝN0/E\\OCCmz۶=6W* 7q`fj:@8ӝ>BL&yF7b(D\\E[/l6W"jҸіQ"Oտy*5wK\ERѪ w0{@oi6hw-/=Iͦeɉ߿t=7:+ׯ!$Zbmm5~ܘE\.=.l!0(HiwKRSSU~#ll3&O >Wkf*d|9]pR~IioTʔT?ӑb],[xN18866=CݻuUl &L&###GG`qS墊033c)eH$M^)J:MGټQGN)#Gc5k8JH$W]]?xd{ʕ*/^]t鐐oJrLBH+Vnݾ\Hf7p[DܯJԯNv`kohi|S{E_ۈcoB3Gݾ$艉9~+[ྍ-O[63H1YӇMsuc_qNHH1>bf']$s/^+V(m6nx\q箒;k_2RtPnJk{a)-G/]&WXyO֖D:bsͺ J[߷W:߸9JX{^ܶu+n=7A7| F"Z-Y4/؂G[lvٗGSj,āA^m6J;,X|Jqkƍhg*8{/=ݽd# daaޱc{"Xv1|嗞+Wb՚,x0ի4޻,[g͙N~r#'kkvGDFnٖu*ebj`$v%KMϿ͉2|$bv^z;wd qrwS"6oݞ$ɒUDT#?[47ժVٶekLSc< 'O89rj5\~,ߓe>"jڸ1I$!G~;oFF6%Jѻw}_Ho@/2K\ne2:&f#ujתQz<={<~d7niC1laG.WNZDࡑe{H$0et"222ԡnܨ!EDDt˭wD"qZZڍ~m;t~AU>Qrr>r 'Y" TJը^ H.â&$$YaDdjjҩS\!w2sވDb[1 e.:A$ɉS[m>_{NTۻQD׽Wl}DD׬ې~V W**\(>|([o#R뀀gU~6ґbNDg422"Z6>>RRRٽw1,͔IBƍoc"ѡG4id|rws{GEDDpZv߁Ddaa[^#U'w7jz&u{ 0o޼o=V1=JMf  tQy׾]sN3>pҔujڰnҙ's|Hwv구, d2ٯ{uhY_"Ho…[4w\.o[s?us-Xtki"!h^ze棕)ٵKcODǎ8ssgO;A1M4חH$oDDڵݵsOlӆmw-tC255)QB& U˗*v-evՊmۇ={}D&X500Xj(6raƴ~nD'N=w)..bӾ]'''_Λj[֫?p_fgnn^z?y8gp?/?wsF;i46 P,0nnnAAaaau6!"kkUorp߿}'$$ZvND7P(\0o6\W=װP j=wD$Q6-WBfMU\Nܨ]G߭~"ED1~}YAL9)n;n8dH$pEK͋fMdFj۵9s7))S66Ŋ I̎nbbzW˕{P..N}zp'\K:+d/8r| dBj}i3 r9ػk1&&oވb@ЬizeƆu~aaaiii͚4{ƻ\9,yp-]z%MK.7]}eJJʧϟ|* Zjy¹^=>999޸zi@~E"266ؾ݅s{{4;TRRH!0(*:y9;oƌnؠ>%%%=y,=]B}5u}? -SP(VZR;ۺkUn@mU[Wu@"$f彛ù*п/D)`ΜsGWRRw2bۈyٱrL-*S<m|χ TH$"\ x<^=OvlQr 8w*kG}3#ʦ&9u,YP[`qcnog{Elb玭Vb`XǼw_<߽[8ǓJLƤycGMr|}UW:/^֑W*=]ӰV"Cv'Y9^^^G;w_ܰ+4ĪyyyyQ'O*W 7.D"y.յI|ͭ]!tף6^K53)q:Tኗ&HթSm͘{~8{7ҹ !de+@‰мmc2";;^pp}YW_Y!?B6wb 888BcéU&3>HqiR+ujթQWWWϘp9lێ޻J>%\\\w7=[[[U#y aC$<=ٺ}H$)&Vec,MyXfť%\.WwPRI!xZu9>=-Za!=!'Mޫ_-..&M46yt7k4W-5w[۷v;wdƃ@a?Z$bc66msYj5Gyn B0iB9;;?}۷oܼrj?8977"}fY+{y-;}n`P(tpp~rsi_GJjJJ?T*f2+YY~Y{ȡl!D잃B>~X.yzzeee]Hf UknF*K;w^vmV3w,ۑcdKSӌiSOKMKK{&ͺwZj 9?nyc²1'DZB+MBYNzONIٽw rdLw ?w܀bOkլYPPQd]ggDφ|:/5'GbmظiێIƤ~zgO, &&>wqqٷg2BV Zu`_b\Zy׮߸y+=]Yyk;֭[ܭӝ瑃7Y ˗tnYSg c{<'O._#))_RTZZu+1acnogGΜ MsDzD*A6lAN9B!B!Zh50vA!B!R&!B!BJ`!B!BH L B!B)IB!B!%0iB!B!&MB!B! B!B!4A!B!R&!B!BJ`!B!BH L B!B)IB!B!%0iB!B!&MB!B! B!B!n2TZT/,*))-+I$s!B!ո\յ31wr웟 R-B!B!!H2,/ίk%s7J&Mɘdg'Gww <B!B4 i^nժ䄺IvNNqqOJYYYgX$cbcc,J"B!B<;'J >p]g IO55W?}mrsV]99dϠg͘Q޽5'O.(($kjbxqcx<ٸs-P:9 O1dL֭RiFVL2 04(cM2 eT*HP(tss ptt(/xlIV:3Fy'b`FF&é㓚.f˶qϟ=(=!\.n:IISR/]+GM222߼yj?κPH,x\.íL2 04(cM2 eccclgg]]]===3B!{&^#IМ1A!B!f<F,ݨXpd]Go׶͵+whNfw޻wl,)o^ ĩ?ٸsxd 4 +mllNةc8y 1E׫"pw'r(Ϙj!d$e`iQFk`i`(s\r ;;ࠚ{isgO2Urߌ_ҺUKZh8΂&dL(//߹{K=H$ǝdL777Dr߿ja4$ `M2 04(L5 040OYs^YpDEEE9><}lSO=n(dym㏛_|>nhf%4{~ӰV踺N{[B!B!dJ&M-ZԪ^Qyy>rЦM.]kPùP ԾH/vBL2 04(cM2 ('Myϣ(" Dr;)))4dgڷk{qwwWhjZTx(/'Fe`iQƚePe$//?bC镽dJMKKOAAw2g{4nr}6;w>/ 4n$Pnn^ܹ Юm_ B!BH7_i2˯dֿ}qܳGwfW#F~Ï̚;wvǶ-j2&еUQc_''3볲5_Z3ye`iQFk`i@y-D,mW(@jZZ͠z'7 iXz,2o?//[~*U@e`iQFk`i@y-5i"J VJ$ٕ",D,(0y7J.۾]9u+*-)UܹXL|҅+V^Oy/Ύף{ysBj=|,B!B!R&ZuKiݪoǎ$N΁w[~&=vhնz߳K z_KP`V;Ap(OL2 04(cM2 (&MtTqǺN2 04(L5 044B!BJ +;zx>cog]je19f{y ȝ_Wlz`iQQN^XVb_O(,7ܹ{O$k|]hx#~ں;u0;jfF!z)H 4QV VaZ(nxŦƚePe&<=ng"Xf.fpss[P x7߸h'?T*7q#Gýn:^%ŝ;1{|٠/ !D oq˛([k+"B H7EzX,?o'Tm1dL&M7wv|0n o^Aj{>15sڔvv<xzW#O:Jd2Qº>ɒ#?==&DV}F04(Ӏ(S4sޒ+Wck g&iuС}%-dVVaPaYYܹ ǏUsm}5YY;(p=zȼsnZBpja G6$G4Xo+6FGT*?b\]]?[͖[Rwr<=>{{5OڷW?{(iSXmn3d Bʀ JT&F!Q4i-l9sTU 666kVTX,IKQ^NF 2aME{YƼEt M5 04+M{!gWlƚePe^իWR D~=fmw*u}yЃxuq8R) F](k1ɝ4,Ӱ!nJ$j3&z1bɫC-XT-,70ʸɢNUȹ{-DD@~NqeLqxxU+tF$ݿ`/:998ּǺrF/u-z5]5o?8>x===t\T4j4 ),` (^8bB!d^Nm++M*`kkۢEء{tTRR2ow>q /7f/v/c*%2+M&D&FkfL*2VvFj`iQQ1M4p:(˷٩~Ͼf̲Y懯nF"UhGkҌ Y9J4S갇.9j(G>tFaiQQJ͘<~DѲ2JX~Qvvv`! kLP %'fDYnK B!&w7S|f'^O2]"lثgcir2J`iU ̛]rd1Qƌ+6=04(Ӏ(c~6bl;|(S$J;pp,  }{;fKKK on (aQ24# &[Y&qFXLʣL9 }.Y|>*U$v7#o?ZKgSRSIFOwqq!:{l 3OJjjhXkpttT5pa_ Ξ:&O*8B!D= E2&PTTĬd3'gNZJ䔔qΝOIM\y)qO0JKJY(--T_bQ^NF K2fL4ۼ*XobʘE7J~FXLʣL9Μ|c''ys7۴7ogp8>5kPr 55ADy9%04ж{1*9Ȃk`i@y4M[ k4cBe&&ShMB!dF4A֏r2JXn1c9ݺ¼acQƼ+6ƚePe*X (G7Q: qCiW짣-vɑsh`Wl 5 04ჭm*U7nI3>|{gg T^]gŋb:um4ʉo޼))) qvv@eee?p8!!!666>KwI7RT(ӤyBÇ"˫QF7“VN~~g޿RVڵkk,Tɓ7o{{{ F `%Sb;[#YP1c3ͫ&K,MKgAWl'://oذa_͚5k標(>pҤI-Z߿߾}6lXf͘UիWvٱcǁׯUVnnn~왚Wŋ__v}'=zQF-.]#Hk׮أGAѣnݺժU[bEYY쫐H$֭ ֭[[n3|߫:V~~ TҼy>}ݻiӦ-=?#<<\sm_&>}Fbk.~W-[ׯ;vٮ]s OZFbbb߾}}||ڴi3`:u4l_~Q,TaÆFՋӧO/**ҰΝ#ttt,..YIK d0cZ7Q.90R!7jF=Jjjj&M6o\PP߼y3a„ѣG+>e՝:uJHHJ͚5 suu-++ =vc5kɓ"HXw ߻WKeIII'ND0u1ܹsIIܳʺw>cƌ҆<}T[Ըq㘘|%߿_dIv|VXѱcNj/ e۴iӸ8_oHyd={5L ]ֳgE mOڳgφ>}I>}9a*++fu IDATٳiRSSA&"EEEׯС&yoFv&M|gJ`i`s¼,cϒQƙt,^XN<{n|]j͟?l٤I'ۗdF @<;v쐻J~~~yyyw޽}vNNζmx}:d>ooo?˗H$ѣGhbȑ/^??m۶'''oܸ_ߒ(O2yP( 7oܹ3ܾ}[СC͓JQQQBz@gmʛ7ov:m4@ 4`R[1hР[n?|ڴi${d:ڞի!CyyF 5k'7Ю]k׮ iѢ>={{[nƌ0y7Vn߾ݲeKsN@@wXXH$3XIbbbHHX,[ݻw]\\dzjl l߾("C7n7ojՊH$"66vР|=I$=zΝ[Uƍ={,((pppXj˝4iiJÇ2qM6=1<<… A622ٶmۨQdzmƍ*W,ׯm:v/;fJAAAF޼yckkNJƍ?|N s2 UgiŽ/$8vQ1u&99))rs]0cbAh.91Wj:}8 Gݱc&sغulD 4A:u,Y"իWGGGOJX|MS̘~J_.֭[$M_eL`QQQ{?~&da֬YrhҤIϞ=@(޾}YO?bXjŋ@.yf[nSlmm׬YCeu1i߾\\.{tɓ _'Op{DoU7>}:鵤yt8isrrH4i"1jժjC>tRٹs(nnn7n\jՙ3gd@rrrƎ Æ #)VfyY=~\z'+&77oǎC ֌n<ٸs-P:9Qd$1r;ғeE3&19J9|e(fIv!A\Τc,늍XwqժUWo߾={6DFFv?VǓA:&LtR!瓼3)#G)S(>HhjѾ}{tz:u (>}GGLj{߿?44HBxxҗܦM5jʼnb6zyy]6''=Lr gr3~kj8@ XbENNNNN5jx%/++dڞgϞ%tC2SN1%3yyyU߾}e'QV:ԱqeeeUReƍa,>iSgF:9OLS;('5--=]̖mgΟ?{RMq|歪=Ɖrtokdp,2=u FeαTM%GU]&&dkY1oԅ?4+62 ƺF.]bFӌ3ܘٳgB޽5[J 23_nɱUMDDt AA@J_֭[M6d0?$MRvک:V6mrss>}ڨQ# >}&ͫ\49rHͷwrr"w 9J*i1᤭ ?.\ +~嗣G-[ 'M g~;]||1ALZƌȬ^7 mJV:}1cSRS-Y uh{w+>jcZ4LAͰc$ob⌉{e"L@db;Г7A\4M˗Iǂ |}}%#TTvdM^^^jjjyyժUwpo߾_|SNr9s,Vs/^@f͘޽{]@@c(Rի`ooFV2S֫WO֭+"I 1u7&۫a._4OV6333///''$8us$555??'00P$a4|kf61Mvuvm\{*ӓw޻wldLo^ T TJsWWsTT,-h,9={aaalsw9"o޼yUTo߾MV|]K [r.q8=zNNNNR4++k'OpbiΝ;I%ɼĂ&ǎUYЦ&V8Ԉǂ+M\]+i1BȺa5:͘/KpryFM>uJ-C*n܅LYPәZinϒs2/:j=~zڴifΜ9fmR)d>ݱc=<< ?ѣCﲻJKK#/sԨQdr%+cI ܽec1M$ɽ^K$-[G;GnG(cL9{RV7=$L*Pٖv(aQ1 :0{ H5gΜ! ǏWzsN4 )))M6v37o޾}իWO82S*Λ7oժUr}UX,~ٳgcccK2ŋG޺u+P@@I̘1C"̙3֭[g28p <>"##(ېy[:(dG͛7+W ޽IYGR ̟?/^$ ͛7W.;fرcZ?" :+kժ#Rc"13AO~~23,UMZj>}RO?DV6L*laB J۵k~;w8;;D"GGGeftaF9Qufdsd+R4eKw,{\]]Wo߹K,9€UTih\4]8ol۾g߁~};wh!Mp4bUc{Ci?`sW]r F5@2*aN=^?X\V]QYe9B^T~Tmccc뛙 L9իW' >| 'O$ٖ?Vms>}~缼?/!N x,M8LӾ}ǏWVfsujoCus'Zn*4v}]~nRgsi޼)SVXQZZo߾ٳg(AAAIII ++G6{̊\"e___G_50`͛7垕Mn߾MXBCC}y&GW_ܼCGb׬[ׯܽsgŕg.]z*i/0ibbm'ʘ11dL RGiItW+Jjcr)-vEUބIA4OXJ=WldlVǏ޽BBBHÇLY0_& 5kT[O"Qv ''GճU!PاOK.СCwڥ깲5 O5!/\OgffvIM{_|h,]sǎ>t`/8uW}D.۵3c !1z8aUmT n* U)2& ١OBP\\| ez(նm[wI0xL=tQ8ܵشj ?$/*2DfV&][=GÌ$쌲0 s":dOؙ@a 1h?۷+/i'G}D_j' r;wT|JyyF[6m ÇVGhE۷oICӦM{yyWzJYǎ#E8Y)nܸŒϢ.TV-/𜜜\ "4[n;̞={:#Y?3Y}o۷oOR~I+9lVTTDXb А4ٶC?|2 r,XJMMK*Uw*ӄn , Erecl#%yd{Em>]’ZCE"MtU6\ML\3wsLb# JHHsԩS{4>>_???f^z҃*^ۛTÇ',YrZd (t 6lذt8b=4hm۶ 3_$cǎ%wʒ@"?ܺGEE>4}tfFnn.iݔ)Sda۶mJ(w=d͛7*MJNH+VPٳg۶m#4P^^N? ggg2oJJqɯӇYoccCLT*}ݲe#-i1!j^^@ι5\NФyq.@mt޿r0oaƄrJ5Pn%,c^6zMM{X%ֳ"?~\ݻwd˗[lr̘1/^5jTxuֵjժ/HLL=ztժU3338pBkXrپZjƍ۴iSQQQNuF:CDDD׮]/^ߵkŋ7k֬~7o`֬YcƌٺuH$ѣǸq `gg{2q\p! ?N^o͇Za@$+Op9"""v͚5dϿs΄ ֭SNXLܿ0fB4fɲ;wÇ322-ZݻI&ծ];77766v޼y"nذ`iӦٳŋ[n-((?~pppIII\\\TTiW_}UaT8a-qZtL6J{ZݒZݖhMˏ 6yOd۷_3{d&jĨwz>mdPFͱeeZ~.#(0ȡeeg=r7޺F 3 o?8>x=== {8c##9f2&ML="7!5PU`b))FY."ܦj^Wbٯئ {&[+9ѿ'NK:w\NΜ93h .KĜ9sˇ v?.jժIҴ4f3g^ZX ,` xArW8}t߾}K.̼Pv _LR_~o>\|N:16lWB?g%&Ni&5/^$E=͛7'TWm2Xzٳec-M6qqq?̱llld1I{Νnݺ)nr7mD擖ܱcGk׮'NP5'o***"CUh(?'3\+X7} h޶-{X,T|*HMK]Qs7n6 kݻ߀ֺ흻\իefzSRu8-1NNNI_}>ߌϚ4kyM{{[ 1Ab۷52̘Ѐx4p]uu[1y4pE 0l,{UH IDATCSbM]5zRNBn>9N-N>}Dq lڴիB {Qdd$9Ep8;J3&ѣ'ÿ'ԬYsÆ qqqfLVD"o극.i|_kיr\.m|;֭dլG))#anz+/'3TΝ͉ iPW)4AȌ0c)h'e}n\vDORijF <<''RJS: S={r6l({ƻw^~]XXw봴UQJ,?{ݻw<f͚#ݪQTT\ՠAݽe˖ ?}4++ͭnݺJ66>VvmMN?񙙙<Ov#`[&MtSRR:;;;2D z_KP`IXX \Qƌ){ &mU1SHQ ަ={B2&M5,(ʩj?~|ttbaLe%M XYNNNBRHu%H[rG(2&bh_~P^ !w֔1D4ر4\iz b,(]!ǂl : B UvsK kvѐ-ҹK%]rd{s mi^~"Ki°PU F2 (2&MBb11 <\: YӤHTQUrf{#^V'}ѹDpa ¤J +;zxٙ9HwQl}s"V%Qy%t!(p-eRZfM%'L2 (2]IaYي~=q.;tss=H<EX'w`."9Ǯ^\Tr޽z~?0j,4ɛs֙xc̕I1M9(9`4(Ӏ(S4yq=K$J7[t7kݺu߸yE M SקBP/| d0Mհ̒Xna9v1 =tdJ,ɤ~lfK廙hQQ"ir%WV^mNMdCvK[Ȭ%fSF²s&pÿ֯] 2ԫ=GW4a(*%Ad yP7$yaLq6+-9`4(Ӏ(S4JG_ٲuU(?ٳWxF! lS^Fv1CNy}:<&coK/9A!EEҤYh۷hSU=$߿j;9w攝O!c[4%LYhf9Lb~/+fR/H#&:zKJN7 041U%'<]ۙePe*& ަ:}f+-pX2MYNRfޓXUy<28M2)r7c]y5S\`W2^MjܬEkO/?;/Msho?á|ᰡ`FY1cO)_ڥ?XCK:$R*Q M,1`IS^5%-4."W6\l=?,XmDUW˫]r;i=QLev⨚Ek %"s2(c{U.к]lDRR-na@ZZοfPII֘̓?Df' ~=9F-'AP{%J+EYBpws5!+@‰мmCp`nyD"֬xLܥ߯8ּBbIDǗAVO^ IpW aBȲ`Ҥ-Z:!~=YVPE7ɞh"L B&VъzdCeU0uR+M,FkTnV :WJ?e3csD BƀX2&䀘K@}C %fOB,IK: 2N2{2&%vܠkҍٿi˘0ƆM?,ֶEv{LX" PeLX=G7V W1QW#هT=jK)ʱ^DM32`ɉ1`%`HG48S.S0:zA_G#LVfb U&nb(Ϙ2('lV(@A6l&&Yh9Y|caQ1INDr9_(/cbl}R4am d@쏲쭦_9\M?4O`,6Ҋ̶ vA֏ "(fLtN>]U=-zb6HD}֣CK5G*cqòttPP7Q`W;;i#â;ѹer{jGfeg{DPEi*"D++k}uݵuu-{+U*Bb<@H̝;0Ν gNڼY.Ϛ;?J*,<<"ۖm;.]t񬽽$%%Ç<nڶ66o߿a}6[=h@IȨ/_UZ[ ^K8{$)Yɔª )}_/nz.R?LFh72&MN-bx=GY&IIf>q֦O׮UrQYNmnGp[7mPs~b sJ7"DZ5Slڤq ~Ur5i}< J.z1M;;Fu UKЯgiP>FYS%(~{/ݧ,_]@n` xHD۷ldLKcFܴe ~[7)Zׯ'N"7p"gNw6lڲf_d"@S"|ZXi$Nd)/)`>|1 hlȘh&>H\ԦI>?oάɿM5xFOOKo[jѶԴ4/\DU0h@{\FFFDLDVJ:A2E/@DpS'r8EzA޽j(%z3odLF^MN`~4?)t:e(tGY&Ǎ555ɷX:s70M F?yFDd2&D԰7ĄTD4*@i2UeOsy?Rw'ELn >>K7xIGyȘ5?u?SOtRxP0e=N(1Q@(ٷ:w쨸dPPUTIvsr|>_$}#iDD999srrꛛdA&ZRA:46)Șh# /z4QCFFFJJJo߾۸yW=kX`⹸o .]JvϷ-M<]AXYYM4Ix@d&LXȘHM$VEȘ0=}qTQK:J*22&Zdzפ/Ƚ5lzT2ɮ=,Z W?onfxt"ʫ %%%+WGV9!1?,cyhXغ5 ks@ܳVp%)N;VEi, (#o dL FMN)K' D6٠vٌ[_rv.`{8x(߿h!µTQZƍƍ٣U9iܿ}cܘD7o廞˪Oqm-(2&NNN0 z?jgkRۗ{>~o:70 6 KA^gq@d/ }?ھLm2ݫ4xW.l#+ёF)9 gODٕR[,ZRbŀ')pUk&$$vyߞ {x։ڼq݀~}eVV36.n5WPINNN&?}s;*ʳ-]V*Q&fvvv8cTɘm` gX##Rnx PaDY꤇&R x]FݤLGȆt,D*`U3 IQ>OQb\TbR2X[ih6ڙDTl#agg;~ܘ̹7njղE^K*';I$'$pe/isw *dL;AƄ, 2(%Ő11H|@ʐz?!Ocxݝ0zIWCBC{ iIaa"Tqwqŋ'LAfVt2&OCW:No$^PK=PXcIv_vb Lvj0 jhuԃe'*V@D"(**:*:^:ÉL{ԧdH6(f0QFcԻ.ToHѡs2/EOFc9"~=G~$!!k3M)UdIa߈EA ?uh?kO<|ԨaxX!"֥3u+'.򬙻?DԴIB6P2&R'fa?k7_ ы b!iҿ_7 GޱkĨ1OK1:۷O}7ɱ>92adG+/ODbxM0+٦MkGDz߾E=C.*qcbcbii9j0%@QBP'@((NL9oc5V2<^lԈJ )&MD"K333(,")bIՃRp6ҩcJo)Šu_2kפzӃC,--]*UTЌ cٲ J 23?VDqWssx>4)2H%UoYț }'"d ))\ȡ%M+Vf(VXui] !cRww" ðAYu ۡA*jE_^1f IDAT^]??EsdLXd$Dv~CJ܏ # J(b ف AJ^޽~^s (߭%P@wL%'''$xfƱpD+I/lR_cJWikZр[rTؽ $MT=eW_wv>Wn ne6>fLRŭW~ʘ ]bpODD9.F^{b]x h7`HgHZ{k-,4o'Up)f$$$Q<-#zx}"rppTB\\\pHH$233;yHƍ^JBt~LzrJ 2懲 &rNMa{*P(ܳM2W=l Mm0)8~2xNhD2 ev ,@YEYnkAM|7G>9&bff\Ζ8tx݆ͩ^/ pfD2;k ,,Te_@&Qˀ'D$tu.Xk{ = @AˡX1mEQCK373޵߹3KoܼUk`$o]CY(QfbDGI"bccݾ]["{ᄊi( e ,@فXQfQ9;;wINN=~Xzf (;[v~( Z&cc ܽwMIBɓgDv rd (QfĚ2 2&qUhSOOO>svpHSkgی^`YxAF ,@Y(fƣs'\xHIDa\%#ϟYюӺmڵ<+V":x`E ,4D7t1Ibqr.\$'''lg_׷wb_<}܍ݫl\fݚUZ'ބ˘0ޜ2 e ,@فXQfQ6RGgODٕ2! &&&J*eٖ.+ZUwS3;;;-ZEk{ Cb^Db\TbR2X[ih6ڙDTx=GSTqZz>ƛ1QfD2;k ,`>!)9xKRcvH+f)SԤW4d@Y(QfĚ2 !$ML-#6lr#_|Ɣ֭ˬӔ̞r+)))DdbbҪe UꞻE?YsU[eדǎ*a=z49}ܔi3Ș/s"*WΩoaa{wrin5n鳀W޺}ƍJJFFFI2,--H('''Ɠ,@Y(QfĚ2 'M͜}⤯MW]ϫ_ycaasۖN;p#߸5x؈y ۳S222R~Qrr_&\|eOZXXX$"jҸd ԉ :|UG8;e ,@Y(fƣڳIߦM߻uyy:}-Y8_1!֭ZL}_%T'}meLjV111#)LDvvV/^MN u\z4:{lYR׮mnݺHM_233p"jܨK%J:x;Q2299U${{fD2 ev ,@Yx*ʮ.֭;)33J(!::\*UQ<FFF_KBc9#e ,@Y(fƣIE?"j#Af2e(===22ѱ,קuNNN''Go\a(2z4)(͙5Cq d'qI?&ID,y rFj M5Hxoό@Y(QfĚ2 iR_ iBMnݪxytn ))._5rİ ĪUݓ|ʬm*S$M΀;n ""Bj  oQfaQfaQfaQfg{j`Q@8dWݻFD>Qb\fWJu7o]hI<ȷc~>t!HԢu7oߖ)Sf󆵭Zx/^5g׈_#+5k᣾׬Qc9qby IDǏj٢ZUwS3;;;M/NDk{ Cb^Db\TbR2X[ih6ڙDT̵4ٴe۠#222fLf|;{Pbe -}YWxqKn`]lIL-]Vٕw(Ir`e ,@Y(fƣP&"9jffi^={(?ݛ׷l~ظ2Z=jķoD9w P/QfD2;k ,`<ʬ$Mb;~TɒG_5Xϙ5C+WQ FO@Wx !sz@gaYy=gǎ,[Y52&ytZGH$,aW5ĘYB")%2ƛ1QfD2;k ,((D""!iRݳw..&Ow@fVx?Dԧ׏7}/]Q^_|%UI||Wijn*,,̉(##A,Q1ޜ2 e ,@فXQfAG9[$""cc]y-&iiis- "IW 1mNkm)Y׮XhƷoCFDڶFiѱ,=.8$DRCLla#RRR,--GVx'++"OHřB PYY@WCU"ȥ俙D^]2ߚ5:s6w"3oֶdтr/_ Vd.^}箫׮ׯ_7%%R-KJܶwAލyկ䔐#@`ffs2eȃU Ks3 %%*--ʊ3)@ e|ii+*X,52'''l"HWmYt:ix;;u7Qbņ dvtF _[W=|ijjҡ}gԨ^]-,##eJGXYY/XYB{l纛F ʔ{vtHDqQ])($_""'$+Vzꖖ^9AJJX, ff]M)"v0k⣸4est 20MMM|> H-eeeDDdaa錉41X6㢜 @$edR|ƏEebblbR\( "QXLbv Xgd32266651֝_jA3116љ6>|@$M@@tr.e 7b# E Iv埻mZPpΗJ\܃f^8|xED]ƵtP(\v}\=jԮPb>Qb\fW ؓճw{թ]W fG9زEsų'?KDn]˗/5"ÇDԿ_-.wgb{{ի<Dժ_8SD Iɤ|ծikc(## V_{-Yu~5kezf͘6s|kP씯d>{nʴ DTbŀ'+N1]'O~E۷lӻl/z*Wv #͚ 1E+W]nCvv6 8`ú%LDK-/΢ؽxSן,,,խ(Q*͛1Lx=7/-o$ʮ.ʗ  #gN⥨tV>v*U2%K >2+KXBF/^砛n֭Z=|0ߓbvTL.RDta"Gqa40{8:uʵ~N:Y.3~<-l#G535wo=|cSRRL$]O?~ѽg_X~[ \kq뮙sx9jkW;vvsܬI%gPN>jkk{Vkk+nd%vmjee9(̹J{,`ɲ?˔)sܩ ,^f͘H## uܩCv'mb|,SpuN||dQV M7'":}i(v8iK . &}'Nnڤqommm]۹msrN fǐ& 8>}'"ɹODC5mRBl?Kܘ"J s .\ OD.x*Q\\5;)|>ޜYg|-렠Xw2qYkR)--5_ߪUݥ&yկGD_F(Ǹv=|`J߉hJwݧ؝p~*wIkk.:^.cX,ѽݛ׼|ipHѣ&߻-7S0'mR%v*U2%gƺ$Wƌ4;`Iо+WQvm՛gDb_Ԥr圸Ǐ(8$4w"j$s|Q^jlЛbbbBBC[gwv&"h"rv.`v NjAqcN-N qksnn-֮mm7n(L"V0;qںiWy 2v&)?bo2խS( IDATgmRϷrq7fM4TcAʟIةT-˔<tIܘfb2 i{"Qذiˢ%lش%y2QJNX}$)inn %sU+2˕㚜I C0[bllgEWk(v*U RŠ;Ǹv]Kȧu+pkQv+,?G5輪JFFFGwD55bX5W]:ULJSZ)ƍV(_^,oٶ#ظ8˗o^ fPp. . K} @"*nioKڮm[7Kޓ+&6J.%w*(_Rqa>ogk') rbou622 xg?\7%4;|'k7l鳭/c((c\$%%O} ߺiJj"vD ظ8M0^cY?X~cNNd[e}{vzT`v s211ٹms~כ7o}|ZY[Yܳ7>>wr&!!{=XaA,%5=oApHȢ֩߸yW:qp zoLRFe9ãڨM-5lx^ Q.8ס,]m߲VAIzdّQ6~zΫI"(0WhUpf؋FѺU ;[/׬sP}޺fooBUޭrgt}aFFF Peɽ iZ)>~|5K"jҸQڵq~:w)~Ǚ;se/jaP=.X$ ;uP#''~={'MP0b(dzjW^7_۶8 ~OVVuj̮ NjA=8KLll?>ᬒd1N7w Ϛ5ԫADPna[lIׯYYyͮp.\7mɝ1!vv˗.&'|#"5b($ . &e%J(S enmmMD¼/DFDy$VK*n@osT\mhXH$]>}&uNID!yՠةT-;ǸIHHg߀uj׺~ٯfJΈc\=9ݨiw' 7{7jҧJ4;ɍjeuGKWJRxcFDBa^+V)vW x)1^kv 'm)s=XaAϫ~]" |RvRx"*-az{QpHBBCaDR"|TIX̍l԰ajeK\Y/ {_\37ɋYYyށi(v*U )N1/{ݻfM?㫠HY8ULl\tLlYYYD{j|o̊+ ITJB23Hef*RI[IJ^pqVX4[W"=u:11)7nQ fZս 8Ԥ}QuʮD:u@D*yo&jύC{>sЃr"n]:+W$llK,IDN}@DKRmi NjA=8 z֬?%+ ǸP|XZjIDsg 󼄆buq%?w"uڥ@Ϙ;>rO/:MD x)]6;|q;3ylw܍)ޟNJR{‚ h_]VuOHH9f,;"ʚ6svbb$7mֶCaڔDznKF_uN"1}d䤉ܾswLIDC |Xɱ>D4apnX,^|ųfff&/̽`ED:9xg"ӻd䝻vԶCo"%#5;q멧:lllk6\gqi߫$c4n]TvuILL$ɛcQTRÐAh %wý5zH'mb|~}{ћo7lڒ{|LlWQ-Ϛ#(_PpΗJ\܃ K=w| $89)w:v鞔\ήe<{##x<޶{!)9}֜]- [֨O"wv xHDC\fU{2m򬙐x}PY3IImg3SӦM[YY=|fdd}˦kJMMs/|ZV9995kTpT%gΝ6b4={|ߥR%I%ՂH$r!offfff&+^d37l8usOs?'ZXXrJ֭vFD~RRnq{  e ŮgfΙwov:bZ—%J\8{j+HGDz'M5rI[)_-T:׬k歁/^J177ݫ9/e 'mTtKRRrhXXvvs94.\$H`WΥR%}eiiYɥ!'GDzeT"KLt /]|yeܽ^ANP씯ԦN1=s$ {||xW|y=efe.]RŊr(8U:i+;|}׬,kkWWcc9?D"{{wڹT '…{Tji p PY~ qgAfVVeK>l43 ?yҾc︹Us *%M94I94I94I94I94I94I94I94I94I9HBB׈"rt,[N۫_#ͭWZhYfV 3S).ϙYY\,ab.\hުMVm|}Ok{]#;;LjaB)dD"pvvvbK-Ðmvde pbm @BK,wυ pݻvٻ{G!V}YV]"*[ xٺm"jlQmʴCD׮2hWnԡu8yj DԻW[7+.eێɿ͛3KBhؤyHh(={|ߥR%m@AKmڻW ~qq]ƅ2p%k W-Mr˫ulBio"DTgB?G45z}6>>fLRbE":p0^Т^} Z?4 Rl7ٳYYYjղg֬ yv- R\"(22*>!¢Cŋ+9cBBoNN66ֲu~HJJyK/]Z llmJ*UQIIɑŋwv655Qf.XTɥg8B׈4ҥ퍌4 23|fan^3*#!AffI;ex8G3&joP(JHHP|3 23}jcc]Ys{O6&DeddY[[;:kH$rpp)UGttt"QsrJF<;;;,<\,&Jyjk1k|yee 5uY~^>rۖ5֫tJgظ8n',_7-_wU7oզCł^ɭj&7oRZmOoqʍ{;v햝W^ eݫWQi ֪] Wtó{>Dtu7hհT ]8*iUl'}ިWr\'gϵnJ&[7i޺[>~D'}}TrM7oƽz^6o.ӫo`'H`޻¾݀ j{s#"ʮ#"Kcbcs466nܰALlo.UGbbccbc^2 Z;~211ܼBvv999OACG>q$$$L9 ڸyk./ gkkcbbBDQk֭oզ}Lbx¤ɿMnJ(_+'66۷ȘXAfԌjEEEna‚k%yv})5KV۫II;uݾsWRR2ۗ+|} *VՈNjt]~[VhXXRS?~Z51"h'鳜SS[[###XߧL6btNNT=$&&usʴ/^LLLwf7o{U#mP#dfVc222bbcFDĴmi߁C))) m4r\;򕫙DĵHHHܾsW歸Ԥyf1_F/ge |~rN/_1ju륚oԮ]P8%%+Wˮի׹7{Mwx":f->էsӨ1H]58pTibbc% $&&q1=#Cx?W7n>r&D$=~ҥ{πRk. G7zܯ\ 4&$4tނEֳfv%bbc\Ɲjdedd=5lP} EI-HKK;~—ݫxyF4BGӛ'}wDUՅyqN VVV[6 QЇn_oѼ]3oAzL7oߝ=YƟ˖l߲ a?ypRXlii{綈"ܺ~IFD9(xyRwc\6;m EA?x8g"4 &DD:vxఠ?,cX,;чs"٫کckWm޸^:{׫o^z4Ûܼu{}RӪ%})5;DĽSp=m|Zs7mpџTqp[xHw߾=|3=ar7'?X<|ԘQ>͋O‚>{yzzÕR5Rϟ<|x7\v_< (S9~o[7m9KHDXЦ kɅ\3 K[ ߻k舰8 ADÆqrwBtt􃇏˫~*nީ:A65-}gN߾eK#G嚨 ۗ?Bܫg+V~?_riӺ7pջ{H$I$pb1g_{1$55uĨ9}o‚>| ~l!D6r/YYB-JH_a5rkWϟnژQ#^<:gwl=Fx|n;.ѽû#c?uD%\ _twmҸѥgc |\DߧJJV?KDԿ_>mAXW"j;v$w=qzܝ{+[ '7orr~}X{s>n/ף{7{֬qaC3g%'J^㽀;كQѱ~;)-Ro5-(8ڍD{vJV=wL"9x%Gb;m!K屛 rv.W7ljjZٹ 6gdDDqq>:wd---XbmL\9993f%"sssOvحu{AD!!ի׭S{חADԸQÍהzpv.c릶m|>\ͭ2Kܼu:whmm"?p͗ڵƜbqߨ%q߿{nݻvY`ބtnoaaѺuK"D@ympHթ]KysfQWF^}+7stcgL2g DN?qRdRs]=VjQ#elբԫNN]:u$ X,{>hތ[ee gL:oάS'sծ%^z |HvGDFFF.["'eN?q6I3ԋܨ#vm<6$y/_Q=+//5˸1|~%%PM|O!bŊM,:0הLwMo.(U(SVي@ (*{2]2D"(@6Z((Kh٣#tmgL.ivyr'w{|GT{=I4_oٓ'M(íGw`x]u"16'73((ETszҽow0o.zǿw<3,,3J^}ݿz࿟DѣDԺUK> ҂s?<إ gH`)Īk&~}|Duv3g"? ߽«/w܍^h.*2lAD"#RWV27x?o'=j]oAR>jpcV:|]]t6L1Izܖmֆxe5m3zr:tڴnF^^^g.r}ms<=|Aa+߹sWժT G|s ;ts6\QQ?m;#>(;N&"x33~۱399ŜA+srr`᧑*U gڸ&TPa_.˜M:1ٿ%Uǎ01 jvoY>EwDt޽zwڵ!vm=vKDF{\%od۶0 H|}|ÇDpbhؕѺ u&[n#Z5kp_%v3?X%KB<7JVb$˫mV|<|͛7*((8s6e(":\TI\Y~/Ν;uG맥l94=6`^^Wb9HDCcOQQQ͛nj~)33뜻w>f &NnFn ./ |xlUkN8^^={|8㣒۶IǎsϺ]@g2_r}^!VUUT(s+W:Iʶw'B~4//Z}|| E9;Mc*oM6 >z84֔p-wQQBp蕙]wp]׬YBHBP+w nP+\wȎ`c8Q6K+cm԰񳍒gorߍ'\:k'V\x֝d4ԩc⁃)@ gfM?q1.i5)Wn;;;W|3Ɛয়z*((Sm׬Gd]?m<4=N;(+A"z9S]O u  󔖖j 7u0aw<ďHBD+Tᅽ~;rhy |~7"gwhѲa Cs*}1mSOU]y-_x@ۭi5ZbW>JJJJBhD޽zΜ>̅ξrA_G  ;8ś~2vhzRf%]LeB4a;~W)׸QӰ]6\ݷ'ѓjQt2o>Vh/>׬i(Ӿ洃 -[p6OD[Q:7of!i<Iv"#@̇\r+WMQ~}Mرk!EEw$fM|w1 Wl ܸ^hw u ?=qnǣYXᗩ|=tfd2jS[]MNIKK =r?Io/f͚?Zjɽߪe ~ Wu1u{}UrD|J]8Fʙd[iz LۻYl8i-;uI 5*haDDzGճSOU= N񧺨Ҹ_!!6`PvgUE O++..ŦLÆ 撕[nkؠ~ZZB aa`]?&Χs?6tɷ󞽿'ҋ]vCL^ 5hw /Zwt=鷯_ނ&=)??p #C_6:bmTPPpj2=ӆdTgo .pH;pQ8z˗ӉvڵmCOZ>z?Nh} ׯR_nԭ5sa)gTĥqpwziݳ:}[bծv;^[:]L s%%%Wuթ donas0*Z>u3go;t1L+Xw8$iV7߼upK.߿Z)vml#[ZBO  '%*ԐܣNIIɚut_Dt;wg=VWlaYAfn^7(p矧aY4l؀+pߍwKb7G`TRz؉:BDիUӭM鼼ID1Ѻk0}D[E6iLD).^$̵cH9!o5|wj4^d[~ݼB+V9ZgULixvqcN;p JCWӦM0,,x7GRGp9L۶h|z̙Kѭ۷O:͝]:GX$I"kFOYv=!kf7xk7۫׮j/ۛEEOCD/v/ص[{^}ԬS+~2žyF\y\YO)?ǙY}8bm}rzޓ׋9vEw]pٔ:`oLtݩ>}Z[W[D5T?V^&zR0ed,3gk4ƌ׮}f-XԳT'e89N;N#=Ϝ{ԴIF q(-,2Қטp ? \o8Ͼ[+WTNCO zb6q8EEcM;ҶppO; yP_{\W6< ֟|3gmsdIgh4֬c |cSOUWsn/kF 'O?ύlrwwӹDTZZ:0v؆=To]2bDӣǫfEs[ ADꢢ1yyy͛ܿ Wcx4d/6?zH\tiĨ1+Z=76R(ڵ% o^M~}{ĺDt=q9׫(++kBY|=r]\t&"ooMђ u#w蔩ӹ኉af {۲EO2y6p@fMсqm|Ng}Z=^t C|2?\VHyyzr +WOP=(= fV00vkvnl#(88# vh`":ݻHOk]Z~ܠG?m]ky4}C- QfX jN`M4RG_R>E~nHسssN8i~>Ρ~6}ro?jԪk ~Р~}nةwԩv/_gА޲EwUBn/HD{#@,?;*sKٻUuj'C N[-@J:vxAp ]t;gT7O|wT2>>[_t~ݺ+@D{GgdyssÇ ;o8am)G-**޲u]~n W^~w&o"-Ni?՗wy񕌇O>A33KKK[8ÈĠe(\D]z kp}Xv6Rtİ!?Zs֭ /6oٶRjOjj.sSX~CW^4q| |={ 痚_w.sUzl75 nACs<~@ݺ;(C?|$Ɣ+WLJߊO[V)45}lyfuԶt\HD@e\꫐i_/rZv݆~bŊ*&Mh0ccOpy$-<=\P&"o/Sޛ2u:͘5 Uz'b&=tM[QWFct9`aՍT[}h:/W\IICkDDm=(C_|6G;1/MD|'&5kX^uп;JgXqC(3إ3}q n;m7^OױC{Bj{5MPPCom~7r08-=җgw-*V/ʕ|z^65}Zչ9-V,bQnk>ӟ|?O0+=tN6kի݉k𡟟Q#mRP .c 13 `g.Yjoݾ}_5roJc_5ݽ$_ U[®SwիcTTf%8`ufN;B8>9}mԐJJJxxx=od)_|ݹiYp 镗_ˆzuVMKKSTUYӧ]t,x{{7iܘn"JoTo"z}\rss&6ol@H 纋NMM=^M\~ЪWqI [N;(___0g,@˘3o Q矫^7=x [V":},:uDDcCsjVVoXXʪebzm/\|QŊkTVw~@@y*TH!  W}wmw59ۊrk֨}Jͫ\1>̼rj^^^hhh \)h*WYꢢiB)ڵ{*ά "k#u{^`i7nTrbع+24[Bݸy[Z6JZ\*JJJ_SOq9]iiin+Tn0͵OjrJIII0?!Tʵkwzu#MwTTTܰI󴴴mZ]U #ĸuDԬ~)$M~7ODӧ}䉮z5UZv!_ջּDeK/&h{פy+s =?ohӺs @>JKK͘j=<<;ջ|ED՞y+/zw>4;tȍ7ߚ09?JKK^CDYG/ 0_QQiKODC Y9CGpc̜1 ]F{g򤝻o޺@gv?t7૗גE_[Ve.\mZ}1nzuΞ9#G'IK7{vuc$Mႃwƽ5aҁs~ٴY:K}ݴIcWDegg/[yWO|2_[Ip*U¶lx…VZu[D B+>jdVvVHpsvNִiaC%| ?H4_A X~`ZM5mBG4 $M i IH@! IDAT@&4 $M i IH@@@9W8CiiܼlգV={*xssss @D*egQn^i#ǴZmP]R940wJ&eL22復OpPSA$ 3+DIҴlv\ãz~~~#޾C*T[n=!r{J&/ܙTVmH젷ƎQ(˫}ָD[®J*}[>pDԪoy\Ƥv 9; nnnHD2 ev ,@Y(jBZXFx(bIVe?p6\sk׎ NIvƍs8xןM_q.]~-)8b[޾}z,?Pk޽FDիWW(I8ܶu2 e ,@فXQf陗zPODCCGΉut>i֌𑣫Vh4 ^ԩW\գC!mZHg_N;pi3& f " Czjdw|Wбzq3=<<&MBh]§Nx+W޽c븷:t[\㝐"٪GDĵaa/k0+ؑT+MN>zr-q}3&Fm׋Vtt*D4r׮_秥#??Q#YoY^!#D>D2 ev ,@YxZi|J"j]^2̾kGQuQ#>ƍVlsrZE5oT*28YXXlʕ+r`(QfD5 e0e&M HժT*c\=zOMujѶڴnoyݗ?]:88ؑT&V.7]_̟'lթS{jurrrnn^5kh%`GD2 e @Y((K5i"~^^+ pv ,@Y(QfbDGI)9N(/'cD2 ev ,@Yx4c g,K;QfD5 e0ewWBջ(ɎG7=,@فXQfQF?(Kukw2% e @Y((#i"%$! ]HH Fϱ=3Qv9$G.p.QfbDGI?pv N8e @Y((#iQp-is04QVmgdxyzV,Wx0^NDj.LXtބgt+'zCWpfbDG'E[~w9BBw5=9}{Sf<|ػgY3>hsl?yVKD>>>/m԰V` gl3#ez #OWpfbDGIffV^}_@DU*~{߸ysUYRw ~"z0m7_~%9*UrrJ|žoXSV:|`K.9bzCzy9xcoZĀ{Spgﺽԕa#RSS\:qIWۅ-Opw "JN;lvҩ?V9aިӒ#R{.&rbʕؠ fƣpmwdzf"ءۓ&Q}EE)Ӧ'kpK7ˈ+/Oy>9Rf'SO>mX>!(;:?ӫC7jwP6Hؠfƣ,JܼA xֽ+z/E5oFDj:###l%gLxV1f BY((˿Oc~?h;z[Μ=ƿ5V7AcLph~L t'̡T*6>V?$'vmQn.gL`&0 qr36 SAD؝rIz=i¸Y3>4X{;h>xoIjݪeܖM +YC1e"YGb-JdeydDyzB&#~lfCJWlXQf"m"b%ƭ#fm;^J=^확=|hktfMlX(,_11d,cBFA301!dDPwck ,`2cb^vFjvaDdzaWp=RQVs/))!gVAAm;pAdz11㪠1ы2:7%_|5 e0e3zԈѣF 7ݯoo9uF41BNQFK:b[ R!+6XQfQ s@װv&9W3!ix9#e41sx֎lU`7^R5 e0e7ϑ c!(#cb{5@S9sX +6XfƣJ)J/ԛX9Mr΁ dbQfb)ۛB'VpP]&lH AY((#ix9#$edL`v< (9}k:8SArWlbDGIgCD<59\$L8& 1Qf}Bc&˘e4ґ\فXQfQFDJCzĎr2FH((3CUAĐK L̉2lXQfQFDJ0z!c"fVhb6FH1^NID9y]Ò+23h#ib] ,@Yx4)--}7U*Ĉr2F ,ph]ú(#o"]bfƣ\;`{ŗwy.^ڐAoP( Wqۉ跄]*Ut駞p |8؟GԪnde&ӫ-uX/j9 H&g?;;ݽv툐koܘ=g~y^ weג[ܶ}゚MDu"d&2GCDm۴ϾVls1G{qfƄHװɘQF#) fƣ,դcfzxxL0O>O+W{qobsWuvm;tڙXk(`oy=d5 |?&M3p@:z/E5oFDwUUiiiݏLle<<G~b*BYx4)/ "VR-Grss {?]69kiimhӺs}w_'fzz*vuWrdLX gi 9 _}F:ސĚe2 T&V.7]_̟'+W΢&0u^jeZW5_HpNɉ2& B}W[lQ^=dL\ޞ(ę$78DCGDYYbs3fƣVq~dpI1q24帼\|uB(r,|.ma!ր((#i"%=@<139"o&9H:L *H1^NDk̛X$&9eMCWl+Z2~7;AYx4cN2L\Bsxy K$G fg\KNdk!,`M23{"ZUSOݻw͛+Vg_ΪUsVRR2¯^TRRBDfZŇyoǟmyyy8@9a22&!9QMҟvocaOW{fee;s4W*^_L섛vW3&|{LvBTa70 FYD 8MHs0c2l|,7!30Vr"!h&eL8([V}s;},:uDD)GZYh}{L/`}h+2)wmZE/I/Q: Om@ft"8޷ޞAb1$؍4޺ Q9*" p&*Qb:"jֶ4h4&L1kBXtI`[MrZJҤmXB6{#r/ ۣLď/Jaiwb\6,ǁ஺wX1QfQf#wLe*Uvl\F W8{{ֻb(#c" ,"rLй}sY&޺k/DGJMnYrU@@@ܖ_11×LGƄ#Β$//oD4wGjq͉tӵ[Çv\ ֍2.'3v-QFT}.)cI/'b58ƣ,s֮0~DT|ycCcѱ'痔xz*}9~~:Mi7хsgg.,f5T*"Q(ܜl=簪[0#Ȟ,3&0HFqnѣG*#jnb%%%DTT̜U+(]ܼ<+X0 tMM tɿ҄41Mf}YtȷIEIiQ*"%GQF݉s.$P2 eT8̮~;HoȘ@l"2MN ˬeLE%'b58ƣʐ2`˝ # wz%'oicPi"%=:^ɵĢ(#c"QW2.vef3&pDԪoBd"kc,(34`~.#cbGr"{0/DGYIIzퟝ^vDHppJʵ7n̞3C^/or…ǎt2kIm䨺t{7m88(OޣwE_/<5~So߾cl=~~~%ȓHCҝ"caGo/'#դIZ=tĨ윈Z+P^="h4.~]zù5͢o|6KF۫G-,ܔiϕj<5kGp˯ߝҮmj<-!mZ[z< 1$Hy7̙- jKU/o/~"!~SF6{֌IGFQT?7bph~LO0; 6KqXn?9޿8;JR NH:ʂt9( ? ?dqwՄ'> 3}cB$y-,NnfrX"u>3RSV,X[lҹ1]¹3f[V-գᫍFݾ}ysƌEDCzٰAY3qJKKMeDe/MǤ󗉨ndWHH}7V`bZv2 E z=|nw1'stsdgf稈((nIT1QL/,9oe[eKt}}}srT[/($"???U+.6wG_MNYI K 2&eN>hR$9i^e[Rk3&DZ"gh2eLpwwԑ.^d=ӜSie&,AdeS&?19sF#`GYڕ&YY={xRn\RJJDD_vK7nh4DTvD'"u{9gKdL!qU|Wv]uȘȉ^4qH0(K8iߧk/]z]ۍV:hCZDm޲tDVgHѤ>H}Y& ߼u*WvHf\qbdLdyCLIyjrϵk& lҹ7o}W^˖~wkZ~.y3RyB//eKT\ٞp:KǢ6;3g<0z)2E(PRMVUTƖ#=z.T9k``;g~[f6j`/^w6[?gާ{%~nkN}Aؗɐ1q3dpLwHc22&e,ob,z-M59k1pG%Q(;#ձ;%bo(((TWfbB:99977|y5jx{{;nC1e"YGMW һȘȀ;X3@r3RsTDMU #ĸuDԬm' #i"H8ܽ9L &AU`r('T Xǖr2OnD&>Q`"38іGloƣ+ B24p Y (cb]Ș g4r(.4;2&P`iȘ] v ȟEd(0-4`edLg4r(Nx F0e$M@l̘MTbȿ̝'ó4 ebWyCƄb; ZQ ߫-5LŚ(s0z`ۡDZoq,i #gfbm/=_Sf9 L$ǰdػu؝˼ X9F?1=ɝ66d9c$w⻹m_Kw蔹6 EoJ9@P`N洡E~ HN^Wa{ͅ}3%k@,P`2fsnuH#PDŎ F )h!igN/ܱI 2 eح?>Y#3Z}+ 8 kS*7A2iii!*2'c5=e ʤ$0| <3o5{KOkS*,gLIݻw/ܾsgNSZ!;FPƟ7_Ot{w .?$o~|KoJ]{Őر8?,*@,g?;;ݽv툐koܘ=g~y^afw۱{7//.sÕD] D,D9d&[V%  g4iXe^($q:e7wᵽ;c1AҤljs""j\CzH|s>rt굣FOسww_}۞}j{퉱L1m]Ș#dCYHs烉"p(FhkP82eY&ep"ZbyddnǤ >r;w&MbT( 6d򙚮ix!{n9}6 (y׆dP_c5Z)&Hϯ>|ƄռCOa?|8" ]v Y((# d3yr}х)b oI:Dw|kz;3aOOaLAEuib힌M2 ebifk5RTIi={S1q\\o gԹPE]͢W&}ZŢkssscaDdXRMcBJR N ,L 6>#=Ą}'Z$ DVL^ N܌ ȢD"}eg:v` &qNS>S3??q;ZE/I/Q: OmZ$F o+Ylb>M3RsTD` FDq눨Y[TXcg_E_ȘHo ,!ib‘ߘ`+="B1D2 ev ,@YT*Md1!$M,՞[) w=?? e ,@فXQfeü 9ٻK4~vՕ*Ur8IL޾ޮ gCYKϵk3n 2&bc:iN u( eD2;k*k0t8؅]vwkwvww(*et 0q30zߏ\=x3Ϝ{2&*Yhi@`P:Ϟ:n``P҇ 7ط=: r2 \(sb2prFjDqm;v噙D4}֜92%;ܿpGV]B'GQD e.@D 8e$M򗕙EDb8555:"[,jYYYYYYrzFz;;e.@QD;k.@QF$GP/¯=s2 \(sb2p.wF̹vm OɾFָqG+WRSS'11'=g*QO;"ߔf9?:-W7CDZC ijjNkJmڍl[Y3، uq_Sh-uX--=;1"46?y<(dffjl̗gddT9ў9QD e.@D 85ibdh8h` )BDNQTԷDo޾ '#1l(|d_>EfU˔)3jp"~[JD|œǻqo[ IDAT2 \(sb2p2 )V@`M32)*p ň8QD e.@D 8_ɉSWYafffffMtt:yiLDA_<.{o-9Ǝ^liSkԨ53fQDL- OXl; l* X,` XP W:i8FD 1=BYv555wl{83pB5jTZŞ8%DTfMU(88dڌ ɑ)wus'2%nԮߨC_i$11ܪe O((++TDDUZY&~N:oʳg >|v߽w?͝3S:vy6lٲ/^wUl/_G/:uɉ)С{X1zlZZpު2(1)Y"dggZ42 \(s5 \#O8 D$;tW;7J KԸq#;[ۈ "5bXݤzUxDclXw7n~@`_[ٚ::0xXhXX歝7IJJ}D ߳|~5d iii|>?##si e.@QD;k.@GFY DBMMӤGAeefX,NMMͫ(ck:޻ϟMD)J="r5b{PPL"?GMJ100UaI --M"Hr:jݗ%y\=IDZ(4UT$׋Y@"H(E"!;cRPHL-blm,ssYH$U~G>Em+Db$=6: VUF)=,(vZڥf&ҏs( H(A.ª~I%}?&#_V%xwޱ_.k-ٽsm%w {~Kv\o޹ߒ{ɞu9 i& i& i&#ps*5Η/kg͵eହkYs|8ka4PI4PI_ uD;k.@QD eB@$M@@$Mׇ'QD e.@D 8e$M@@$M@@$M@@$M@@$M@@sgR/:2k%"Afz -11)11Ѐ+LR/---&6 ;;::&WD"ILJJHH*Q4@Y;՛B+E=^I$_y<^aR8)vB0...55M__p$@FFFFLllU.PTo%bc&~,TS𦝯g0izFD%Y+%PZnܼvFU׬]eJ~O%ɡGjkg_~ToҢG%|eχ^{ɡF5.Y"##CfFF+kԪWzz w硗wNnrܵgJU6tɶRn=߹z j͂a#mԽW_%Պxq3g7jҢnCK_gUvQvURS-v檸%? }.u:XZM5lR'UDMq܄9iP^CcO铊G99Vb)yv.*TZak-8;QŽM[YSv~cm+;Ԭۀyn֪}E"{QS𦝯g"HVFD 1=(윜~>hPebbΙS۵m|sD2)/\""U>~ k~$E ͞9]^ z ,x;v3r̸J+6o($$CD޹홓}VS𦝯g0L-I"jEye4Raɲ>+UEKK7;o?TXw N ;{D"9{T1ټqu.Y4][PS ,HKII1&QJj"/An[jwƭݻ)+5v|rrCՇڵ}V_:{8tD;i@pX i%/Gѡ{Ԯo޸aM8EGӹiD4{֌ߺtf ;w8)Dap]Bm֋>F*Ls쾢>_xvVS`ޜ-n۱N3._FD5F.]>[PSTod8tKZߦu+%5~qǥo޸yBt-22:~LԜKy =1~;66*nA[Tq5k&663eʔ9w7 zG Xߺ~y>AbxD4}z3Sgn]:wbnv%T.PToT=z%&&+KJh٢yѕוHMÛv &P.\, [lѴt=;+TQo_53Ye_Ş`F޴U\|+.H@ɻsuԱp?}ODUYXȬPI?~#~%r'5mdUXY&DQc ;[["R̎%"[ J6WS ,IfLw_d%uVԱÞwnWKovv6+xڽc[A /^Sd [hVj]"D԰A|U`֪e CCBH7m*H ,x;3RRR333eV;iB? V\4;"Uӑo۱kʿ桡DTr%k+UHD!!lM===KK?KהjVgVt9c+C诩tCOZZZ}({ZM+P CQ ~q W!O,v'"J/YǽGZ~ْPKOOͫYftt P=o޾%"T{ͺ zcUN7Nf9N@hެD"ٵgty|B; _j޴B.>72BIiiiDddh8xwvas µLZzM555LMʐ/U֮^5w3aAx^&KM+PP8Eȸj[155cD%pDRRRN{6==m@ae fXk+˿׬ݼuX,fW9TrJ6WSp;/mm{v!aӖk׬ks5s{qcbb7oڄ燇G\~cƬ9^>;nk[5Q.3XqAJcF`3&~k԰@MWW%I" DU&S9%%UʐW͞@WWk?N=ѵGVeVHM+PP8Eȸ:`问\5008*C)$|:s\--=;nuĎWe&!|6kؠ>1aX;z7]]$M;+22w`+4-_|I.]g6WSR fjb,8֨!n:D ss"W!au.\ A٧hՙfQQsr\M\)5l 1!ffkV .}%;D@`I(aeʔ)_< E c766&ܼ0Xa.ժ95‰ok*o6GH$]!D԰a%ZPS ,N/2HRRr~ԯwݵNZ*n{ӵ73MKD۶lҼU;NJQG ejZ[[-KjժfD$ksߴ ;՛U<~0cks5oڪS.>$M95nHDA_ȯ),&֬33I !fM}JL25% SؼY3fk3i%3{K fgkJc\bWfp~q,233֭Z޸zI8p|>ϏOCDiq;PS6$oTYWVf)`FD~TG"3XqAJ^^=+)))'M(ټFUѱdV9zjլP xn]'ejufJ~YSS38$'5%c'WyٲD(? ,͕-Y(_d?խS*=^U^hтyC߿y}1Co\z-55Ufׯo"={9g`Ht 5kdsߴ +P/b|0#"SÛT`I(yzQzRR򸉓Y(;'g)Æf+صcnCnaDqB'sfM{laHh9h66C $)S(HVYה?* ODGys zБcD4p@?ۧcnt%-TSTo @O?؉ZZZQ28GL}r.֮)vzZ>99OzO}rVVVMGG|*++ˑÇѤ?bŚ0n,[vVM@SYA7v.{Z"W|Djj*eWlM5o*\|+I" "^È(9AsJEۮ=z53k׮->_ ?0yǏ{w>*Wzzz>khhwX{]X\v.)S|c'S_ʕF;՛H$Vovvvvv6322b o\>aE=^lo IDATU4sS:w>>ysd^2`>/U|| 1offP(Y@yACG߹rҩ.o޺ݻwoNPM{e333L[4o&H||%'o߼^z__EAC3"(##ʔ)x eCҺ+]vښ-7oh̨6cvVM@SYn*|93+̔ZMSY`I$D$ "XЋ{ʒtVVTVErnpQeǙ A&j]u[MWf;u\fUz0KDlvL27]^z3goa f5u1 ۗ orSnM5qrھsw6zzz]pmeM[gCO(]RRR#>~ l_y}U"(,<"9)ɬ}ʟchhXپYYkk++GD,*)ӳOoLת)v7 E=9[>j\jUjO"y<^E;;"=e䄅YXXTTIa%s޴U]|%|cbl\E"Q9kM~b7` I0ĄM[wC/8윜k\d%},Fg|PԈ;4P@I̞& i& i& i& i& i& i& i& i& iVI@Td"rp[҇E% cAI&Eb8'74y;'g鲕O""CCèϫ@w( i[] /Os  w+ڳoD4kƴ zPݻy{gȬ222j߮?'5qr*ݭXJ$jP;@}0 p]NN?86163356khhQzz7t~b٣D"9y,}린okl>lo˾@OFY>(Jz)J%KϝHDe:[.+UxD$?p㦫D"Yv]J[=ťQzu"?N7{U/ -pz@J%D$E}ɳ(gaYYYdVeffFE}D&}MU$VWV [q)L kؠS"_Y ̂jZZZn7e feew>eʔiۦ6j؀-ܲm=D"w׬KD'۲u{Ҙuuh?MD}zZf̮=zM}2ӂ4M6_V^ l:^BG2/[[.sf͔}X,>{¡b1SQq#~լ@$%|JDAL ,-{޻#w}Ďߦu35nHV^{)"oo߹QQ::]z ++//_mx$~Nϝ]ё)dOO/":owV-^=QΞ:Ex  EXl߹kޮn355aGٴes (AG['.>>.>>..؉7nW\:ruԬP\r/^;~Ҧ-[eoԯ_iWwޓ?wMLdgi٦c' g:s|v>{&HFFf\||TOɘ8RΝWT,LcQc/W^Ra$22m+^dL,lmuuuntإێ]{eg%ƬJNNa|=gE|߾}/5F͜=\r~=zdx>T~yN$3ϩbD"yGfR(..>.>)e1>! .Xw2kzy;bH$cO|)u~㺵zzzCGSmAm߱-7"V/>~1;[["v'?dԯ\n 7o+Ã=S̓\+Ws5c}n&{ϝUPtdx|t"#:"՗/уHKK{'Dyb==?̦.Dt- ҕDׯo\O $M("KKOO455֩}Ifx׮K} ;sg8׮QͶoT[ֶ¾;:vpֶCUR4yEDݻv56gdd=^{N̹x*ӿwfwmcci]:w"444͙%.D#]EDM4fԐ{Iڵj^b&M/~cda"fffvhܮV.fbikk3g$HN>#fӆu=wc߾}tmV5dm;v(~rcy8k۰A}"  +m2k<["X֕=y*=D"%mZ㉪u{"gJwɎtuMJJ.ɫ&''wYΟ3kFd֯WɏxJDG`.ysLeV`xܻ/y솴V-[0YP0%%DT}޽d6:x1ؘÙW»fBhPD8-66666pvEZ噅%M0 (Y`Q^] ss1}׷LallEf_D߻;c_V||kdJ5l =^i;Ѯ][]J?pHIHI6oemw?w*=|M[=ymܖnݙqvL8F~MLdT`)s "z̯qBNdjjҰA}?&Efu bS^a`!5n333|PZ5GֹS99O>ez-;#+`Y|TgXRyjhht*]bt܉ۧs2k^g--r"#;<},;;ڶm#vx;|}ʭZ|kDT.ab@4N+kfVr%ubbc/򒞞@ DBaDGfH,_NlfG|_Ue&-[>Ox>&"KKKʕ'Osss>b/utip暜ȨȤLP$ & OԪ%_+fbE;Av +VCwD"Q^?g'!ߏrJ[ѩcN;DFF߹SR3;qjİ]˔~i)5j ͥ@hXXLL ;-Z85n&MM:J%M7d@UroɔWߨ)i"#>!!...%%5''G$ #&H^zMDzz ϋL7 ?204 "{Un"938ur?faCT $MڷooNuܽtJvwPvUU2ʓOl>>$֭ZQƍtuu6q"/^Q.- 8uϟ Z3JH6 K.7MMMc'_S&geeI]t̚!`H5=lyƍ=nh" {MKKH$N  z<~JLO%~fRt:wwF"} Aݪe o_oY310I5#w0uNs+׮+oYM޽{g~7AHOOgfPIye'eةLMJu֭s/.[y53c"B^|o`c 6::Z?3*0!Mh+Z}C]B2N23i݊tut7jۇI0Qkii9K=wŚښh'%%ˏ5"===ߤɴeJna&sg*6U2833s6lŏ?9q̘Q#(33 . [JfFfQa&II>L҄IX3Ű]rrrutE"ѣOH^`gRNϜ=Ub_H[[[[K׏<)U}|hsעsǏCҭק&Mhgw啵4ZW#3#:sIzӼYSfQMe/07|fhHy*Щ2C̾_xշrZEf{xKMM̼9ff]( S@iѺK] 9HQ-Fؿ?:CCCe())999EP( TKv}>Zf6Zkdggfdd4y%3o;gL w:DTa_Q0Rfi~!G ʺߟ`}!f}fM먮C{g;;t[lAzCDm۴b nk0ɔlS45ȼz&&qx|t6wVHJJfDs㖫P(r OSTP8HFzF`l 왟d.` < }.QpHhll,Є۰a"}$V,--kKwtRSSO<]a;A\~3:xuR?5k׹vߺ}';D^aZժBY33GD)22qzx0 ͛5+і+W^DTR%A^.E322;v ݂:^ 'а7o*S;x3}{y0CE&Np<=PZ:5Rfj=3ݗ.]r'3bax< I(] g1aX/,xJfU\\܄'c"(#ХsGfaϾ2* µ6!ۡL/6[JW` >zcT1eZ@Pqnז2[ Dy˭U:x֭Z2i蘑ǥ/[,0bط#F֯WNm2>MrF\?{j?QnXGG;;;Бc7;KWPva+D" }sr&1U[FMZhQrj?Y~9 IDATS Gj6AaV_g]>TX~Xff̍wAn'85 8<;@Dխho(4$M ù][faǮ=T5Ds܅322֮Y޻@f L*3uLvw>ꙟ nhddĩ1>rVϸLd 711&"obۧ[nruɉaboǤ D׽W_GlOSܳo?tѠ~eKъU7oy؉'eY2OBH*@itrS@t0a5n԰GoJOOo`9 ##ϟ?g^8{j*YYY^{m-GC,߲qqbgN=gnn.ӧMDD$=C{gGLKQ&N::LCfa"]0oμhɲheY>:&Ku+֥AzA?EF6l3 ѥsիV,^<55ϩf[`cctI0559~;hA)SFy_ՋN=22*>!aӖ(>FCCc!֭.9uH~##:rI{ZZ?}bGcUٹP(|zͺDԳ{ ҴQzzzRR2jRfV-[<~Լ9 5n5559ww޻vwnmmehhv߯3U/VP&N{ G9zO߼iܴeX#V9owP]{EKN:ݫGӦQN>#Hô>ŋ>rkffjnn5NZ)IɫZ=c'L]Uke cْEoXC&ṆX\P5nhfŸpDҽoo5kļlч?}Rݻ^ܴlD4qk0\ӃCB7nt1WXbbb^zFןOtys[mm/_E"1߽)A7z{㺵͛5Uc|İwoڶe(+{zܙǤffxMzzo]:{:D\҆uk}f[Fr2K_}׭] a%:88ɘ895޵}=;IՁ߸zo"?EF~Lǹ,gaѩcx\.KX8c||';<<::~+^{^̊bwLfrrsǬ;sPHRnޭކ~pa``p||mesF47Ldjirڵ.ݫL-6ƆkVGN6sqddiY:N(G>?s;-Zhd29{۹§*=-iM?2M"MLLl;?|/2*{TwvBؾ^ I4sCovsci09sbWxcC쮮uܙD?8p_- VMb{{jk7m3OCp&P1vxep X B4M"D B4M"D B4M"D B4M"D B4M"D B4M"D B4M"D B4M"ʍ&UDP!$$UZ(?jB2!%- PA !KCZق2/Lt?}5z=ɛY(71q|׉B2~Ã0ܖjjI^#e{K[Y*B0Ñ/\mjI6nxJ"7 impulse = { ''').lstrip()) for i in range(output.shape[0]): f.write(f" (float){output[i, 0]},\n") f.write(textwrap.dedent(''' }; '''.lstrip())) signal-estimator-0.0.9/script/generate_pcm.py000077500000000000000000000542271452044147100213300ustar00rootroot00000000000000#!env python3 import builtins import math import os import sys try: import jinja2 except ImportError: print(''' error: can't import python module "jinja2", install it using "pip3 install Jinja2" '''.strip(), file=sys.stderr) exit(1) def compute_minmax(enc): suffix = '' if not enc['is_signed']: suffix += 'u' if enc['width'] >= 32: suffix += 'l' if enc['width'] >= 64: suffix += 'l' if enc['is_signed']: power = pow(2, enc['width']-1) - 1 min_val = f'-{power}{suffix} - 1' max_val = f'{power}{suffix}' else: power = pow(2, enc['width']) - 1 min_val = f'0{suffix}' max_val = f'{power}{suffix}' return min_val, max_val def compute_masks(enc): value_mask = hex(int('1' * enc['width'], 2)) if not enc['is_signed']: value_mask += 'u' if enc['is_signed']: sign_mask = hex(int('1' + '0' * (enc['width']-1), 2)) else: sign_mask = None if enc['is_signed'] and enc['unpacked_width'] > enc['width']: lsb_mask = hex( int( ('1' * (enc['unpacked_width'] - enc['width']) + '0' * enc['width']), 2)) else: lsb_mask = None return value_mask, sign_mask, lsb_mask def compute_octets(enc): return (math.ceil(enc['width'] / 8), math.ceil(enc['packed_width'] / 8), math.ceil(enc['unpacked_width'] / 8)) def alsa_name(enc, end): name = enc['alsa_format'] if end != 'Native': if '_' not in name: name += '_' if end == 'Big': name += 'BE' if end == 'Little': name += 'LE' return name main_encoding = 'SInt16' encodings = [ { 'encoding': 'SInt8', 'signed_encoding': 'SInt8', 'type': 'int8_t', 'signed_type': 'int8_t', 'unsigned_type': 'uint8_t', 'alsa_format': 'S8', 'is_integer': True, 'is_signed': True, 'width': 8, 'packed_width': 8, 'unpacked_width': 8, }, { 'encoding': 'UInt8', 'signed_encoding': 'SInt8', 'type': 'uint8_t', 'signed_type': 'int8_t', 'unsigned_type': 'uint8_t', 'alsa_format': 'U8', 'is_integer': True, 'is_signed': False, 'width': 8, 'packed_width': 8, 'unpacked_width': 8, }, { 'encoding': 'SInt16', 'signed_encoding': 'SInt16', 'type': 'int16_t', 'signed_type': 'int16_t', 'unsigned_type': 'uint16_t', 'alsa_format': 'S16', 'is_integer': True, 'is_signed': True, 'width': 16, 'packed_width': 16, 'unpacked_width': 16, }, { 'encoding': 'UInt16', 'signed_encoding': 'SInt16', 'type': 'uint16_t', 'signed_type': 'int16_t', 'unsigned_type': 'uint16_t', 'alsa_format': 'U16', 'is_integer': True, 'is_signed': False, 'width': 16, 'packed_width': 16, 'unpacked_width': 16, }, { 'encoding': 'SInt18_3B', 'signed_encoding': 'SInt18_3B', 'type': 'int32_t', 'signed_type': 'int32_t', 'unsigned_type': 'uint32_t', 'alsa_format': 'S18_3', 'is_integer': True, 'is_signed': True, 'width': 18, 'packed_width': 24, 'unpacked_width': 32, }, { 'encoding': 'UInt18_3B', 'signed_encoding': 'SInt18_3B', 'type': 'uint32_t', 'signed_type': 'int32_t', 'unsigned_type': 'uint32_t', 'alsa_format': 'U18_3', 'is_integer': True, 'is_signed': False, 'width': 18, 'packed_width': 24, 'unpacked_width': 32, }, { 'encoding': 'SInt20_3B', 'signed_encoding': 'SInt20_3B', 'type': 'int32_t', 'signed_type': 'int32_t', 'unsigned_type': 'uint32_t', 'alsa_format': 'S20_3', 'is_integer': True, 'is_signed': True, 'width': 20, 'packed_width': 24, 'unpacked_width': 32, }, { 'encoding': 'UInt20_3B', 'signed_encoding': 'SInt20_3B', 'type': 'uint32_t', 'signed_type': 'int32_t', 'unsigned_type': 'uint32_t', 'alsa_format': 'U20_3', 'is_integer': True, 'is_signed': False, 'width': 20, 'packed_width': 24, 'unpacked_width': 32, }, { 'encoding': 'SInt20_4B', 'signed_encoding': 'SInt20_4B', 'type': 'int32_t', 'signed_type': 'int32_t', 'unsigned_type': 'uint32_t', 'alsa_format': 'S20', 'is_integer': True, 'is_signed': True, 'width': 20, 'packed_width': 32, 'unpacked_width': 32, }, { 'encoding': 'UInt20_4B', 'signed_encoding': 'SInt20_4B', 'type': 'uint32_t', 'signed_type': 'int32_t', 'unsigned_type': 'uint32_t', 'alsa_format': 'U20', 'is_integer': True, 'is_signed': False, 'width': 20, 'packed_width': 32, 'unpacked_width': 32, }, { 'encoding': 'SInt24_3B', 'signed_encoding': 'SInt24_3B', 'type': 'int32_t', 'signed_type': 'int32_t', 'unsigned_type': 'uint32_t', 'alsa_format': 'S24_3', 'is_integer': True, 'is_signed': True, 'width': 24, 'packed_width': 24, 'unpacked_width': 32, }, { 'encoding': 'UInt24_3B', 'signed_encoding': 'SInt24_3B', 'type': 'uint32_t', 'signed_type': 'int32_t', 'unsigned_type': 'uint32_t', 'alsa_format': 'U24_3', 'is_integer': True, 'is_signed': False, 'width': 24, 'packed_width': 24, 'unpacked_width': 32, }, { 'encoding': 'SInt24_4B', 'signed_encoding': 'SInt24_4B', 'type': 'int32_t', 'signed_type': 'int32_t', 'unsigned_type': 'uint32_t', 'alsa_format': 'S24', 'is_integer': True, 'is_signed': True, 'width': 24, 'packed_width': 32, 'unpacked_width': 32, }, { 'encoding': 'UInt24_4B', 'signed_encoding': 'SInt24_4B', 'type': 'uint32_t', 'signed_type': 'int32_t', 'unsigned_type': 'uint32_t', 'alsa_format': 'U24', 'is_integer': True, 'is_signed': False, 'width': 24, 'packed_width': 32, 'unpacked_width': 32, }, { 'encoding': 'SInt32', 'signed_encoding': 'SInt32', 'type': 'int32_t', 'signed_type': 'int32_t', 'unsigned_type': 'uint32_t', 'alsa_format': 'S32', 'is_integer': True, 'is_signed': True, 'width': 32, 'packed_width': 32, 'unpacked_width': 32, }, { 'encoding': 'UInt32', 'signed_encoding': 'SInt32', 'type': 'uint32_t', 'signed_type': 'int32_t', 'unsigned_type': 'uint32_t', 'alsa_format': 'U32', 'is_integer': True, 'is_signed': False, 'width': 32, 'packed_width': 32, 'unpacked_width': 32, }, { 'encoding': 'Float32', 'signed_encoding': 'Float32', 'type': 'float', 'signed_type': 'float', 'alsa_format': 'FLOAT', 'is_integer': False, 'is_signed': True, 'width': 32, 'packed_width': 32, 'unpacked_width': 32, }, { 'encoding': 'Float64', 'signed_encoding': 'Float64', 'type': 'double', 'signed_type': 'double', 'alsa_format': 'FLOAT64', 'is_integer': False, 'is_signed': True, 'width': 64, 'packed_width': 64, 'unpacked_width': 64, }, ] endians = [ 'Native', 'Big', 'Little', ] types = [ ('int8_t', 1), ('uint8_t', 1), ('int16_t', 2), ('uint16_t', 2), ('int32_t', 4), ('uint32_t', 4), ('int64_t', 8), ('uint64_t', 8), ('float', 4), ('double', 8), ] for enc in encodings: enc['min'] = f"pcm_{enc['encoding'].lower()}_min" enc['max'] = f"pcm_{enc['encoding'].lower()}_max" enc['signed_min'] = f"pcm_{enc['signed_encoding'].lower()}_min" enc['signed_max'] = f"pcm_{enc['signed_encoding'].lower()}_max" enc['min_value'], enc['max_value'] = compute_minmax(enc) enc['value_mask'], enc['sign_mask'], enc['lsb_mask'] = \ compute_masks(enc) enc['significant_octets'], enc['packed_octets'], enc['unpacked_octets'] = \ compute_octets(enc) env = jinja2.Environment( trim_blocks=True, lstrip_blocks=True, undefined = jinja2.StrictUndefined) template = env.from_string(''' // Copyright (c) Signal Estimator authors // Licensed under MIT // Generated by generate_pcm.py. DO NOT EDIT! #pragma once #include "io/AlsaConstants.hpp" #include "io/PcmFormat.hpp" #include #include #include #include #include #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ // Big-endian CPU #define PCM_BIG_ENDIAN #else // Little-endian CPU #define PCM_LITTLE_ENDIAN #endif namespace signal_estimator { {% for enc in encodings %} {% if enc.is_integer %} // {{ enc.encoding }} value range const {{ enc.type }} {{ enc.min }} = {{ enc.min_value }}; const {{ enc.type }} {{ enc.max }} = {{ enc.max_value }}; {% endif %} {% endfor %} // Convert between signed and unsigned samples template struct pcm_sign_converter; {% for enc in encodings %} {% if enc.is_integer %} // Convert {{ enc.encoding }} from/to signed/unsigned template <> struct pcm_sign_converter { {% if enc.is_signed %} // {{ enc.encoding }} from unsigned value static inline {{ enc.signed_type }} from_unsigned({{ enc.unsigned_type }} arg) { if (arg < {{ enc.unsigned_type }}({{ enc.signed_max }}) + 1) { return {{ enc.signed_type }}(arg) - {{ enc.signed_max }} - 1; } return {{ enc.signed_type }}(arg - {{ enc.unsigned_type }}({{ enc.signed_max }}) - 1); } // {{ enc.encoding }} to unsigned value static inline {{ enc.unsigned_type }} to_unsigned({{ enc.signed_type }} arg) { if (arg >= 0) { return {{ enc.unsigned_type }}(arg) + {{ enc.signed_max }} + 1; } return {{ enc.unsigned_type }}(arg + {{ enc.signed_max }} + 1); } {% else %} // {{ enc.encoding }} from signed value static inline {{ enc.unsigned_type }} from_signed({{ enc.signed_type }} arg) { if (arg >= 0) { return {{ enc.unsigned_type }}(arg) + {{ enc.signed_max }} + 1; } return {{ enc.unsigned_type }}(arg + {{ enc.signed_max }} + 1); } // {{ enc.encoding }} to signed value static inline {{ enc.signed_type }} to_signed({{ enc.unsigned_type }} arg) { if (arg >= {{ enc.unsigned_type }}({{ enc.signed_max }}) + 1) { return {{ enc.signed_type }}(arg \ - {{ enc.unsigned_type }}({{ enc.signed_max }}) - 1); } return {{ enc.signed_type }}(arg - {{ enc.unsigned_type }}({{ enc.signed_max }}) - 1); } {% endif %} }; {% endif %} {% endfor %} // Convert between unpacked encodings template struct pcm_encoding_converter; {% for out in encodings %} {% for in in encodings %} {% if out.encoding == main_encoding or in.encoding == main_encoding %} {% set both_unsigned = not in.is_signed and not out.is_signed %} // Convert {{ in.encoding }} to {{ out.encoding }} template <> struct pcm_encoding_converter { static inline {{ out.type }} convert({{ in.type }} arg) { {% if in.encoding == out.encoding %} return arg; {% else %} {% if not in.is_signed and not both_unsigned %} // convert to signed {{ in.signed_type }} in = \ pcm_sign_converter::to_signed(arg); {% else %} {{ in.type }} in = arg; {% endif %} {% if both_unsigned %} {{ out.type }} out; {% else %} {{ out.signed_type }} out; {% endif %} {% if not out.is_integer and not in.is_integer %} // float to float out = {{ out.type }}(in); {% elif not out.is_integer and in.is_integer %} // integer to float out = {{ out.type }}(in * (1.0 / ((double){{ in.signed_max }} + 1.0))); {% elif out.is_integer and not in.is_integer %} // float to integer const double d = double(in) * ((double){{ out.signed_max }} + 1.0); if (d < {{ out.signed_min }}) { // clip out = {{ out.signed_min }}; } else if (d >= (double){{ out.signed_max }} + 1.0) { // clip out = {{ out.signed_max }}; } else { out = {{ out.signed_type }}(d); } {% elif out.width == in.width %} out = in; {% elif out.width < in.width and both_unsigned %} // downscale unsigned integer out = {{ out.type }}(in >> {{ in.width - out.width }}); {% elif out.width < in.width and not both_unsigned %} // downscale signed integer if (in > {{ in.signed_type }}({{ in.signed_max }} - \ ({{ in.signed_type }}(1) << {{ in.width - out.width - 1 }}))) { // clip out = {{ out.signed_max }}; } else { out = {{ out.signed_type }}({{ in.unsigned_type }}(in + \ ({{ in.signed_type }}(1) << {{ in.width - out.width - 1 }})) >> {{ in.width - out.width }}); } {% elif out.width > in.width and both_unsigned %} // upscale unsigned integer out = {{ out.type }}({{ out.type }}(in) << {{ out.width - in.width }}); {% elif out.width > in.width and not both_unsigned %} // upscale signed integer out = {{ out.signed_type }}({{ out.unsigned_type }}(in) << {{ out.width - in.width }}); {% endif %} {% if not out.is_signed and not both_unsigned %} // convert to unsigned return pcm_sign_converter::from_signed(out); {% else %} return out; {% endif %} {% endif %} } }; {% endif %} {% endfor %} {% endfor %} // N-byte native-endian packed octet array template struct pcm_octets; {% for size in [1, 2, 4, 8] %} // {{ size }}-byte native-endian packed octet array template <> struct pcm_octets<{{ size }}> { #ifdef PCM_BIG_ENDIAN {% for n in reversed(range(size)) %} uint8_t octet{{ n }}; {% endfor %} #else {% for n in range(size) %} uint8_t octet{{ n }}; {% endfor %} #endif }; {% endfor %} // N-byte native-endian sample template struct pcm_sample; {% for type, size in types %} // {{ type }} native-endian sample template <> struct pcm_sample<{{ type }}> { union { {{ type }} value; pcm_octets<{{ size }}> octets; }; }; {% endfor %} // Sample packer / unpacker template struct pcm_packer; {% for enc in encodings %} {% for endian in ['Big', 'Little'] %} // {{ enc.encoding }} {{ endian }}-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, {{ enc.type }} arg) { // native-endian view of octets pcm_sample<{{ enc.type }}> p; p.value = arg; {% if enc.width < enc.packed_width %} // zeroise padding bits p.value &= {{ enc.value_mask }}; {% endif %} // write in {{ endian.lower() }}-endian order {% for n in range(enc.packed_octets) %} {% if endian == 'Big' %} {% set n = enc.packed_octets - n - 1 %} {% endif %} *(buffer++) = p.octets.octet{{ n }}; {% endfor %} } // Unpack next sample from buffer static inline {{ enc.type }} unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample<{{ enc.type }}> p; // read in {{ endian.lower() }}-endian order {% for n in range(enc.unpacked_octets) %} {% if endian == 'Big' %} {% set n = enc.unpacked_octets - n - 1 %} {% endif %} {% if n >= enc.packed_octets %} p.octets.octet{{ n }} = 0; {% elif enc.packed_width % 8 == 0 %} p.octets.octet{{ n }} = *(buffer++); {% endif %} {% endfor %} {% if enc.width < enc.packed_width %} // zeroise padding bits p.value &= {{ enc.value_mask }}; {% endif %} {% if enc.is_signed and enc.width < enc.unpacked_width %} if (p.value & {{ enc.sign_mask }}) { // sign extension p.value |= ({{ enc.type }}){{ enc.lsb_mask }}; } {% endif %} return p.value; } }; {% endfor %} {% endfor %} // Map encoding and endian of samples template struct pcm_mapper { static inline void map(const uint8_t* in_sample, uint8_t* out_sample) { pcm_packer::pack(out_sample, pcm_encoding_converter::convert( pcm_packer::unpack(in_sample))); } }; // Sample mapping function typedef void (*pcm_mapper_func_t)(const uint8_t* in_data, uint8_t* out_data); // Select mapper function template pcm_mapper_func_t pcm_mapper_func() { return &pcm_mapper::map; } // Select mapper function template pcm_mapper_func_t pcm_mapper_func(PcmEndian in_endian, PcmEndian out_endian) { switch (in_endian) { {% for in_end in endians %} case PcmEndian::{{ in_end }}: {% if in_end == 'Native' %} #ifdef PCM_BIG_ENDIAN return pcm_mapper_func(PcmEndian::Big, out_endian); #else return pcm_mapper_func(PcmEndian::Little, out_endian); #endif {% else %} switch (out_endian) { {% for out_end in endians %} case PcmEndian::{{ out_end }}: {% if out_end == 'Native' %} #ifdef PCM_BIG_ENDIAN return pcm_mapper_func(in_endian, PcmEndian::Big); #else return pcm_mapper_func(in_endian, PcmEndian::Little); #endif {% else %} return pcm_mapper_func(); {% endif %} {% endfor %} } break; {% endif %} {% endfor %} } return nullptr; } // Select mapper function inline pcm_mapper_func_t pcm_mapper_func(PcmEncoding in_encoding, PcmEncoding out_encoding, PcmEndian in_endian, PcmEndian out_endian) { if (in_encoding == PcmEncoding::{{ main_encoding }}) { switch (out_encoding) { {% for e in encodings %} case PcmEncoding::{{ e.encoding }}: return pcm_mapper_func( in_endian, out_endian); {% endfor %} } } if (out_encoding == PcmEncoding::{{ main_encoding }}) { switch (in_encoding) { {% for e in encodings %} case PcmEncoding::{{ e.encoding }}: return pcm_mapper_func( in_endian, out_endian); {% endfor %} } } return nullptr; } // Get number of bits per sample in packed format inline size_t pcm_sample_bits(PcmEncoding encoding) { switch (encoding) { {% for e in encodings %} case PcmEncoding::{{ e.encoding }}: return {{ e.width }}; {% endfor %} } return 0; } // Get number of bits per sample in packed format inline size_t pcm_sample_bytes(PcmEncoding encoding) { switch (encoding) { {% for e in encodings %} case PcmEncoding::{{ e.encoding }}: return {{ e.packed_width // 8 }}; {% endfor %} } return 0; } // List of all formats inline std::vector pcm_supported_formats() { return { {% for enc in encodings %} {% for end in endians %} {% if enc.width != 8 or end == 'Native' %} PcmFormat{ PcmEncoding::{{ enc.encoding }}, PcmEndian::{{ end }} }, {% endif %} {% endfor %} {% endfor %} }; } // Format from string inline std::optional pcm_format_from_string(const std::string& str) { {% for enc in encodings %} {% for end in endians %} if (str == "{{ alsa_name(enc, end).lower() }}") { return PcmFormat{ PcmEncoding::{{ enc.encoding }}, PcmEndian::{{ end }} }; } {% endfor %} {% endfor %} return {}; } // Format to string inline std::string pcm_format_to_string(const PcmFormat& format) { switch (format.encoding) { {% for enc in encodings %} case PcmEncoding::{{ enc.encoding }}: switch (format.endian) { {% for end in endians %} case PcmEndian::{{ end }}: return "{{ alsa_name(enc, end).lower() }}"; {% endfor %} } break; {% endfor %} } return ""; } // Format from ALSA inline PcmFormat pcm_format_from_alsa(int format) { switch (format) { {% for enc in encodings %} {% for end in endians %} {% if enc.width == 8 and end == 'Native' %} case SND_PCM_FORMAT_{{ alsa_name(enc, 'Native') }}: #ifdef PCM_BIG_ENDIAN return PcmFormat{ PcmEncoding::{{ enc.encoding }}, PcmEndian::Big }; #else return PcmFormat{ PcmEncoding::{{ enc.encoding }}, PcmEndian::Little }; #endif {% elif enc.width != 8 and end != 'Native' %} case SND_PCM_FORMAT_{{ alsa_name(enc, end) }}: return PcmFormat{ PcmEncoding::{{ enc.encoding }}, PcmEndian::{{ end }} }; {% endif %} {% endfor %} {% endfor %} } return {}; } // Format to ALSA inline int pcm_format_to_alsa(const PcmFormat& format) { switch (format.encoding) { {% for enc in encodings %} case PcmEncoding::{{ enc.encoding }}: switch (format.endian) { {% for end in endians %} case PcmEndian::{{ end }}: {% if enc.width == 8 %} return SND_PCM_FORMAT_{{ alsa_name(enc, 'Native') }}; {% elif end == 'Native' %} #ifdef PCM_BIG_ENDIAN return SND_PCM_FORMAT_{{ alsa_name(enc, 'Big') }}; #else return SND_PCM_FORMAT_{{ alsa_name(enc, 'Little') }}; #endif {% else %} return SND_PCM_FORMAT_{{ alsa_name(enc, end) }}; {% endif %} {% endfor %} } break; {% endfor %} } return SND_PCM_FORMAT_UNKNOWN; } } // namespace signal_estimator '''.strip()) text = template.render( **dict(list(globals().items()) + list(builtins.__dict__.items())), ) os.chdir(os.path.join( os.path.dirname(os.path.abspath(__file__)), '..')) cpp_path = 'src/base/io/PcmFuncs.hpp' with open(cpp_path, 'w', encoding = 'utf-8') as fp: fp.write(text) fp.write('\n') signal-estimator-0.0.9/script/plot_dump.py000077500000000000000000000042001452044147100206640ustar00rootroot00000000000000#!env python3 import argparse import csv import numpy import os import pylab import sys def load(filename, direction, has_device, filter_device): if filter_device: print(f'Loading {direction} signal from {filename} for device {filter_device} ...', file=sys.stderr) else: print(f'Loading {direction} signal from {filename} ...', file=sys.stderr) x_vals = [] y_vals = [] with open(filename) as fp: for row in csv.reader(fp, dialect='unix'): if len(row) < 2: continue if row[0] != direction[0]: continue row = row[1:] if has_device: if filter_device and row[0] != filter_device: continue row = row[1:] if len(row) < 2: continue try: ts = float(row[0]) amp = float(row[1]) except: continue if ts <= 0: continue x_vals.append(ts) y_vals.append(amp) return numpy.array([x_vals, y_vals]).T parser = argparse.ArgumentParser(description='plot dump in csv format') parser.add_argument('-d,--device', dest='device', type=str, required=False, help='filter by device name (for multi-input setup)') parser.add_argument('dump_file', nargs=1, help='csv dump file') args = parser.parse_args() has_device = bool(args.device) out_sig = load(args.dump_file[0], 'output', has_device, None) in_sig = load(args.dump_file[0], 'input', has_device, args.device) out_sig[:,0] /= 1000000 in_sig[:,0] /= 1000000 base = min(out_sig[0,0], in_sig[0,0]) out_sig[:,0] -= base in_sig[:,0] -= base print('Plotting ...', file=sys.stderr) fig = pylab.figure() fig.canvas.mpl_connect('close_event', lambda ev: os._exit(0)) pylab.plot(out_sig[:,0], out_sig[:,1], '-o', label='output signal') pylab.plot(in_sig[:,0], in_sig[:,1], '-o', label=(f'input signal ({args.device})' if has_device else 'input signal')) pylab.grid() pylab.xlabel('time, milliseconds') pylab.ylabel('amplitude') pylab.legend() pylab.show() signal-estimator-0.0.9/script/update_authors.sh000077500000000000000000000065451452044147100217100ustar00rootroot00000000000000#!env bash function find_login() { local github_login="$(curl -s "https://api.github.com/search/users?q=$1" \ | jq -r '.items[0].login' 2>/dev/null)" if [[ "${github_login}" != "" ]] && [[ "${github_login}" != "null" ]] then echo "${github_login}" fi } function find_name() { local github_name="$(curl -s "https://api.github.com/users/$1" \ | jq -r .name 2>/dev/null \ | sed -r -e 's,^\s*,,' -e 's,\s*$,,')" if [[ "${github_name}" != "" ]] && [[ "${github_name}" != "null" ]] then echo "${github_name}" fi } function find_email() { local github_email="$(curl -s "https://api.github.com/users/$1/events/public" \ | jq -r \ '((.[].payload.commits | select(. != null))[].author | select(.name == "'$1'")).email' \ 2>/dev/null \ | sort -u \ | grep -v users.noreply.github.com \ | head -1)" if [[ "${github_email}" != "" ]] && [[ "${github_email}" != "null" ]] then echo "${github_email}" fi local reflog_email="$(git reflog --pretty=format:"%an <%ae>" | sort -u | \ grep -vF users.noreply.github.com | grep -F "$1" | sed -re 's,.*<(.*)>,\1,')" if [[ "${reflog_email}" != "" ]] then echo "${reflog_email}" fi } function add_if_new() { local file="$1" local commit_name="$2" local commit_email="$3" if grep -qiF "${commit_name}" "${file}" || grep -qiF "${commit_email}" "${file}" then return fi local github_login="$(find_login "${commit_email}")" if [ -z "${github_login}" ] then github_login="$(find_login "${commit_name}")" fi if [[ -z "${github_login}" ]] then if echo "${commit_email}" | grep -q users.noreply.github.com then github_login="$(echo "${commit_email}" | sed -re 's,^([0-9]+\+)?([^@]+).*$,\2,')" fi fi local print_name="$(find_name "${github_login}")" if [ -z "${print_name}" ] then print_name="${commit_name}" fi print_name="$(echo "${print_name}" | sed -re 's/\S+/\u&/g')" local print_addr="" if echo "${commit_email}" | grep -q users.noreply.github.com then if [[ ! -z "${github_login}" ]] then print_addr="$(find_email "${github_login}")" fi else print_addr="${commit_email}" fi if [[ -z "${print_addr}" && ! -z "${github_login}" ]] then print_addr="https://github.com/${github_login}" fi if [ -z "${print_addr}" ] then echo "Adding ${print_name}" 1>&2 echo "* ${print_name}" else echo "Adding ${print_name} (${print_addr})" 1>&2 echo "* ${print_name} (${print_addr})" fi } function add_contributors() { out_file="$1" repo_dir="$2" git log --encoding=utf-8 --full-history --reverse "--format=format:%at,%an,%ae" \ | sort -u -t, -k3,3 \ | sort -t, -k1n \ | while read line do name="$(echo "${line}" | cut -d, -f2)" email="$(echo "${line}" | cut -d, -f3)" add_if_new "${out_file}" "${name}" "${email}" >> "${out_file}" done } function update_authors() { file="AUTHORS.md" temp="$(mktemp)" cat "${file}" > "${temp}" add_contributors "${temp}" "$(pwd)" cat "$temp" > "${file}" rm "${temp}" } cd "$(dirname "$0")/.." update_authors "${sphinx}" echo "Updated AUTHORS.md" signal-estimator-0.0.9/script/update_readme.sh000077500000000000000000000017431452044147100214530ustar00rootroot00000000000000#!env bash set -euo pipefail run() { echo "Running: $*" 1>&2 "$@" || exit 1 } if ! which markdown-toc >/dev/null 2>&1; then echo "error: markdown-toc not found in PATH" >&2 echo "you can install it using 'npm install --save markdown-toc'" >&2 fi if ! which mdspell >/dev/null 2>&1; then echo "error: mdspell not found in PATH" >&2 echo "you can install it using 'npm install --save markdown-spellcheck'" >&2 fi cd "$(dirname "$0")"/.. run mdspell -n -a README.md run sort .spelling -o .spelling run markdown-toc -i README.md cat >/tmp/signal-estimator.help <<'EOF' ``` $ signal-estimator --help EOF run bin/$(uname -m)-linux-gnu/signal-estimator --help | sed -e 's/[[:space:]]*$//' >>/tmp/signal-estimator.help cat >>/tmp/signal-estimator.help <<'EOF' ``` EOF sed -e '//{r /tmp/signal-estimator.help' \ -e 'N' \ -e '}; //,//d' \ -i README.md echo "Updated README.md" signal-estimator-0.0.9/src/000077500000000000000000000000001452044147100155735ustar00rootroot00000000000000signal-estimator-0.0.9/src/base/000077500000000000000000000000001452044147100165055ustar00rootroot00000000000000signal-estimator-0.0.9/src/base/core/000077500000000000000000000000001452044147100174355ustar00rootroot00000000000000signal-estimator-0.0.9/src/base/core/Config.hpp000066400000000000000000000104321452044147100213530ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/DevInfo.hpp" #include "core/Dir.hpp" #include "core/Time.hpp" #include "io/PcmFormat.hpp" #include #include #include namespace signal_estimator { enum class Mode { LatencyCorr, LatencyStep, Losses, IOJitter, IODelay, }; enum class Format { Text, Json, }; struct Config { // operation mode Mode mode { Mode::LatencyCorr }; // report format Format report_format { Format::Text }; // whether to show device names in reports and dumps bool show_device_names { false }; // instead of output + input, pass two inputs to estimator bool diff_inputs { false }; // disable using SCHED_RR policy bool no_realtime { false }; // device names std::string output_dev; std::vector input_devs; // dump file std::string dump_file; // total measurement duration float measurement_duration { 0 }; // how long to ignore input after startup, in seconds float warmup_duration { 1 }; // number of samples per second per channel unsigned int sample_rate { 48000 }; // channel count for processing unsigned int channel_count { 2 }; // probe signal gain float gain { 0.8f }; // desired output latency, in microseconds unsigned int requested_output_latency_us { 8000 }; // desired number of periods in output ring buffer(s) unsigned int requested_output_period_count { 2 }; // desired format for output device PcmFormat requested_output_format {}; // desired input latency, in microseconds unsigned int requested_input_latency_us { 8000 }; // desired number of periods in input ring buffer(s) unsigned int requested_input_period_count { 2 }; // desired format for input device PcmFormat requested_input_format {}; // output device info DevInfo output_info; // input device(s) info std::vector input_info; // sma window for latency reports, in seconds size_t report_sma_window { 5 }; // dump compression ratio size_t dump_compression { 0 }; // interval between strikes in seconds float step_interval { 1 }; // strike length in seconds float step_length { 0.1f }; // running maximum window for strike detection size_t step_detection_window { 96 }; // strike detection threshold float step_detection_threshold { 0.4f }; // the impulse latency estimator peak detection window length in samples size_t impulse_peak_detection_width { 128 }; // the peak-to-noise minimum ratio threshold float impulse_avg_2_peak_ration_threshold { 4.0 }; // interval between impulses in seconds float impulse_interval { 1 }; // running maximum window for signal detection size_t signal_detection_window { 48 }; // signal detection threshold float signal_detection_threshold { 0.15f }; // glitch detection window size_t glitch_detection_window { 32 }; // glitch detection threshold float glitch_detection_threshold { 0.05f }; // running window for jitter calculation, number of periods size_t io_jitter_window { 250 }; // percentile for jitter reports, from 0 to 100 size_t io_jitter_percentile { 95 }; // running window for delay calculation, number of periods size_t io_delay_window { 250 }; // default number of samples for each frame size_t frame_size { 0 }; // number of pre-allocated frames in frame pool size_t frame_pool_size { 128 }; // get warmup duration in samples size_t warmup_samples() const { return size_t(sample_rate * warmup_duration) * channel_count; } // get test duration in samples size_t total_samples() const { return size_t(sample_rate * measurement_duration) * channel_count; } // convert number of samples (all channels) to number of nanoseconds nanoseconds_t samples_to_ns(size_t num_samples) const { return nanoseconds_t(num_samples) / channel_count * Second / sample_rate; } // convert number of samples (per channel) to number of nanoseconds nanoseconds_t frames_to_ns(size_t num_samples) const { return nanoseconds_t(num_samples) * Second / sample_rate; } }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/core/DevInfo.hpp000066400000000000000000000020521452044147100214770ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/Dir.hpp" #include "io/PcmFormat.hpp" #include namespace signal_estimator { struct DevInfo { // input or output device Dir dir { Dir::Output }; // short name of device for reports and dumps std::string short_name {}; // number of periods in hardware ring buffer // may differ from Config::requested_XXX_period_count, for each // device we use what it supports unsigned int period_count { 0 }; // number of samples (for all channels) in period // based on Config::requested_XXX_latency_us and // Config::requested_XXX_period_count unsigned int period_size { 0 }; // sample format // may differ from Config::requested_XXX_format, for each // device we use what it supports PcmFormat sample_format {}; // number of channels // may differ from Config::channel_count, for each // device we use what it supports unsigned int channel_count { 0 }; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/core/Dir.hpp000066400000000000000000000003121452044147100206600ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once namespace signal_estimator { // I/O direction enum class Dir { Output, Input, }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/core/Frame.cpp000066400000000000000000000047771452044147100212120ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "core/Frame.hpp" #include "core/FramePool.hpp" #include namespace signal_estimator { Frame::Frame(const Config& config, FramePool& pool) : config_(config) , pool_(pool) { data_.reserve(config_.frame_size); } int Frame::get_ref() const { return refcount_; } void Frame::add_ref() { const int oldcount = refcount_++; (void)oldcount; assert(oldcount >= 0); } void Frame::sub_ref() { const int oldcount = refcount_--; assert(oldcount > 0); if (oldcount == 1) { pool_.release_frame_(this); } } void Frame::reset(Dir dir, size_t dev_index) { dir_ = dir; dev_index_ = dev_index; size_ = dev_info().period_size; assert(size_ > 0); if (data_.size() < size_) { data_.resize(size_); } std::fill_n(data_.data(), size_, 0); set_times(0, 0, 0, 0, 0); } size_t Frame::dev_index() const { return dev_index_; } const DevInfo& Frame::dev_info() const { switch (dir_) { case Dir::Output: assert(dev_index_ == 0); return config_.output_info; case Dir::Input: break; } assert(dev_index_ < config_.input_info.size()); return config_.input_info[dev_index_]; } Dir Frame::dir() const { return dir_; } size_t Frame::size() const { return size_; } const sample_t* Frame::data() const { assert(size_ > 0); return &data_[0]; } sample_t* Frame::data() { assert(size_ > 0); return &data_[0]; } void Frame::set_times(nanoseconds_t sw_time, nanoseconds_t hw_time, nanoseconds_t wc_time, nanoseconds_t sw_delay, nanoseconds_t hw_delay) { sw_time_ = sw_time; hw_time_ = hw_time; wc_time_ = wc_time; sw_delay_ = sw_delay; hw_delay_ = hw_delay; } nanoseconds_t Frame::sw_frame_time() const { return sw_time_; } nanoseconds_t Frame::hw_frame_time() const { return hw_time_; } nanoseconds_t Frame::wc_frame_time() const { return wc_time_; } nanoseconds_t Frame::sw_sample_time(size_t sample_index) const { return sw_time_ + config_.samples_to_ns(sample_index); } nanoseconds_t Frame::hw_sample_time(size_t sample_index) const { return hw_time_ + config_.samples_to_ns(sample_index); } nanoseconds_t Frame::wc_sample_time(size_t sample_index) const { return wc_time_ + config_.samples_to_ns(sample_index); } nanoseconds_t Frame::sw_delay() const { return sw_delay_; } nanoseconds_t Frame::hw_delay() const { return hw_delay_; } } // namespace signal_estimator signal-estimator-0.0.9/src/base/core/Frame.hpp000066400000000000000000000065531452044147100212110ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/Config.hpp" #include "core/Dir.hpp" #include "core/Sample.hpp" #include "core/Time.hpp" #include #include #include #include #include namespace signal_estimator { class FramePool; class FrameTraits; // Audio frame class Frame { public: Frame(const Config&, FramePool&); Frame(const Frame&) = delete; Frame& operator=(const Frame&) = delete; // reset frame to initial state void reset(Dir dir, size_t dev_index); // source or destination device size_t dev_index() const; const DevInfo& dev_info() const; // frame direction (input or output) Dir dir() const; // frame size and data size_t size() const; const sample_t* data() const; sample_t* data(); // record hw and sw times void set_times(nanoseconds_t sw_time, nanoseconds_t hw_time, nanoseconds_t wc_time, nanoseconds_t sw_delay, nanoseconds_t hw_delay); // get time when the frame was passed to or received from the OS nanoseconds_t sw_frame_time() const; // get time when the frame was passed to or received from hardware // takes into account ALSA ring buffer size nanoseconds_t hw_frame_time() const; // same as hw time, but using wallclock (absolute system clock) instead // of monotonic clock nanoseconds_t wc_frame_time() const; // get time when the sample inside frame was passed to or received from the OS nanoseconds_t sw_sample_time(size_t sample_index) const; // get time when the sample inside frame was passed to or received from hardware // takes into account ALSA ring buffer size and position of sample in frame nanoseconds_t hw_sample_time(size_t sample_index) const; // same as hw_sample_time, but using wallclock (absolute system clock) instead // of monotonic clock nanoseconds_t wc_sample_time(size_t sample_index) const; // get ring buffer size as reported by ALSA // at the time when frame was captured or played nanoseconds_t sw_delay() const; // get hardware delay between ring buffer and ADC/DAC, as reported by ALSA // at the time when frame was captured or played nanoseconds_t hw_delay() const; // index access const sample_t& operator[](const size_t index) const { assert(index < data_.size()); return data_[index]; } sample_t& operator[](const size_t index) { assert(index < data_.size()); return data_[index]; } private: friend class FramePool; friend class FrameTraits; int get_ref() const; void add_ref(); void sub_ref(); const Config& config_; FramePool& pool_; Dir dir_ {}; size_t dev_index_ {}; std::vector data_; size_t size_ {}; nanoseconds_t sw_time_ {}; nanoseconds_t hw_time_ {}; nanoseconds_t wc_time_ {}; nanoseconds_t sw_delay_ {}; nanoseconds_t hw_delay_ {}; std::atomic refcount_ {}; }; // For FramePtr class FrameTraits { public: static void add_ref(Frame* frame) noexcept { frame->add_ref(); } static void sub_ref(Frame* frame) noexcept { frame->sub_ref(); } }; // Intrusive shared pointer to frame using FramePtr = isptr::intrusive_shared_ptr; } // namespace signal_estimator signal-estimator-0.0.9/src/base/core/FramePool.cpp000066400000000000000000000020301452044147100220200ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "core/FramePool.hpp" namespace signal_estimator { FramePool::FramePool(const Config& config) : config_(config) { for (size_t n = 0; n < config.frame_pool_size; n++) { free_list_.enqueue(create_frame_()); } } FramePool::~FramePool() { Frame* frame = nullptr; while (free_list_.try_dequeue(frame)) { delete_frame_(frame); } } FramePtr FramePool::allocate(Dir dir, size_t dev_index) { Frame* frame = nullptr; if (!free_list_.try_dequeue(frame)) { frame = create_frame_(); } frame->reset(dir, dev_index); assert(frame->get_ref() == 0); return FramePtr::ref(frame); } void FramePool::release_frame_(Frame* frame) { assert(frame->get_ref() == 0); free_list_.enqueue(frame); } Frame* FramePool::create_frame_() { return new Frame(config_, *this); } void FramePool::delete_frame_(Frame* frame) { assert(frame->get_ref() == 0); delete frame; } } // namespace signal_estimator signal-estimator-0.0.9/src/base/core/FramePool.hpp000066400000000000000000000014731452044147100220370ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/Config.hpp" #include "core/Frame.hpp" #include #include namespace signal_estimator { // thread-safe lock-free frame pool class FramePool { public: FramePool(const Config& config); ~FramePool(); FramePool(const FramePool&) = delete; FramePool& operator=(const FramePool&) = delete; // allocate and reset() frame // frame smart pointer will automatically return frame to pool FramePtr allocate(Dir dir, size_t dev_index); private: friend class Frame; void release_frame_(Frame*); Frame* create_frame_(); void delete_frame_(Frame* frame); moodycamel::ConcurrentQueue free_list_; const Config config_; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/core/FrameQueue.cpp000066400000000000000000000011061452044147100221760ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "core/FrameQueue.hpp" namespace signal_estimator { bool FrameQueue::empty() const { return size_ == 0; } void FrameQueue::push(FramePtr frame) { queue_.enqueue(std::move(frame)); size_++; } FramePtr FrameQueue::try_pop() { FramePtr frame; if (!queue_.try_dequeue(frame)) { return {}; } size_--; return frame; } FramePtr FrameQueue::wait_pop() { FramePtr frame; queue_.wait_dequeue(frame); size_--; return frame; } } // namespace signal_estimator signal-estimator-0.0.9/src/base/core/FrameQueue.hpp000066400000000000000000000014501452044147100222050ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/Frame.hpp" #include #include namespace signal_estimator { // thread-safe lock-free frame queue class FrameQueue { public: FrameQueue() = default; FrameQueue(const FrameQueue&) = delete; FrameQueue& operator=(const FrameQueue&) = delete; // check if queue is empty bool empty() const; // lock-free operation void push(FramePtr frame); // returns null if queue is empty or if null frame was pushed FramePtr try_pop(); // returns null only if null frame was pushed FramePtr wait_pop(); private: moodycamel::BlockingConcurrentQueue queue_; std::atomic size_ { 0 }; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/core/Log.cpp000066400000000000000000000021271452044147100206640ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "core/Log.hpp" #include void init_log(int verbosity) { auto sink = std::make_shared(); sink->set_color(spdlog::level::critical, sink->red); sink->set_color(spdlog::level::err, sink->red); sink->set_color(spdlog::level::warn, sink->yellow); sink->set_color(spdlog::level::info, sink->green); sink->set_color(spdlog::level::debug, sink->reset); sink->set_color(spdlog::level::trace, sink->white); auto logger = std::make_shared("default", sink); spdlog::set_default_logger(logger); spdlog::set_pattern("[%L%L] %^%v%$"); spdlog::level::level_enum log_level; switch (verbosity) { case 0: log_level = spdlog::level::warn; break; case 1: log_level = spdlog::level::info; break; case 2: log_level = spdlog::level::debug; break; default: log_level = spdlog::level::trace; break; } spdlog::set_level(log_level); } signal-estimator-0.0.9/src/base/core/Log.hpp000066400000000000000000000006121452044147100206660ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include #define se_log_error(fmt, ...) spdlog::error(fmt, ##__VA_ARGS__) #define se_log_warn(fmt, ...) spdlog::warn(fmt, ##__VA_ARGS__) #define se_log_info(fmt, ...) spdlog::info(fmt, ##__VA_ARGS__) #define se_log_debug(fmt, ...) spdlog::debug(fmt, ##__VA_ARGS__) void init_log(int verbosity); signal-estimator-0.0.9/src/base/core/RateLimiter.cpp000066400000000000000000000015011452044147100223570ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "core/RateLimiter.hpp" namespace signal_estimator { RateLimiter::RateLimiter(float period_sec) : allow_period_(nanoseconds_t(period_sec * 1000000000)) { } double RateLimiter::allow() { const nanoseconds_t cur_pos = elapsed_nsec_(); if (cur_pos <= next_allow_pos_) { return 0; } const double ret = (cur_pos - last_allow_pos_) / 1000000000.0; next_allow_pos_ = (cur_pos / allow_period_ + 1) * allow_period_; last_allow_pos_ = cur_pos; return ret; } nanoseconds_t RateLimiter::elapsed_nsec_() { if (!started_) { start_pos_ = monotonic_timestamp_ns(); started_ = true; return 0; } else { return monotonic_timestamp_ns() - start_pos_; } } } // namespace signal_estimator signal-estimator-0.0.9/src/base/core/RateLimiter.hpp000066400000000000000000000010571452044147100223720ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/Time.hpp" #include namespace signal_estimator { // limit events to given rate per second class RateLimiter { public: explicit RateLimiter(float period_sec); double allow(); private: nanoseconds_t elapsed_nsec_(); const nanoseconds_t allow_period_; nanoseconds_t last_allow_pos_ {}; nanoseconds_t next_allow_pos_ {}; nanoseconds_t start_pos_ {}; nanoseconds_t started_ { false }; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/core/Realtime.cpp000066400000000000000000000010511452044147100217000ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "core/Realtime.hpp" #include "core/Log.hpp" #include namespace signal_estimator { void make_realtime() { sched_param param {}; param.sched_priority = sched_get_priority_max(SCHED_RR); if (sched_setscheduler(0, SCHED_RR, ¶m) == 0) { se_log_debug("successfully enabled real-time scheduling policy"); } else { se_log_warn("can't enable real-time scheduling policy (try running with sudo)"); } } } // namespace signal_estimator signal-estimator-0.0.9/src/base/core/Realtime.hpp000066400000000000000000000003351452044147100217110ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once namespace signal_estimator { // enable real-time scheduling policy for current thread void make_realtime(); } // namespace signal_estimator signal-estimator-0.0.9/src/base/core/Sample.cpp000066400000000000000000000017721452044147100213710ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "core/Sample.hpp" namespace signal_estimator { sample_t saturated_add(sample_t a, sample_t b) { if (a > 0) { if (b > MaxSample - a) { return MaxSample; } } else { if (b < MinSample - a) { return MinSample; } } return a + b; } sample_t saturated_sub(sample_t a, sample_t b) { if (a > 0) { if (b < a - MaxSample) { return MaxSample; } } else { if (b > a - MinSample) { return MinSample; } } return a - b; } sample_t saturated_cast(float x) { if (x > MaxSample) { return MaxSample; } else if (x < MinSample) { return MinSample; } return (sample_t)x; } sample_t saturated_cast(double x) { if (x > MaxSample) { return MaxSample; } else if (x < MinSample) { return MinSample; } return (sample_t)x; } } // namespace signal_estimator signal-estimator-0.0.9/src/base/core/Sample.hpp000066400000000000000000000010241452044147100213640ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include namespace signal_estimator { using sample_t = int16_t; constexpr sample_t MaxSample = +32767; constexpr sample_t MinSample = -32768; // add or subtract sample_t, saturate on overflow sample_t saturated_add(sample_t a, sample_t b); sample_t saturated_sub(sample_t a, sample_t b); // cast float to sample_t, saturate on overflow sample_t saturated_cast(float x); sample_t saturated_cast(double x); } // namespace signal_estimator signal-estimator-0.0.9/src/base/core/Time.cpp000066400000000000000000000011551452044147100210410ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "core/Time.hpp" #include namespace signal_estimator { nanoseconds_t monotonic_timestamp_ns() { return nanoseconds_t(std::chrono::duration_cast( std::chrono::steady_clock::now().time_since_epoch()) .count()); } nanoseconds_t wallclock_timestamp_ns() { return nanoseconds_t(std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()) .count()); } } // namespace signal_estimatorc signal-estimator-0.0.9/src/base/core/Time.hpp000066400000000000000000000017251452044147100210510ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once namespace signal_estimator { //! Nanoseconds type. using nanoseconds_t = long long; //! One nanosecond represented in nanoseconds. inline constexpr nanoseconds_t Nanosecond = 1; //! One microsecond represented in nanoseconds. inline constexpr nanoseconds_t Microsecond = 1000 * Nanosecond; //! One millisecond represented in nanoseconds. inline constexpr nanoseconds_t Millisecond = 1000 * Microsecond; //! One second represented in nanoseconds. inline constexpr nanoseconds_t Second = 1000 * Millisecond; //! One minute represented in nanoseconds. inline constexpr nanoseconds_t Minute = 60 * Second; //! One hour represented in nanoseconds. inline constexpr nanoseconds_t Hour = 60 * Minute; // current timestamp from monotonic source nanoseconds_t monotonic_timestamp_ns(); // current timestamp from wallclock source nanoseconds_t wallclock_timestamp_ns(); } // namespace signal_estimator signal-estimator-0.0.9/src/base/dumps/000077500000000000000000000000001452044147100176355ustar00rootroot00000000000000signal-estimator-0.0.9/src/base/dumps/AsyncDumper.cpp000066400000000000000000000011411452044147100225700ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "dumps/AsyncDumper.hpp" namespace signal_estimator { AsyncDumper::AsyncDumper(std::shared_ptr dumper) : dumper_(std::move(dumper)) , thread_(&AsyncDumper::run_, this) { } AsyncDumper::~AsyncDumper() { queue_.push(nullptr); if (thread_.joinable()) { thread_.join(); } } void AsyncDumper::write(FramePtr frame) { queue_.push(std::move(frame)); } void AsyncDumper::run_() { while (auto frame = queue_.wait_pop()) { dumper_->write(frame); } } } // namespace signal_estimator signal-estimator-0.0.9/src/base/dumps/AsyncDumper.hpp000066400000000000000000000012461452044147100226030ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/FrameQueue.hpp" #include "dumps/IDumper.hpp" #include #include namespace signal_estimator { // wraps another dumper and invokes it in background thread class AsyncDumper : public IDumper { public: AsyncDumper(std::shared_ptr dumper); ~AsyncDumper(); AsyncDumper(const AsyncDumper&) = delete; AsyncDumper& operator=(const AsyncDumper&) = delete; void write(FramePtr frame) override; private: void run_(); std::shared_ptr dumper_; FrameQueue queue_; std::thread thread_; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/dumps/CsvDumper.cpp000066400000000000000000000105171452044147100222550ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "dumps/CsvDumper.hpp" #include "core/Frame.hpp" #include "core/Log.hpp" #include "core/Time.hpp" #include #include #include #include #include namespace signal_estimator { namespace { std::string quote(const std::string& str) { std::string quoted_str = str; if (quoted_str.find(',') != std::string::npos || quoted_str.find('"') != std::string::npos || quoted_str.find('\n') != std::string::npos || quoted_str.find('\r') != std::string::npos) { quoted_str = std::regex_replace(quoted_str, std::regex("\""), "\"\""); quoted_str = "\"" + quoted_str + "\""; } return quoted_str; } } // namespace CsvDumper::CsvDumper(const Config& config) : config_(config) { // upper bound buf_.resize(256 + 24 * config_.channel_count); } CsvDumper::~CsvDumper() { close(); } bool CsvDumper::open(const std::string& filename) { if (filename == "-") { fp_ = stdout; } else { fp_ = fopen(filename.c_str(), "w"); } if (!fp_) { se_log_error("can't open output file {}: {}", filename, strerror(errno)); return false; } return true; } void CsvDumper::close() { if (fp_) { if (fp_ != stdout) { fclose(fp_); } fp_ = nullptr; } } void CsvDumper::write(FramePtr frame) { if (!frame) { return; } if (!fp_) { return; } DevState& dev = devices_[frame->dir()][frame->dev_index()]; if (dev.win_size == 0) { device_init_(dev, frame->dev_info()); } device_add_frame_(dev, *frame); } void CsvDumper::device_init_(DevState& dev, const DevInfo& info) { dev.dir = info.dir; if (config_.show_device_names) { dev.name = quote(info.short_name); } // if dump_compression is 0 or 1, SMA window is 1, but has no effect dev.win_size = std::max(config_.dump_compression, (size_t)1); for (size_t ch = 0; ch < config_.channel_count; ch++) { dev.win_avg.emplace_back(dev.win_size); } } void CsvDumper::device_add_frame_(DevState& dev, const Frame& frame) { for (size_t ns = 0; ns < frame.size(); ns += config_.channel_count) { // add samples to SMA window for (size_t ch = 0; ch < config_.channel_count; ch++) { dev.win_avg[ch].add(frame[ns + ch]); } if (dev.win_pos == 0) { // remember time of the middle of the sliding window dev.win_time = frame.wc_sample_time(ns) + config_.frames_to_ns(dev.win_size / 2); } dev.win_pos++; // once per window, print line if (dev.win_pos == dev.win_size) { if (!header_printed_) { header_printed_ = true; print_header_(); } print_line_(dev); dev.win_pos = 0; } } } void CsvDumper::print_header_() { size_t off = 0; off += (size_t)snprintf(buf_.data() + off, buf_.size() - off, "# dir"); if (config_.show_device_names) { off += (size_t)snprintf(buf_.data() + off, buf_.size() - off, ",dev"); } off += (size_t)snprintf(buf_.data() + off, buf_.size() - off, ",timestamp"); for (size_t ch = 0; ch < config_.channel_count; ch++) { off += (size_t)snprintf( buf_.data() + off, buf_.size() - off, ",ch%d", (int)ch + 1); } off += (size_t)snprintf(buf_.data() + off, buf_.size() - off, "\n"); fprintf(fp_, "%s", buf_.data()); fflush(fp_); } void CsvDumper::print_line_(const DevState& dev) { size_t off = 0; off += (size_t)snprintf( buf_.data() + off, buf_.size() - off, "%s", dev.dir == Dir::Output ? "o" : "i"); if (config_.show_device_names) { off += (size_t)snprintf( buf_.data() + off, buf_.size() - off, ",%s", dev.name.c_str()); } off += (size_t)snprintf( buf_.data() + off, buf_.size() - off, ",%lld", (long long)dev.win_time); for (size_t ch = 0; ch < config_.channel_count; ch++) { off += (size_t)snprintf(buf_.data() + off, buf_.size() - off, ",%lld", (long long)dev.win_avg[ch].get()); } off += (size_t)snprintf(buf_.data() + off, buf_.size() - off, "\n"); fprintf(fp_, "%s", buf_.data()); fflush(fp_); } } // namespace signal_estimator signal-estimator-0.0.9/src/base/dumps/CsvDumper.hpp000066400000000000000000000027221452044147100222610ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/Config.hpp" #include "core/Frame.hpp" #include "dumps/IDumper.hpp" #include "processing/MovAvg.hpp" #include #include #include #include #include namespace signal_estimator { // dumps samples with their timestamps to a csv file // to reduce file size, can "compress" output by replacing each N // samples with an average value among those samples, where N is // defined by config.dump_compression class CsvDumper : public IDumper { public: CsvDumper(const Config& config); ~CsvDumper(); CsvDumper(const CsvDumper&) = delete; CsvDumper& operator=(const CsvDumper&) = delete; bool open(const std::string& filename); void close(); void write(FramePtr frame) override; private: struct DevState { Dir dir { Dir::Output }; std::string name; std::vector> win_avg; size_t win_size { 0 }; size_t win_pos { 0 }; nanoseconds_t win_time { 0 }; }; void device_init_(DevState& dev, const DevInfo& info); void device_add_frame_(DevState& dev, const Frame& frame); void print_header_(); void print_line_(const DevState& dev); const Config config_; std::map> devices_; bool header_printed_ { false }; FILE* fp_ {}; std::vector buf_; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/dumps/IDumper.hpp000066400000000000000000000004231452044147100217120ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/Frame.hpp" namespace signal_estimator { class IDumper { public: virtual ~IDumper() = default; virtual void write(FramePtr frame) = 0; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/io/000077500000000000000000000000001452044147100171145ustar00rootroot00000000000000signal-estimator-0.0.9/src/base/io/AlsaConstants.cpp000066400000000000000000000031701452044147100223760ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include #include #define print(name) printf("#define %s %d\n", #name, name) int main() { printf("// Copyright (c) Signal Estimator authors\n" "// Licensed under MIT\n" "\n" "// Generated by AlsaConstants.cpp. DO NOT EDIT!\n" "\n" "#pragma once\n" "\n"); print(SND_PCM_FORMAT_UNKNOWN); print(SND_PCM_FORMAT_S8); print(SND_PCM_FORMAT_U8); print(SND_PCM_FORMAT_S16_BE); print(SND_PCM_FORMAT_S16_LE); print(SND_PCM_FORMAT_U16_BE); print(SND_PCM_FORMAT_U16_LE); print(SND_PCM_FORMAT_S18_3BE); print(SND_PCM_FORMAT_S18_3LE); print(SND_PCM_FORMAT_U18_3BE); print(SND_PCM_FORMAT_U18_3LE); print(SND_PCM_FORMAT_S20_3BE); print(SND_PCM_FORMAT_S20_3LE); print(SND_PCM_FORMAT_U20_3BE); print(SND_PCM_FORMAT_U20_3LE); print(SND_PCM_FORMAT_S20_BE); print(SND_PCM_FORMAT_S20_LE); print(SND_PCM_FORMAT_U20_BE); print(SND_PCM_FORMAT_U20_LE); print(SND_PCM_FORMAT_S24_3BE); print(SND_PCM_FORMAT_S24_3LE); print(SND_PCM_FORMAT_U24_3BE); print(SND_PCM_FORMAT_U24_3LE); print(SND_PCM_FORMAT_S24_BE); print(SND_PCM_FORMAT_S24_LE); print(SND_PCM_FORMAT_U24_BE); print(SND_PCM_FORMAT_U24_LE); print(SND_PCM_FORMAT_S32_BE); print(SND_PCM_FORMAT_S32_LE); print(SND_PCM_FORMAT_U32_BE); print(SND_PCM_FORMAT_U32_LE); print(SND_PCM_FORMAT_FLOAT_BE); print(SND_PCM_FORMAT_FLOAT_LE); print(SND_PCM_FORMAT_FLOAT64_BE); print(SND_PCM_FORMAT_FLOAT64_LE); return 0; } signal-estimator-0.0.9/src/base/io/AlsaConstants.hpp000066400000000000000000000024121452044147100224010ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT // Generated by AlsaConstants.cpp. DO NOT EDIT! #pragma once #define SND_PCM_FORMAT_UNKNOWN -1 #define SND_PCM_FORMAT_S8 0 #define SND_PCM_FORMAT_U8 1 #define SND_PCM_FORMAT_S16_BE 3 #define SND_PCM_FORMAT_S16_LE 2 #define SND_PCM_FORMAT_U16_BE 5 #define SND_PCM_FORMAT_U16_LE 4 #define SND_PCM_FORMAT_S18_3BE 41 #define SND_PCM_FORMAT_S18_3LE 40 #define SND_PCM_FORMAT_U18_3BE 43 #define SND_PCM_FORMAT_U18_3LE 42 #define SND_PCM_FORMAT_S20_3BE 37 #define SND_PCM_FORMAT_S20_3LE 36 #define SND_PCM_FORMAT_U20_3BE 39 #define SND_PCM_FORMAT_U20_3LE 38 #define SND_PCM_FORMAT_S20_BE 26 #define SND_PCM_FORMAT_S20_LE 25 #define SND_PCM_FORMAT_U20_BE 28 #define SND_PCM_FORMAT_U20_LE 27 #define SND_PCM_FORMAT_S24_3BE 33 #define SND_PCM_FORMAT_S24_3LE 32 #define SND_PCM_FORMAT_U24_3BE 35 #define SND_PCM_FORMAT_U24_3LE 34 #define SND_PCM_FORMAT_S24_BE 7 #define SND_PCM_FORMAT_S24_LE 6 #define SND_PCM_FORMAT_U24_BE 9 #define SND_PCM_FORMAT_U24_LE 8 #define SND_PCM_FORMAT_S32_BE 11 #define SND_PCM_FORMAT_S32_LE 10 #define SND_PCM_FORMAT_U32_BE 13 #define SND_PCM_FORMAT_U32_LE 12 #define SND_PCM_FORMAT_FLOAT_BE 15 #define SND_PCM_FORMAT_FLOAT_LE 14 #define SND_PCM_FORMAT_FLOAT64_BE 17 #define SND_PCM_FORMAT_FLOAT64_LE 16 signal-estimator-0.0.9/src/base/io/AlsaDeviceManager.cpp000066400000000000000000000044761452044147100231260ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "io/AlsaDeviceManager.hpp" #include #include #include namespace signal_estimator { namespace { void chomp(char* buffer) { size_t len = strlen(buffer); if (len == 0) { return; } while (buffer[len - 1] == '\n') { buffer[len - 1] = '\0'; len--; } } } // namespace std::vector AlsaDeviceManager::get_output_devices() { char buffer[128]; std::vector strvec; // run pipe to get output devices from aplay std::unique_ptr pipe1(popen("aplay -l", "r"), pclose); if (!pipe1) { return strvec; } // read everything from aplay into result while (fgets(buffer, sizeof(buffer), pipe1.get()) != nullptr) { // if line has both card and device in it if (std::strstr(buffer, "card") != nullptr && std::strstr(buffer, "device") != nullptr) { chomp(buffer); strvec.emplace_back(buffer); } } return strvec; } std::vector AlsaDeviceManager::get_input_devices() { char buffer[128]; std::vector strvec; // run pipe to get output devices from arecord std::unique_ptr pipe2(popen("arecord -l", "r"), pclose); if (!pipe2) { return strvec; } while (fgets(buffer, sizeof(buffer), pipe2.get()) != nullptr) { // if line has both card and device in it if (std::strstr(buffer, "card") != nullptr && std::strstr(buffer, "device") != nullptr) { chomp(buffer); strvec.emplace_back(buffer); } } return strvec; } std::string AlsaDeviceManager::format_device_name(std::string_view buffer) { if (buffer == "default" || buffer.empty()) { return std::string { buffer }; } std::string result { "hw:" }; const char* card_prefix = "card "; if (const char* str = std::strstr(buffer.data(), card_prefix)) { result += *(str + strlen(card_prefix)); } const char* device_prefix = " device "; if (const char* str = std::strstr(buffer.data(), device_prefix)) { result += ','; result += *(str + strlen(device_prefix)); } return result; } } // namespace signal_estimator signal-estimator-0.0.9/src/base/io/AlsaDeviceManager.hpp000066400000000000000000000007171452044147100231250ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "io/IDeviceManager.hpp" #include #include namespace signal_estimator { class AlsaDeviceManager : public IDeviceManager { public: std::vector get_output_devices() override; std::vector get_input_devices() override; std::string format_device_name(std::string_view buffer) override; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/io/AlsaReader.cpp000066400000000000000000000053201452044147100216230ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "io/AlsaReader.hpp" #include "core/Log.hpp" #include "io/AlsaUtils.hpp" namespace signal_estimator { AlsaReader::~AlsaReader() { close(); } bool AlsaReader::open(const Config& config, const std::string& device) { se_log_info("opening alsa reader for device {}", device); config_ = config; pcm_ = alsa_open(device.c_str(), SND_PCM_STREAM_CAPTURE, config_, dev_info_); frame_chans_ = config.channel_count; dev_chans_ = dev_info_.channel_count; mapper_ = std::make_unique( /* input: */ dev_info_.sample_format, dev_info_.channel_count, /* output: */ PcmFormat(), config.channel_count); map_buf_.resize( mapper_->input_bytes(dev_info_.period_size / frame_chans_ * dev_chans_)); return pcm_; } void AlsaReader::close() { if (pcm_) { alsa_close(pcm_); pcm_ = nullptr; } } DevInfo AlsaReader::info() const { return dev_info_; } bool AlsaReader::read(Frame& frame) { int err = read_(frame); if (err < 0) { if ((err = snd_pcm_recover(pcm_, err, 1)) == 0) { se_log_info("alsa reader: recovered after xrun"); } } if (err < 0) { se_log_error("alsa reader: {}", snd_strerror((int)err)); return false; } return true; } int AlsaReader::read_(Frame& frame) { const size_t samples_per_chan = frame.size() / frame_chans_; // prepare buffer if (const size_t n_bytes = mapper_->input_bytes(samples_per_chan); map_buf_.size() < n_bytes) { map_buf_.resize(n_bytes); } // read from device to buffer if (snd_pcm_sframes_t err = snd_pcm_readi(pcm_, map_buf_.data(), samples_per_chan); err < 0) { return (int)err; } // avail: number of samples in ring buffer // delay: delay from ADC to ring buffer snd_pcm_sframes_t avail = 0, delay = 0; if (int err = snd_pcm_avail_delay(pcm_, &avail, &delay); err < 0) { return err; } const nanoseconds_t sw_time = monotonic_timestamp_ns(); const nanoseconds_t hw_time = sw_time - config_.frames_to_ns((size_t)avail) - config_.frames_to_ns(samples_per_chan); const nanoseconds_t wc_time = wallclock_timestamp_ns() - config_.frames_to_ns((size_t)avail) - config_.frames_to_ns(samples_per_chan); const nanoseconds_t sw_delay = config_.frames_to_ns((size_t)avail); const nanoseconds_t hw_delay = config_.frames_to_ns((size_t)delay) - sw_delay; frame.set_times(sw_time, hw_time, wc_time, sw_delay, hw_delay); // read from buffer to frame mapper_->map(map_buf_.data(), (uint8_t*)frame.data(), samples_per_chan); return 0; } } // namespace signal_estimator signal-estimator-0.0.9/src/base/io/AlsaReader.hpp000066400000000000000000000017531452044147100216360ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/Config.hpp" #include "core/DevInfo.hpp" #include "core/Frame.hpp" #include "io/IDeviceReader.hpp" #include "io/PcmMapper.hpp" #include #include #include #include #include #include namespace signal_estimator { class AlsaReader : public IDeviceReader { public: AlsaReader() = default; ~AlsaReader() override; AlsaReader(const AlsaReader&) = delete; AlsaReader& operator=(const AlsaReader&) = delete; bool open(const Config& config, const std::string& device); void close(); DevInfo info() const; bool read(Frame& frame) override; private: int read_(Frame& frame); Config config_; DevInfo dev_info_; snd_pcm_t* pcm_ {}; std::unique_ptr mapper_; std::vector map_buf_; size_t dev_chans_ {}; size_t frame_chans_ {}; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/io/AlsaUtils.cpp000066400000000000000000000237571452044147100215370ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "io/AlsaUtils.hpp" #include "core/Log.hpp" #include #include namespace signal_estimator { namespace { std::vector alsa_preferred_formats(PcmFormat requested_format) { std::vector all_formats = PcmFormat::supported_formats(); // sort by bits() and then by bytes() in ascending order std::sort(all_formats.begin(), all_formats.end(), [](const PcmFormat& a, const PcmFormat& b) { return a.bits() < b.bits() || (a.bits() == b.bits() && a.bytes() < b.bytes()); }); std::vector ret_fotmats; // first try requested format ret_fotmats.push_back(requested_format); // then try all formats larged than 16 bits in ascending order for (const PcmFormat& fmt : all_formats) { if (std::find(ret_fotmats.begin(), ret_fotmats.end(), fmt) != ret_fotmats.end()) { continue; } if (fmt.bits() >= 16) { ret_fotmats.push_back(fmt); } } // then try the rest for (const PcmFormat& fmt : all_formats) { if (std::find(ret_fotmats.begin(), ret_fotmats.end(), fmt) != ret_fotmats.end()) { continue; } ret_fotmats.push_back(fmt); } return ret_fotmats; } unsigned int alsa_nearest_buffer_size( unsigned int sample_rate, unsigned int latency_us, size_t periods) { unsigned int latency_samples = (unsigned int)((double)latency_us * sample_rate / 1000000); while ((latency_samples % periods) != 0) { latency_samples++; } return latency_samples; } bool alsa_set_hw_params(snd_pcm_t* pcm, snd_pcm_access_t access, PcmFormat* sample_format, unsigned int sample_rate, unsigned int* channel_count, unsigned int requested_latency_us, unsigned int requested_period_count, snd_pcm_uframes_t* selected_buffer_size, snd_pcm_uframes_t* selected_period_size) { int err = 0; snd_pcm_hw_params_t* hw_params = nullptr; snd_pcm_hw_params_alloca(&hw_params); // initialize hw_params if ((err = snd_pcm_hw_params_any(pcm, hw_params)) < 0) { se_log_error( "can't set hw params: snd_pcm_hw_params_any(): {}", snd_strerror(err)); return false; } // set access if ((err = snd_pcm_hw_params_set_access(pcm, hw_params, access)) < 0) { se_log_error( "can't set hw params: snd_pcm_hw_params_set_access(): {}", snd_strerror(err)); return false; } // set format for (const auto fmt : alsa_preferred_formats(*sample_format)) { if ((err = snd_pcm_hw_params_set_format( pcm, hw_params, (snd_pcm_format_t)fmt.to_alsa())) == 0) { *sample_format = fmt; break; } } if (err < 0) { se_log_error( "can't set hw params: snd_pcm_hw_params_set_format(): {}", snd_strerror(err)); return false; } // disable software resampling if ((err = snd_pcm_hw_params_set_rate_resample(pcm, hw_params, 0)) < 0) { se_log_error("can't set hw params: snd_pcm_hw_params_set_rate_resample(): {}", snd_strerror(err)); return false; } // set sample rate if ((err = snd_pcm_hw_params_set_rate(pcm, hw_params, sample_rate, 0)) < 0) { se_log_error("can't set hw params: snd_pcm_hw_params_set_rate_near(): {}", snd_strerror(err)); return false; } // set channel count if ((err = snd_pcm_hw_params_set_channels_near(pcm, hw_params, channel_count)) < 0) { se_log_error("can't set hw params: snd_pcm_hw_params_set_channels(): {}", snd_strerror(err)); return false; } // calculate nearest buffer size that is multiple of # of periods unsigned int requested_buffer_size = alsa_nearest_buffer_size( sample_rate, requested_latency_us, requested_period_count); // set period size in samples // ALSA reads 'period_size' samples from circular buffer every period *selected_period_size = requested_buffer_size / requested_period_count; if ((err = snd_pcm_hw_params_set_period_size_near( pcm, hw_params, selected_period_size, nullptr)) < 0) { se_log_error("can't set hw params: snd_pcm_hw_params_set_period_size_near(): {}", snd_strerror(err)); return false; } // get period time unsigned int selected_period_time = 0; if ((err = snd_pcm_hw_params_get_period_time( hw_params, &selected_period_time, nullptr)) < 0) { se_log_error("can't set hw params: snd_pcm_hw_params_get_period_time(): {}", snd_strerror(err)); return false; } // set buffer size, i.e. number of samples in circular buffer *selected_buffer_size = *selected_period_size * requested_period_count; if ((err = snd_pcm_hw_params_set_buffer_size_near( pcm, hw_params, selected_buffer_size)) < 0) { se_log_error("can't set hw params: snd_pcm_hw_params_set_buffer_size_near(): {}", snd_strerror(err)); return false; } // get buffer time, i.e. total duration of circular buffer in microseconds, // calculated from 'sample_rate' and 'buffer_size' unsigned int selected_buffer_time = 0; if ((err = snd_pcm_hw_params_get_buffer_time( hw_params, &selected_buffer_time, nullptr)) < 0) { se_log_error("can't set hw params: snd_pcm_hw_params_get_buffer_time(): {}", snd_strerror(err)); return false; } se_log_debug( "buffer_size: {} us ({} samples)", selected_buffer_time, *selected_buffer_size); se_log_debug( "period_size: {} us ({} samples)", selected_period_time, *selected_period_size); se_log_debug("sample_rate: {} Hz", sample_rate); se_log_debug("sample_format: {}", sample_format->to_string()); se_log_debug("channel_count: {}", *channel_count); // send hw_params to ALSA if ((err = snd_pcm_hw_params(pcm, hw_params)) < 0) { se_log_error("can't set hw params: snd_pcm_hw_params(): {}", snd_strerror(err)); return false; } return true; } bool alsa_set_sw_params(snd_pcm_t* pcm, snd_pcm_stream_t mode, snd_pcm_uframes_t period_size, snd_pcm_uframes_t buffer_size) { int err = 0; snd_pcm_sw_params_t* sw_params = nullptr; snd_pcm_sw_params_alloca(&sw_params); // initialize sw_params if ((err = snd_pcm_sw_params_current(pcm, sw_params)) < 0) { se_log_error( "can't set sw params: snd_pcm_sw_params_current(): {}", snd_strerror(err)); return false; } if (mode == SND_PCM_STREAM_PLAYBACK) { // set start threshold, after which ALSA starts playback if ((err = snd_pcm_sw_params_set_start_threshold(pcm, sw_params, buffer_size)) < 0) { se_log_error( "can't set sw params: snd_pcm_sw_params_set_start_threshold(): {}", snd_strerror(err)); return false; } // set minimum threshold, below which ALSA won't allow to perform write if ((err = snd_pcm_sw_params_set_avail_min(pcm, sw_params, period_size)) < 0) { se_log_error("can't set sw params: snd_pcm_sw_params_set_avail_min(): {}", snd_strerror(err)); return false; } } else { // set minimum threshold, below which ALSA won't allow to perform read if ((err = snd_pcm_sw_params_set_avail_min(pcm, sw_params, period_size)) < 0) { se_log_error("can't set sw params: snd_pcm_sw_params_set_avail_min(): {}", snd_strerror(err)); return false; } } // send sw_params to ALSA if ((err = snd_pcm_sw_params(pcm, sw_params)) < 0) { se_log_error("can't set sw params: snd_pcm_sw_params(): {}", snd_strerror(err)); return false; } return true; } } // namespace snd_pcm_t* alsa_open(const std::string& device, snd_pcm_stream_t stream, const Config& config, DevInfo& dev_info) { snd_pcm_t* pcm = nullptr; int err = 0; if ((err = snd_pcm_open(&pcm, device.c_str(), stream, 0)) < 0) { se_log_error("can't open alsa device: snd_pcm_open(): {}", snd_strerror(err)); return nullptr; } PcmFormat sample_format = stream == SND_PCM_STREAM_PLAYBACK ? config.requested_output_format : config.requested_input_format; unsigned int sample_rate = config.sample_rate; unsigned int channel_count = config.channel_count; const unsigned int requested_latency_us = stream == SND_PCM_STREAM_PLAYBACK ? config.requested_output_latency_us : config.requested_input_latency_us; const unsigned int requested_period_count = stream == SND_PCM_STREAM_PLAYBACK ? config.requested_output_period_count : config.requested_input_period_count; snd_pcm_uframes_t selected_buffer_size = 0, selected_period_size = 0; if (!alsa_set_hw_params(pcm, SND_PCM_ACCESS_RW_INTERLEAVED, &sample_format, sample_rate, &channel_count, requested_latency_us, requested_period_count, &selected_buffer_size, &selected_period_size)) { goto error; } if (!alsa_set_sw_params(pcm, stream, selected_period_size, selected_buffer_size)) { goto error; } dev_info.dir = stream == SND_PCM_STREAM_PLAYBACK ? Dir::Output : Dir::Input; dev_info.short_name = device; dev_info.period_count = selected_buffer_size / selected_period_size; dev_info.period_size = selected_period_size * config.channel_count; dev_info.sample_format = sample_format; dev_info.channel_count = channel_count; return pcm; error: if ((err = snd_pcm_close(pcm)) < 0) { se_log_error("can't close alsa device: snd_pcm_close(): {}", snd_strerror(err)); } return nullptr; } void alsa_close(snd_pcm_t* pcm) { if (!pcm) { return; } int err = 0; if ((err = snd_pcm_close(pcm)) < 0) { se_log_warn("can't close alsa device: snd_pcm_close(): {}", snd_strerror(err)); } } } // namespace signal_estimator signal-estimator-0.0.9/src/base/io/AlsaUtils.hpp000066400000000000000000000007121452044147100215260ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/Config.hpp" #include "core/DevInfo.hpp" #include #include namespace signal_estimator { // open and setup ALSA PCM device snd_pcm_t* alsa_open(const std::string& device, snd_pcm_stream_t stream, const Config& config, DevInfo& dev_info); // close ALSA PCM device void alsa_close(snd_pcm_t* pcm); } // namespace signal_estimator signal-estimator-0.0.9/src/base/io/AlsaWriter.cpp000066400000000000000000000055561452044147100217100ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "io/AlsaWriter.hpp" #include "core/Log.hpp" #include "io/AlsaUtils.hpp" namespace signal_estimator { AlsaWriter::~AlsaWriter() { close(); } bool AlsaWriter::open(const Config& config, const std::string& device) { se_log_info("opening alsa writer for device {}", device); config_ = config; pcm_ = alsa_open(device.c_str(), SND_PCM_STREAM_PLAYBACK, config_, dev_info_); frame_chans_ = config_.channel_count; dev_chans_ = dev_info_.channel_count; mapper_ = std::make_unique( /* input: */ PcmFormat(), config.channel_count, /* output: */ dev_info_.sample_format, dev_info_.channel_count); map_buf_.resize( mapper_->output_bytes(dev_info_.period_size / frame_chans_ * dev_chans_)); return pcm_; } void AlsaWriter::close() { if (pcm_) { alsa_close(pcm_); pcm_ = nullptr; } } DevInfo AlsaWriter::info() const { return dev_info_; } bool AlsaWriter::write(Frame& frame) { int err = write_(frame); if (err < 0) { if ((err = snd_pcm_recover(pcm_, err, 1)) == 0) { se_log_info("alsa writer: recovered after xrun"); } } if (err < 0) { se_log_error("alsa writer: {}", snd_strerror((int)err)); return false; } return true; } int AlsaWriter::write_(Frame& frame) { const size_t samples_per_chan = frame.size() / frame_chans_; // prepare buffer if (const size_t n_bytes = mapper_->output_bytes(samples_per_chan); map_buf_.size() < n_bytes) { map_buf_.resize(n_bytes); } // write from frame to buffer mapper_->map((const uint8_t*)frame.data(), map_buf_.data(), samples_per_chan); // write from buffer to device if (snd_pcm_sframes_t err = snd_pcm_writei(pcm_, map_buf_.data(), samples_per_chan); err < 0) { return (int)err; } // avail: free space in ring buffer // delay: delay from ring buffer to DAC snd_pcm_sframes_t avail = 0, delay = 0; if (int err = snd_pcm_avail_delay(pcm_, &avail, &delay); err < 0) { return err; } // queued: number of samples in ring buffer const size_t queued = dev_info_.period_count * dev_info_.period_size / frame_chans_ - (size_t)avail; const nanoseconds_t sw_time = monotonic_timestamp_ns(); const nanoseconds_t hw_time = sw_time + config_.frames_to_ns(queued) - config_.frames_to_ns(samples_per_chan); const nanoseconds_t wc_time = wallclock_timestamp_ns() + config_.frames_to_ns(queued) - config_.frames_to_ns(samples_per_chan); const nanoseconds_t sw_delay = config_.frames_to_ns((size_t)queued); const nanoseconds_t hw_delay = config_.frames_to_ns((size_t)delay) - sw_delay; frame.set_times(sw_time, hw_time, wc_time, sw_delay, hw_delay); return 0; } } // namespace signal_estimator signal-estimator-0.0.9/src/base/io/AlsaWriter.hpp000066400000000000000000000017551452044147100217120ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/Config.hpp" #include "core/DevInfo.hpp" #include "core/Frame.hpp" #include "io/IDeviceWriter.hpp" #include "io/PcmMapper.hpp" #include #include #include #include #include #include namespace signal_estimator { class AlsaWriter : public IDeviceWriter { public: AlsaWriter() = default; ~AlsaWriter() override; AlsaWriter(const AlsaWriter&) = delete; AlsaWriter& operator=(const AlsaWriter&) = delete; bool open(const Config& config, const std::string& device); void close(); DevInfo info() const; bool write(Frame& frame) override; private: int write_(Frame& frame); Config config_; DevInfo dev_info_; snd_pcm_t* pcm_ {}; std::unique_ptr mapper_; std::vector map_buf_; size_t dev_chans_ {}; size_t frame_chans_ {}; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/io/IDeviceManager.hpp000066400000000000000000000007341452044147100224340ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include #include #include namespace signal_estimator { class IDeviceManager { public: virtual ~IDeviceManager() = default; virtual std::vector get_output_devices() = 0; virtual std::vector get_input_devices() = 0; virtual std::string format_device_name(std::string_view buffer) = 0; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/io/IDeviceReader.hpp000066400000000000000000000004341452044147100222610ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/Frame.hpp" namespace signal_estimator { class IDeviceReader { public: virtual ~IDeviceReader() = default; virtual bool read(Frame& frame) = 0; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/io/IDeviceWriter.hpp000066400000000000000000000004351452044147100223340ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/Frame.hpp" namespace signal_estimator { class IDeviceWriter { public: virtual ~IDeviceWriter() = default; virtual bool write(Frame& frame) = 0; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/io/PcmFormat.cpp000066400000000000000000000021441452044147100215110ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "io/PcmFormat.hpp" #include "io/PcmFuncs.hpp" namespace signal_estimator { size_t PcmFormat::bits() const { return pcm_sample_bits(encoding); } size_t PcmFormat::bytes() const { return pcm_sample_bytes(encoding); } bool PcmFormat::is_int() const { return encoding != PcmEncoding::Float32 && encoding != PcmEncoding::Float64; } bool PcmFormat::operator==(const PcmFormat& other) const { return encoding == other.encoding && endian == other.endian; } bool PcmFormat::operator!=(const PcmFormat& other) const { return !(*this == other); } std::vector PcmFormat::supported_formats() { return pcm_supported_formats(); } std::optional PcmFormat::from_string(const std::string& str) { return pcm_format_from_string(str); } std::string PcmFormat::to_string() const { return pcm_format_to_string(*this); } PcmFormat PcmFormat::from_alsa(int fmt) { return pcm_format_from_alsa(fmt); } int PcmFormat::to_alsa() const { return pcm_format_to_alsa(*this); } } // namespace signal_estimator signal-estimator-0.0.9/src/base/io/PcmFormat.hpp000066400000000000000000000041151452044147100215160ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include #include #include namespace signal_estimator { // PCM sample encoding enum class PcmEncoding { SInt8, //!< 8-bit signed integer. UInt8, //!< 8-bit unsigned integer. SInt16, //!< 16-bit signed integer. UInt16, //!< 16-bit unsigned integer. SInt18_3B, //!< 18-bit signed integer, in low bits of 3-byte container. UInt18_3B, //!< 18-bit unsigned integer, in low bits of 3-byte container. SInt20_3B, //!< 20-bit signed integer, in low bits of 3-byte container. UInt20_3B, //!< 20-bit unsigned integer, in low bits of 3-byte container. SInt20_4B, //!< 20-bit signed integer, in low bits of 4-byte container. UInt20_4B, //!< 20-bit unsigned integer, in low bits of 4-byte container. SInt24_3B, //!< 24-bit signed integer (3 bytes). UInt24_3B, //!< 24-bit unsigned integer (3 bytes). SInt24_4B, //!< 24-bit signed integer, in low bits of 4-byte container. UInt24_4B, //!< 24-bit unsigned integer, in low bits of 4-byte container. SInt32, //!< 32-bit signed integer. UInt32, //!< 32-bit unsigned integer. Float32, //!< 32-bit IEEE-754 float in range [-1.0; +1.0]. Float64 //!< 64-bit IEEE-754 float in range [-1.0; +1.0]. }; // PCM sample endianess enum class PcmEndian { Native, //!< Endian native to current CPU. Big, //!< Big endian. Little //!< Little endian. }; // PCM format description struct PcmFormat { PcmEncoding encoding { PcmEncoding::SInt16 }; PcmEndian endian { PcmEndian::Native }; // info size_t bits() const; size_t bytes() const; bool is_int() const; // equality bool operator==(const PcmFormat& other) const; bool operator!=(const PcmFormat& other) const; // format list static std::vector supported_formats(); // strings static std::optional from_string(const std::string& str); std::string to_string() const; // alsa static PcmFormat from_alsa(int fmt); int to_alsa() const; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/io/PcmFuncs.hpp000066400000000000000000003023141452044147100213460ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT // Generated by generate_pcm.py. DO NOT EDIT! #pragma once #include "io/AlsaConstants.hpp" #include "io/PcmFormat.hpp" #include #include #include #include #include #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ // Big-endian CPU #define PCM_BIG_ENDIAN #else // Little-endian CPU #define PCM_LITTLE_ENDIAN #endif namespace signal_estimator { // SInt8 value range const int8_t pcm_sint8_min = -127 - 1; const int8_t pcm_sint8_max = 127; // UInt8 value range const uint8_t pcm_uint8_min = 0u; const uint8_t pcm_uint8_max = 255u; // SInt16 value range const int16_t pcm_sint16_min = -32767 - 1; const int16_t pcm_sint16_max = 32767; // UInt16 value range const uint16_t pcm_uint16_min = 0u; const uint16_t pcm_uint16_max = 65535u; // SInt18_3B value range const int32_t pcm_sint18_3b_min = -131071 - 1; const int32_t pcm_sint18_3b_max = 131071; // UInt18_3B value range const uint32_t pcm_uint18_3b_min = 0u; const uint32_t pcm_uint18_3b_max = 262143u; // SInt20_3B value range const int32_t pcm_sint20_3b_min = -524287 - 1; const int32_t pcm_sint20_3b_max = 524287; // UInt20_3B value range const uint32_t pcm_uint20_3b_min = 0u; const uint32_t pcm_uint20_3b_max = 1048575u; // SInt20_4B value range const int32_t pcm_sint20_4b_min = -524287 - 1; const int32_t pcm_sint20_4b_max = 524287; // UInt20_4B value range const uint32_t pcm_uint20_4b_min = 0u; const uint32_t pcm_uint20_4b_max = 1048575u; // SInt24_3B value range const int32_t pcm_sint24_3b_min = -8388607 - 1; const int32_t pcm_sint24_3b_max = 8388607; // UInt24_3B value range const uint32_t pcm_uint24_3b_min = 0u; const uint32_t pcm_uint24_3b_max = 16777215u; // SInt24_4B value range const int32_t pcm_sint24_4b_min = -8388607 - 1; const int32_t pcm_sint24_4b_max = 8388607; // UInt24_4B value range const uint32_t pcm_uint24_4b_min = 0u; const uint32_t pcm_uint24_4b_max = 16777215u; // SInt32 value range const int32_t pcm_sint32_min = -2147483647l - 1; const int32_t pcm_sint32_max = 2147483647l; // UInt32 value range const uint32_t pcm_uint32_min = 0ul; const uint32_t pcm_uint32_max = 4294967295ul; // Convert between signed and unsigned samples template struct pcm_sign_converter; // Convert SInt8 from/to signed/unsigned template <> struct pcm_sign_converter { // SInt8 from unsigned value static inline int8_t from_unsigned(uint8_t arg) { if (arg < uint8_t(pcm_sint8_max) + 1) { return int8_t(arg) - pcm_sint8_max - 1; } return int8_t(arg - uint8_t(pcm_sint8_max) - 1); } // SInt8 to unsigned value static inline uint8_t to_unsigned(int8_t arg) { if (arg >= 0) { return uint8_t(arg) + pcm_sint8_max + 1; } return uint8_t(arg + pcm_sint8_max + 1); } }; // Convert UInt8 from/to signed/unsigned template <> struct pcm_sign_converter { // UInt8 from signed value static inline uint8_t from_signed(int8_t arg) { if (arg >= 0) { return uint8_t(arg) + pcm_sint8_max + 1; } return uint8_t(arg + pcm_sint8_max + 1); } // UInt8 to signed value static inline int8_t to_signed(uint8_t arg) { if (arg >= uint8_t(pcm_sint8_max) + 1) { return int8_t(arg - uint8_t(pcm_sint8_max) - 1); } return int8_t(arg - uint8_t(pcm_sint8_max) - 1); } }; // Convert SInt16 from/to signed/unsigned template <> struct pcm_sign_converter { // SInt16 from unsigned value static inline int16_t from_unsigned(uint16_t arg) { if (arg < uint16_t(pcm_sint16_max) + 1) { return int16_t(arg) - pcm_sint16_max - 1; } return int16_t(arg - uint16_t(pcm_sint16_max) - 1); } // SInt16 to unsigned value static inline uint16_t to_unsigned(int16_t arg) { if (arg >= 0) { return uint16_t(arg) + pcm_sint16_max + 1; } return uint16_t(arg + pcm_sint16_max + 1); } }; // Convert UInt16 from/to signed/unsigned template <> struct pcm_sign_converter { // UInt16 from signed value static inline uint16_t from_signed(int16_t arg) { if (arg >= 0) { return uint16_t(arg) + pcm_sint16_max + 1; } return uint16_t(arg + pcm_sint16_max + 1); } // UInt16 to signed value static inline int16_t to_signed(uint16_t arg) { if (arg >= uint16_t(pcm_sint16_max) + 1) { return int16_t(arg - uint16_t(pcm_sint16_max) - 1); } return int16_t(arg - uint16_t(pcm_sint16_max) - 1); } }; // Convert SInt18_3B from/to signed/unsigned template <> struct pcm_sign_converter { // SInt18_3B from unsigned value static inline int32_t from_unsigned(uint32_t arg) { if (arg < uint32_t(pcm_sint18_3b_max) + 1) { return int32_t(arg) - pcm_sint18_3b_max - 1; } return int32_t(arg - uint32_t(pcm_sint18_3b_max) - 1); } // SInt18_3B to unsigned value static inline uint32_t to_unsigned(int32_t arg) { if (arg >= 0) { return uint32_t(arg) + pcm_sint18_3b_max + 1; } return uint32_t(arg + pcm_sint18_3b_max + 1); } }; // Convert UInt18_3B from/to signed/unsigned template <> struct pcm_sign_converter { // UInt18_3B from signed value static inline uint32_t from_signed(int32_t arg) { if (arg >= 0) { return uint32_t(arg) + pcm_sint18_3b_max + 1; } return uint32_t(arg + pcm_sint18_3b_max + 1); } // UInt18_3B to signed value static inline int32_t to_signed(uint32_t arg) { if (arg >= uint32_t(pcm_sint18_3b_max) + 1) { return int32_t(arg - uint32_t(pcm_sint18_3b_max) - 1); } return int32_t(arg - uint32_t(pcm_sint18_3b_max) - 1); } }; // Convert SInt20_3B from/to signed/unsigned template <> struct pcm_sign_converter { // SInt20_3B from unsigned value static inline int32_t from_unsigned(uint32_t arg) { if (arg < uint32_t(pcm_sint20_3b_max) + 1) { return int32_t(arg) - pcm_sint20_3b_max - 1; } return int32_t(arg - uint32_t(pcm_sint20_3b_max) - 1); } // SInt20_3B to unsigned value static inline uint32_t to_unsigned(int32_t arg) { if (arg >= 0) { return uint32_t(arg) + pcm_sint20_3b_max + 1; } return uint32_t(arg + pcm_sint20_3b_max + 1); } }; // Convert UInt20_3B from/to signed/unsigned template <> struct pcm_sign_converter { // UInt20_3B from signed value static inline uint32_t from_signed(int32_t arg) { if (arg >= 0) { return uint32_t(arg) + pcm_sint20_3b_max + 1; } return uint32_t(arg + pcm_sint20_3b_max + 1); } // UInt20_3B to signed value static inline int32_t to_signed(uint32_t arg) { if (arg >= uint32_t(pcm_sint20_3b_max) + 1) { return int32_t(arg - uint32_t(pcm_sint20_3b_max) - 1); } return int32_t(arg - uint32_t(pcm_sint20_3b_max) - 1); } }; // Convert SInt20_4B from/to signed/unsigned template <> struct pcm_sign_converter { // SInt20_4B from unsigned value static inline int32_t from_unsigned(uint32_t arg) { if (arg < uint32_t(pcm_sint20_4b_max) + 1) { return int32_t(arg) - pcm_sint20_4b_max - 1; } return int32_t(arg - uint32_t(pcm_sint20_4b_max) - 1); } // SInt20_4B to unsigned value static inline uint32_t to_unsigned(int32_t arg) { if (arg >= 0) { return uint32_t(arg) + pcm_sint20_4b_max + 1; } return uint32_t(arg + pcm_sint20_4b_max + 1); } }; // Convert UInt20_4B from/to signed/unsigned template <> struct pcm_sign_converter { // UInt20_4B from signed value static inline uint32_t from_signed(int32_t arg) { if (arg >= 0) { return uint32_t(arg) + pcm_sint20_4b_max + 1; } return uint32_t(arg + pcm_sint20_4b_max + 1); } // UInt20_4B to signed value static inline int32_t to_signed(uint32_t arg) { if (arg >= uint32_t(pcm_sint20_4b_max) + 1) { return int32_t(arg - uint32_t(pcm_sint20_4b_max) - 1); } return int32_t(arg - uint32_t(pcm_sint20_4b_max) - 1); } }; // Convert SInt24_3B from/to signed/unsigned template <> struct pcm_sign_converter { // SInt24_3B from unsigned value static inline int32_t from_unsigned(uint32_t arg) { if (arg < uint32_t(pcm_sint24_3b_max) + 1) { return int32_t(arg) - pcm_sint24_3b_max - 1; } return int32_t(arg - uint32_t(pcm_sint24_3b_max) - 1); } // SInt24_3B to unsigned value static inline uint32_t to_unsigned(int32_t arg) { if (arg >= 0) { return uint32_t(arg) + pcm_sint24_3b_max + 1; } return uint32_t(arg + pcm_sint24_3b_max + 1); } }; // Convert UInt24_3B from/to signed/unsigned template <> struct pcm_sign_converter { // UInt24_3B from signed value static inline uint32_t from_signed(int32_t arg) { if (arg >= 0) { return uint32_t(arg) + pcm_sint24_3b_max + 1; } return uint32_t(arg + pcm_sint24_3b_max + 1); } // UInt24_3B to signed value static inline int32_t to_signed(uint32_t arg) { if (arg >= uint32_t(pcm_sint24_3b_max) + 1) { return int32_t(arg - uint32_t(pcm_sint24_3b_max) - 1); } return int32_t(arg - uint32_t(pcm_sint24_3b_max) - 1); } }; // Convert SInt24_4B from/to signed/unsigned template <> struct pcm_sign_converter { // SInt24_4B from unsigned value static inline int32_t from_unsigned(uint32_t arg) { if (arg < uint32_t(pcm_sint24_4b_max) + 1) { return int32_t(arg) - pcm_sint24_4b_max - 1; } return int32_t(arg - uint32_t(pcm_sint24_4b_max) - 1); } // SInt24_4B to unsigned value static inline uint32_t to_unsigned(int32_t arg) { if (arg >= 0) { return uint32_t(arg) + pcm_sint24_4b_max + 1; } return uint32_t(arg + pcm_sint24_4b_max + 1); } }; // Convert UInt24_4B from/to signed/unsigned template <> struct pcm_sign_converter { // UInt24_4B from signed value static inline uint32_t from_signed(int32_t arg) { if (arg >= 0) { return uint32_t(arg) + pcm_sint24_4b_max + 1; } return uint32_t(arg + pcm_sint24_4b_max + 1); } // UInt24_4B to signed value static inline int32_t to_signed(uint32_t arg) { if (arg >= uint32_t(pcm_sint24_4b_max) + 1) { return int32_t(arg - uint32_t(pcm_sint24_4b_max) - 1); } return int32_t(arg - uint32_t(pcm_sint24_4b_max) - 1); } }; // Convert SInt32 from/to signed/unsigned template <> struct pcm_sign_converter { // SInt32 from unsigned value static inline int32_t from_unsigned(uint32_t arg) { if (arg < uint32_t(pcm_sint32_max) + 1) { return int32_t(arg) - pcm_sint32_max - 1; } return int32_t(arg - uint32_t(pcm_sint32_max) - 1); } // SInt32 to unsigned value static inline uint32_t to_unsigned(int32_t arg) { if (arg >= 0) { return uint32_t(arg) + pcm_sint32_max + 1; } return uint32_t(arg + pcm_sint32_max + 1); } }; // Convert UInt32 from/to signed/unsigned template <> struct pcm_sign_converter { // UInt32 from signed value static inline uint32_t from_signed(int32_t arg) { if (arg >= 0) { return uint32_t(arg) + pcm_sint32_max + 1; } return uint32_t(arg + pcm_sint32_max + 1); } // UInt32 to signed value static inline int32_t to_signed(uint32_t arg) { if (arg >= uint32_t(pcm_sint32_max) + 1) { return int32_t(arg - uint32_t(pcm_sint32_max) - 1); } return int32_t(arg - uint32_t(pcm_sint32_max) - 1); } }; // Convert between unpacked encodings template struct pcm_encoding_converter; // Convert SInt16 to SInt8 template <> struct pcm_encoding_converter { static inline int8_t convert(int16_t arg) { int16_t in = arg; int8_t out; // downscale signed integer if (in > int16_t(pcm_sint16_max - (int16_t(1) << 7))) { // clip out = pcm_sint8_max; } else { out = int8_t(uint16_t(in + (int16_t(1) << 7)) >> 8); } return out; } }; // Convert SInt16 to UInt8 template <> struct pcm_encoding_converter { static inline uint8_t convert(int16_t arg) { int16_t in = arg; int8_t out; // downscale signed integer if (in > int16_t(pcm_sint16_max - (int16_t(1) << 7))) { // clip out = pcm_sint8_max; } else { out = int8_t(uint16_t(in + (int16_t(1) << 7)) >> 8); } // convert to unsigned return pcm_sign_converter::from_signed(out); } }; // Convert SInt8 to SInt16 template <> struct pcm_encoding_converter { static inline int16_t convert(int8_t arg) { int8_t in = arg; int16_t out; // upscale signed integer out = int16_t(uint16_t(in) << 8); return out; } }; // Convert UInt8 to SInt16 template <> struct pcm_encoding_converter { static inline int16_t convert(uint8_t arg) { // convert to signed int8_t in = pcm_sign_converter::to_signed(arg); int16_t out; // upscale signed integer out = int16_t(uint16_t(in) << 8); return out; } }; // Convert SInt16 to SInt16 template <> struct pcm_encoding_converter { static inline int16_t convert(int16_t arg) { return arg; } }; // Convert UInt16 to SInt16 template <> struct pcm_encoding_converter { static inline int16_t convert(uint16_t arg) { // convert to signed int16_t in = pcm_sign_converter::to_signed(arg); int16_t out; out = in; return out; } }; // Convert SInt18_3B to SInt16 template <> struct pcm_encoding_converter { static inline int16_t convert(int32_t arg) { int32_t in = arg; int16_t out; // downscale signed integer if (in > int32_t(pcm_sint18_3b_max - (int32_t(1) << 1))) { // clip out = pcm_sint16_max; } else { out = int16_t(uint32_t(in + (int32_t(1) << 1)) >> 2); } return out; } }; // Convert UInt18_3B to SInt16 template <> struct pcm_encoding_converter { static inline int16_t convert(uint32_t arg) { // convert to signed int32_t in = pcm_sign_converter::to_signed(arg); int16_t out; // downscale signed integer if (in > int32_t(pcm_sint18_3b_max - (int32_t(1) << 1))) { // clip out = pcm_sint16_max; } else { out = int16_t(uint32_t(in + (int32_t(1) << 1)) >> 2); } return out; } }; // Convert SInt20_3B to SInt16 template <> struct pcm_encoding_converter { static inline int16_t convert(int32_t arg) { int32_t in = arg; int16_t out; // downscale signed integer if (in > int32_t(pcm_sint20_3b_max - (int32_t(1) << 3))) { // clip out = pcm_sint16_max; } else { out = int16_t(uint32_t(in + (int32_t(1) << 3)) >> 4); } return out; } }; // Convert UInt20_3B to SInt16 template <> struct pcm_encoding_converter { static inline int16_t convert(uint32_t arg) { // convert to signed int32_t in = pcm_sign_converter::to_signed(arg); int16_t out; // downscale signed integer if (in > int32_t(pcm_sint20_3b_max - (int32_t(1) << 3))) { // clip out = pcm_sint16_max; } else { out = int16_t(uint32_t(in + (int32_t(1) << 3)) >> 4); } return out; } }; // Convert SInt20_4B to SInt16 template <> struct pcm_encoding_converter { static inline int16_t convert(int32_t arg) { int32_t in = arg; int16_t out; // downscale signed integer if (in > int32_t(pcm_sint20_4b_max - (int32_t(1) << 3))) { // clip out = pcm_sint16_max; } else { out = int16_t(uint32_t(in + (int32_t(1) << 3)) >> 4); } return out; } }; // Convert UInt20_4B to SInt16 template <> struct pcm_encoding_converter { static inline int16_t convert(uint32_t arg) { // convert to signed int32_t in = pcm_sign_converter::to_signed(arg); int16_t out; // downscale signed integer if (in > int32_t(pcm_sint20_4b_max - (int32_t(1) << 3))) { // clip out = pcm_sint16_max; } else { out = int16_t(uint32_t(in + (int32_t(1) << 3)) >> 4); } return out; } }; // Convert SInt24_3B to SInt16 template <> struct pcm_encoding_converter { static inline int16_t convert(int32_t arg) { int32_t in = arg; int16_t out; // downscale signed integer if (in > int32_t(pcm_sint24_3b_max - (int32_t(1) << 7))) { // clip out = pcm_sint16_max; } else { out = int16_t(uint32_t(in + (int32_t(1) << 7)) >> 8); } return out; } }; // Convert UInt24_3B to SInt16 template <> struct pcm_encoding_converter { static inline int16_t convert(uint32_t arg) { // convert to signed int32_t in = pcm_sign_converter::to_signed(arg); int16_t out; // downscale signed integer if (in > int32_t(pcm_sint24_3b_max - (int32_t(1) << 7))) { // clip out = pcm_sint16_max; } else { out = int16_t(uint32_t(in + (int32_t(1) << 7)) >> 8); } return out; } }; // Convert SInt24_4B to SInt16 template <> struct pcm_encoding_converter { static inline int16_t convert(int32_t arg) { int32_t in = arg; int16_t out; // downscale signed integer if (in > int32_t(pcm_sint24_4b_max - (int32_t(1) << 7))) { // clip out = pcm_sint16_max; } else { out = int16_t(uint32_t(in + (int32_t(1) << 7)) >> 8); } return out; } }; // Convert UInt24_4B to SInt16 template <> struct pcm_encoding_converter { static inline int16_t convert(uint32_t arg) { // convert to signed int32_t in = pcm_sign_converter::to_signed(arg); int16_t out; // downscale signed integer if (in > int32_t(pcm_sint24_4b_max - (int32_t(1) << 7))) { // clip out = pcm_sint16_max; } else { out = int16_t(uint32_t(in + (int32_t(1) << 7)) >> 8); } return out; } }; // Convert SInt32 to SInt16 template <> struct pcm_encoding_converter { static inline int16_t convert(int32_t arg) { int32_t in = arg; int16_t out; // downscale signed integer if (in > int32_t(pcm_sint32_max - (int32_t(1) << 15))) { // clip out = pcm_sint16_max; } else { out = int16_t(uint32_t(in + (int32_t(1) << 15)) >> 16); } return out; } }; // Convert UInt32 to SInt16 template <> struct pcm_encoding_converter { static inline int16_t convert(uint32_t arg) { // convert to signed int32_t in = pcm_sign_converter::to_signed(arg); int16_t out; // downscale signed integer if (in > int32_t(pcm_sint32_max - (int32_t(1) << 15))) { // clip out = pcm_sint16_max; } else { out = int16_t(uint32_t(in + (int32_t(1) << 15)) >> 16); } return out; } }; // Convert Float32 to SInt16 template <> struct pcm_encoding_converter { static inline int16_t convert(float arg) { float in = arg; int16_t out; // float to integer const double d = double(in) * ((double)pcm_sint16_max + 1.0); if (d < pcm_sint16_min) { // clip out = pcm_sint16_min; } else if (d >= (double)pcm_sint16_max + 1.0) { // clip out = pcm_sint16_max; } else { out = int16_t(d); } return out; } }; // Convert Float64 to SInt16 template <> struct pcm_encoding_converter { static inline int16_t convert(double arg) { double in = arg; int16_t out; // float to integer const double d = double(in) * ((double)pcm_sint16_max + 1.0); if (d < pcm_sint16_min) { // clip out = pcm_sint16_min; } else if (d >= (double)pcm_sint16_max + 1.0) { // clip out = pcm_sint16_max; } else { out = int16_t(d); } return out; } }; // Convert SInt16 to UInt16 template <> struct pcm_encoding_converter { static inline uint16_t convert(int16_t arg) { int16_t in = arg; int16_t out; out = in; // convert to unsigned return pcm_sign_converter::from_signed(out); } }; // Convert SInt16 to SInt18_3B template <> struct pcm_encoding_converter { static inline int32_t convert(int16_t arg) { int16_t in = arg; int32_t out; // upscale signed integer out = int32_t(uint32_t(in) << 2); return out; } }; // Convert SInt16 to UInt18_3B template <> struct pcm_encoding_converter { static inline uint32_t convert(int16_t arg) { int16_t in = arg; int32_t out; // upscale signed integer out = int32_t(uint32_t(in) << 2); // convert to unsigned return pcm_sign_converter::from_signed(out); } }; // Convert SInt16 to SInt20_3B template <> struct pcm_encoding_converter { static inline int32_t convert(int16_t arg) { int16_t in = arg; int32_t out; // upscale signed integer out = int32_t(uint32_t(in) << 4); return out; } }; // Convert SInt16 to UInt20_3B template <> struct pcm_encoding_converter { static inline uint32_t convert(int16_t arg) { int16_t in = arg; int32_t out; // upscale signed integer out = int32_t(uint32_t(in) << 4); // convert to unsigned return pcm_sign_converter::from_signed(out); } }; // Convert SInt16 to SInt20_4B template <> struct pcm_encoding_converter { static inline int32_t convert(int16_t arg) { int16_t in = arg; int32_t out; // upscale signed integer out = int32_t(uint32_t(in) << 4); return out; } }; // Convert SInt16 to UInt20_4B template <> struct pcm_encoding_converter { static inline uint32_t convert(int16_t arg) { int16_t in = arg; int32_t out; // upscale signed integer out = int32_t(uint32_t(in) << 4); // convert to unsigned return pcm_sign_converter::from_signed(out); } }; // Convert SInt16 to SInt24_3B template <> struct pcm_encoding_converter { static inline int32_t convert(int16_t arg) { int16_t in = arg; int32_t out; // upscale signed integer out = int32_t(uint32_t(in) << 8); return out; } }; // Convert SInt16 to UInt24_3B template <> struct pcm_encoding_converter { static inline uint32_t convert(int16_t arg) { int16_t in = arg; int32_t out; // upscale signed integer out = int32_t(uint32_t(in) << 8); // convert to unsigned return pcm_sign_converter::from_signed(out); } }; // Convert SInt16 to SInt24_4B template <> struct pcm_encoding_converter { static inline int32_t convert(int16_t arg) { int16_t in = arg; int32_t out; // upscale signed integer out = int32_t(uint32_t(in) << 8); return out; } }; // Convert SInt16 to UInt24_4B template <> struct pcm_encoding_converter { static inline uint32_t convert(int16_t arg) { int16_t in = arg; int32_t out; // upscale signed integer out = int32_t(uint32_t(in) << 8); // convert to unsigned return pcm_sign_converter::from_signed(out); } }; // Convert SInt16 to SInt32 template <> struct pcm_encoding_converter { static inline int32_t convert(int16_t arg) { int16_t in = arg; int32_t out; // upscale signed integer out = int32_t(uint32_t(in) << 16); return out; } }; // Convert SInt16 to UInt32 template <> struct pcm_encoding_converter { static inline uint32_t convert(int16_t arg) { int16_t in = arg; int32_t out; // upscale signed integer out = int32_t(uint32_t(in) << 16); // convert to unsigned return pcm_sign_converter::from_signed(out); } }; // Convert SInt16 to Float32 template <> struct pcm_encoding_converter { static inline float convert(int16_t arg) { int16_t in = arg; float out; // integer to float out = float(in * (1.0 / ((double)pcm_sint16_max + 1.0))); return out; } }; // Convert SInt16 to Float64 template <> struct pcm_encoding_converter { static inline double convert(int16_t arg) { int16_t in = arg; double out; // integer to float out = double(in * (1.0 / ((double)pcm_sint16_max + 1.0))); return out; } }; // N-byte native-endian packed octet array template struct pcm_octets; // 1-byte native-endian packed octet array template <> struct pcm_octets<1> { #ifdef PCM_BIG_ENDIAN uint8_t octet0; #else uint8_t octet0; #endif }; // 2-byte native-endian packed octet array template <> struct pcm_octets<2> { #ifdef PCM_BIG_ENDIAN uint8_t octet1; uint8_t octet0; #else uint8_t octet0; uint8_t octet1; #endif }; // 4-byte native-endian packed octet array template <> struct pcm_octets<4> { #ifdef PCM_BIG_ENDIAN uint8_t octet3; uint8_t octet2; uint8_t octet1; uint8_t octet0; #else uint8_t octet0; uint8_t octet1; uint8_t octet2; uint8_t octet3; #endif }; // 8-byte native-endian packed octet array template <> struct pcm_octets<8> { #ifdef PCM_BIG_ENDIAN uint8_t octet7; uint8_t octet6; uint8_t octet5; uint8_t octet4; uint8_t octet3; uint8_t octet2; uint8_t octet1; uint8_t octet0; #else uint8_t octet0; uint8_t octet1; uint8_t octet2; uint8_t octet3; uint8_t octet4; uint8_t octet5; uint8_t octet6; uint8_t octet7; #endif }; // N-byte native-endian sample template struct pcm_sample; // int8_t native-endian sample template <> struct pcm_sample { union { int8_t value; pcm_octets<1> octets; }; }; // uint8_t native-endian sample template <> struct pcm_sample { union { uint8_t value; pcm_octets<1> octets; }; }; // int16_t native-endian sample template <> struct pcm_sample { union { int16_t value; pcm_octets<2> octets; }; }; // uint16_t native-endian sample template <> struct pcm_sample { union { uint16_t value; pcm_octets<2> octets; }; }; // int32_t native-endian sample template <> struct pcm_sample { union { int32_t value; pcm_octets<4> octets; }; }; // uint32_t native-endian sample template <> struct pcm_sample { union { uint32_t value; pcm_octets<4> octets; }; }; // int64_t native-endian sample template <> struct pcm_sample { union { int64_t value; pcm_octets<8> octets; }; }; // uint64_t native-endian sample template <> struct pcm_sample { union { uint64_t value; pcm_octets<8> octets; }; }; // float native-endian sample template <> struct pcm_sample { union { float value; pcm_octets<4> octets; }; }; // double native-endian sample template <> struct pcm_sample { union { double value; pcm_octets<8> octets; }; }; // Sample packer / unpacker template struct pcm_packer; // SInt8 Big-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, int8_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // write in big-endian order *(buffer++) = p.octets.octet0; } // Unpack next sample from buffer static inline int8_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in big-endian order p.octets.octet0 = *(buffer++); return p.value; } }; // SInt8 Little-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, int8_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // write in little-endian order *(buffer++) = p.octets.octet0; } // Unpack next sample from buffer static inline int8_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in little-endian order p.octets.octet0 = *(buffer++); return p.value; } }; // UInt8 Big-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, uint8_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // write in big-endian order *(buffer++) = p.octets.octet0; } // Unpack next sample from buffer static inline uint8_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in big-endian order p.octets.octet0 = *(buffer++); return p.value; } }; // UInt8 Little-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, uint8_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // write in little-endian order *(buffer++) = p.octets.octet0; } // Unpack next sample from buffer static inline uint8_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in little-endian order p.octets.octet0 = *(buffer++); return p.value; } }; // SInt16 Big-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, int16_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // write in big-endian order *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet0; } // Unpack next sample from buffer static inline int16_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in big-endian order p.octets.octet1 = *(buffer++); p.octets.octet0 = *(buffer++); return p.value; } }; // SInt16 Little-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, int16_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // write in little-endian order *(buffer++) = p.octets.octet0; *(buffer++) = p.octets.octet1; } // Unpack next sample from buffer static inline int16_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in little-endian order p.octets.octet0 = *(buffer++); p.octets.octet1 = *(buffer++); return p.value; } }; // UInt16 Big-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, uint16_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // write in big-endian order *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet0; } // Unpack next sample from buffer static inline uint16_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in big-endian order p.octets.octet1 = *(buffer++); p.octets.octet0 = *(buffer++); return p.value; } }; // UInt16 Little-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, uint16_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // write in little-endian order *(buffer++) = p.octets.octet0; *(buffer++) = p.octets.octet1; } // Unpack next sample from buffer static inline uint16_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in little-endian order p.octets.octet0 = *(buffer++); p.octets.octet1 = *(buffer++); return p.value; } }; // SInt18_3B Big-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, int32_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // zeroise padding bits p.value &= 0x3ffff; // write in big-endian order *(buffer++) = p.octets.octet2; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet0; } // Unpack next sample from buffer static inline int32_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in big-endian order p.octets.octet3 = 0; p.octets.octet2 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet0 = *(buffer++); // zeroise padding bits p.value &= 0x3ffff; if (p.value & 0x20000) { // sign extension p.value |= (int32_t)0xfffc0000; } return p.value; } }; // SInt18_3B Little-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, int32_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // zeroise padding bits p.value &= 0x3ffff; // write in little-endian order *(buffer++) = p.octets.octet0; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet2; } // Unpack next sample from buffer static inline int32_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in little-endian order p.octets.octet0 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet2 = *(buffer++); p.octets.octet3 = 0; // zeroise padding bits p.value &= 0x3ffff; if (p.value & 0x20000) { // sign extension p.value |= (int32_t)0xfffc0000; } return p.value; } }; // UInt18_3B Big-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, uint32_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // zeroise padding bits p.value &= 0x3ffffu; // write in big-endian order *(buffer++) = p.octets.octet2; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet0; } // Unpack next sample from buffer static inline uint32_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in big-endian order p.octets.octet3 = 0; p.octets.octet2 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet0 = *(buffer++); // zeroise padding bits p.value &= 0x3ffffu; return p.value; } }; // UInt18_3B Little-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, uint32_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // zeroise padding bits p.value &= 0x3ffffu; // write in little-endian order *(buffer++) = p.octets.octet0; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet2; } // Unpack next sample from buffer static inline uint32_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in little-endian order p.octets.octet0 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet2 = *(buffer++); p.octets.octet3 = 0; // zeroise padding bits p.value &= 0x3ffffu; return p.value; } }; // SInt20_3B Big-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, int32_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // zeroise padding bits p.value &= 0xfffff; // write in big-endian order *(buffer++) = p.octets.octet2; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet0; } // Unpack next sample from buffer static inline int32_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in big-endian order p.octets.octet3 = 0; p.octets.octet2 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet0 = *(buffer++); // zeroise padding bits p.value &= 0xfffff; if (p.value & 0x80000) { // sign extension p.value |= (int32_t)0xfff00000; } return p.value; } }; // SInt20_3B Little-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, int32_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // zeroise padding bits p.value &= 0xfffff; // write in little-endian order *(buffer++) = p.octets.octet0; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet2; } // Unpack next sample from buffer static inline int32_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in little-endian order p.octets.octet0 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet2 = *(buffer++); p.octets.octet3 = 0; // zeroise padding bits p.value &= 0xfffff; if (p.value & 0x80000) { // sign extension p.value |= (int32_t)0xfff00000; } return p.value; } }; // UInt20_3B Big-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, uint32_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // zeroise padding bits p.value &= 0xfffffu; // write in big-endian order *(buffer++) = p.octets.octet2; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet0; } // Unpack next sample from buffer static inline uint32_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in big-endian order p.octets.octet3 = 0; p.octets.octet2 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet0 = *(buffer++); // zeroise padding bits p.value &= 0xfffffu; return p.value; } }; // UInt20_3B Little-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, uint32_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // zeroise padding bits p.value &= 0xfffffu; // write in little-endian order *(buffer++) = p.octets.octet0; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet2; } // Unpack next sample from buffer static inline uint32_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in little-endian order p.octets.octet0 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet2 = *(buffer++); p.octets.octet3 = 0; // zeroise padding bits p.value &= 0xfffffu; return p.value; } }; // SInt20_4B Big-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, int32_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // zeroise padding bits p.value &= 0xfffff; // write in big-endian order *(buffer++) = p.octets.octet3; *(buffer++) = p.octets.octet2; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet0; } // Unpack next sample from buffer static inline int32_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in big-endian order p.octets.octet3 = *(buffer++); p.octets.octet2 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet0 = *(buffer++); // zeroise padding bits p.value &= 0xfffff; if (p.value & 0x80000) { // sign extension p.value |= (int32_t)0xfff00000; } return p.value; } }; // SInt20_4B Little-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, int32_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // zeroise padding bits p.value &= 0xfffff; // write in little-endian order *(buffer++) = p.octets.octet0; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet2; *(buffer++) = p.octets.octet3; } // Unpack next sample from buffer static inline int32_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in little-endian order p.octets.octet0 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet2 = *(buffer++); p.octets.octet3 = *(buffer++); // zeroise padding bits p.value &= 0xfffff; if (p.value & 0x80000) { // sign extension p.value |= (int32_t)0xfff00000; } return p.value; } }; // UInt20_4B Big-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, uint32_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // zeroise padding bits p.value &= 0xfffffu; // write in big-endian order *(buffer++) = p.octets.octet3; *(buffer++) = p.octets.octet2; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet0; } // Unpack next sample from buffer static inline uint32_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in big-endian order p.octets.octet3 = *(buffer++); p.octets.octet2 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet0 = *(buffer++); // zeroise padding bits p.value &= 0xfffffu; return p.value; } }; // UInt20_4B Little-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, uint32_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // zeroise padding bits p.value &= 0xfffffu; // write in little-endian order *(buffer++) = p.octets.octet0; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet2; *(buffer++) = p.octets.octet3; } // Unpack next sample from buffer static inline uint32_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in little-endian order p.octets.octet0 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet2 = *(buffer++); p.octets.octet3 = *(buffer++); // zeroise padding bits p.value &= 0xfffffu; return p.value; } }; // SInt24_3B Big-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, int32_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // write in big-endian order *(buffer++) = p.octets.octet2; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet0; } // Unpack next sample from buffer static inline int32_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in big-endian order p.octets.octet3 = 0; p.octets.octet2 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet0 = *(buffer++); if (p.value & 0x800000) { // sign extension p.value |= (int32_t)0xff000000; } return p.value; } }; // SInt24_3B Little-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, int32_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // write in little-endian order *(buffer++) = p.octets.octet0; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet2; } // Unpack next sample from buffer static inline int32_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in little-endian order p.octets.octet0 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet2 = *(buffer++); p.octets.octet3 = 0; if (p.value & 0x800000) { // sign extension p.value |= (int32_t)0xff000000; } return p.value; } }; // UInt24_3B Big-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, uint32_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // write in big-endian order *(buffer++) = p.octets.octet2; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet0; } // Unpack next sample from buffer static inline uint32_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in big-endian order p.octets.octet3 = 0; p.octets.octet2 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet0 = *(buffer++); return p.value; } }; // UInt24_3B Little-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, uint32_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // write in little-endian order *(buffer++) = p.octets.octet0; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet2; } // Unpack next sample from buffer static inline uint32_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in little-endian order p.octets.octet0 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet2 = *(buffer++); p.octets.octet3 = 0; return p.value; } }; // SInt24_4B Big-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, int32_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // zeroise padding bits p.value &= 0xffffff; // write in big-endian order *(buffer++) = p.octets.octet3; *(buffer++) = p.octets.octet2; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet0; } // Unpack next sample from buffer static inline int32_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in big-endian order p.octets.octet3 = *(buffer++); p.octets.octet2 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet0 = *(buffer++); // zeroise padding bits p.value &= 0xffffff; if (p.value & 0x800000) { // sign extension p.value |= (int32_t)0xff000000; } return p.value; } }; // SInt24_4B Little-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, int32_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // zeroise padding bits p.value &= 0xffffff; // write in little-endian order *(buffer++) = p.octets.octet0; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet2; *(buffer++) = p.octets.octet3; } // Unpack next sample from buffer static inline int32_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in little-endian order p.octets.octet0 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet2 = *(buffer++); p.octets.octet3 = *(buffer++); // zeroise padding bits p.value &= 0xffffff; if (p.value & 0x800000) { // sign extension p.value |= (int32_t)0xff000000; } return p.value; } }; // UInt24_4B Big-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, uint32_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // zeroise padding bits p.value &= 0xffffffu; // write in big-endian order *(buffer++) = p.octets.octet3; *(buffer++) = p.octets.octet2; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet0; } // Unpack next sample from buffer static inline uint32_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in big-endian order p.octets.octet3 = *(buffer++); p.octets.octet2 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet0 = *(buffer++); // zeroise padding bits p.value &= 0xffffffu; return p.value; } }; // UInt24_4B Little-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, uint32_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // zeroise padding bits p.value &= 0xffffffu; // write in little-endian order *(buffer++) = p.octets.octet0; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet2; *(buffer++) = p.octets.octet3; } // Unpack next sample from buffer static inline uint32_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in little-endian order p.octets.octet0 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet2 = *(buffer++); p.octets.octet3 = *(buffer++); // zeroise padding bits p.value &= 0xffffffu; return p.value; } }; // SInt32 Big-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, int32_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // write in big-endian order *(buffer++) = p.octets.octet3; *(buffer++) = p.octets.octet2; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet0; } // Unpack next sample from buffer static inline int32_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in big-endian order p.octets.octet3 = *(buffer++); p.octets.octet2 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet0 = *(buffer++); return p.value; } }; // SInt32 Little-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, int32_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // write in little-endian order *(buffer++) = p.octets.octet0; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet2; *(buffer++) = p.octets.octet3; } // Unpack next sample from buffer static inline int32_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in little-endian order p.octets.octet0 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet2 = *(buffer++); p.octets.octet3 = *(buffer++); return p.value; } }; // UInt32 Big-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, uint32_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // write in big-endian order *(buffer++) = p.octets.octet3; *(buffer++) = p.octets.octet2; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet0; } // Unpack next sample from buffer static inline uint32_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in big-endian order p.octets.octet3 = *(buffer++); p.octets.octet2 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet0 = *(buffer++); return p.value; } }; // UInt32 Little-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, uint32_t arg) { // native-endian view of octets pcm_sample p; p.value = arg; // write in little-endian order *(buffer++) = p.octets.octet0; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet2; *(buffer++) = p.octets.octet3; } // Unpack next sample from buffer static inline uint32_t unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in little-endian order p.octets.octet0 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet2 = *(buffer++); p.octets.octet3 = *(buffer++); return p.value; } }; // Float32 Big-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, float arg) { // native-endian view of octets pcm_sample p; p.value = arg; // write in big-endian order *(buffer++) = p.octets.octet3; *(buffer++) = p.octets.octet2; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet0; } // Unpack next sample from buffer static inline float unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in big-endian order p.octets.octet3 = *(buffer++); p.octets.octet2 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet0 = *(buffer++); return p.value; } }; // Float32 Little-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, float arg) { // native-endian view of octets pcm_sample p; p.value = arg; // write in little-endian order *(buffer++) = p.octets.octet0; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet2; *(buffer++) = p.octets.octet3; } // Unpack next sample from buffer static inline float unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in little-endian order p.octets.octet0 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet2 = *(buffer++); p.octets.octet3 = *(buffer++); return p.value; } }; // Float64 Big-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, double arg) { // native-endian view of octets pcm_sample p; p.value = arg; // write in big-endian order *(buffer++) = p.octets.octet7; *(buffer++) = p.octets.octet6; *(buffer++) = p.octets.octet5; *(buffer++) = p.octets.octet4; *(buffer++) = p.octets.octet3; *(buffer++) = p.octets.octet2; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet0; } // Unpack next sample from buffer static inline double unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in big-endian order p.octets.octet7 = *(buffer++); p.octets.octet6 = *(buffer++); p.octets.octet5 = *(buffer++); p.octets.octet4 = *(buffer++); p.octets.octet3 = *(buffer++); p.octets.octet2 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet0 = *(buffer++); return p.value; } }; // Float64 Little-Endian packer / unpacker template <> struct pcm_packer { // Pack next sample to buffer static inline void pack(uint8_t* buffer, double arg) { // native-endian view of octets pcm_sample p; p.value = arg; // write in little-endian order *(buffer++) = p.octets.octet0; *(buffer++) = p.octets.octet1; *(buffer++) = p.octets.octet2; *(buffer++) = p.octets.octet3; *(buffer++) = p.octets.octet4; *(buffer++) = p.octets.octet5; *(buffer++) = p.octets.octet6; *(buffer++) = p.octets.octet7; } // Unpack next sample from buffer static inline double unpack(const uint8_t* buffer) { // native-endian view of octets pcm_sample p; // read in little-endian order p.octets.octet0 = *(buffer++); p.octets.octet1 = *(buffer++); p.octets.octet2 = *(buffer++); p.octets.octet3 = *(buffer++); p.octets.octet4 = *(buffer++); p.octets.octet5 = *(buffer++); p.octets.octet6 = *(buffer++); p.octets.octet7 = *(buffer++); return p.value; } }; // Map encoding and endian of samples template struct pcm_mapper { static inline void map(const uint8_t* in_sample, uint8_t* out_sample) { pcm_packer::pack(out_sample, pcm_encoding_converter::convert( pcm_packer::unpack(in_sample))); } }; // Sample mapping function typedef void (*pcm_mapper_func_t)(const uint8_t* in_data, uint8_t* out_data); // Select mapper function template pcm_mapper_func_t pcm_mapper_func() { return &pcm_mapper::map; } // Select mapper function template pcm_mapper_func_t pcm_mapper_func(PcmEndian in_endian, PcmEndian out_endian) { switch (in_endian) { case PcmEndian::Native: #ifdef PCM_BIG_ENDIAN return pcm_mapper_func(PcmEndian::Big, out_endian); #else return pcm_mapper_func(PcmEndian::Little, out_endian); #endif case PcmEndian::Big: switch (out_endian) { case PcmEndian::Native: #ifdef PCM_BIG_ENDIAN return pcm_mapper_func(in_endian, PcmEndian::Big); #else return pcm_mapper_func(in_endian, PcmEndian::Little); #endif case PcmEndian::Big: return pcm_mapper_func(); case PcmEndian::Little: return pcm_mapper_func(); } break; case PcmEndian::Little: switch (out_endian) { case PcmEndian::Native: #ifdef PCM_BIG_ENDIAN return pcm_mapper_func(in_endian, PcmEndian::Big); #else return pcm_mapper_func(in_endian, PcmEndian::Little); #endif case PcmEndian::Big: return pcm_mapper_func(); case PcmEndian::Little: return pcm_mapper_func(); } break; } return nullptr; } // Select mapper function inline pcm_mapper_func_t pcm_mapper_func(PcmEncoding in_encoding, PcmEncoding out_encoding, PcmEndian in_endian, PcmEndian out_endian) { if (in_encoding == PcmEncoding::SInt16) { switch (out_encoding) { case PcmEncoding::SInt8: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::UInt8: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::SInt16: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::UInt16: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::SInt18_3B: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::UInt18_3B: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::SInt20_3B: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::UInt20_3B: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::SInt20_4B: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::UInt20_4B: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::SInt24_3B: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::UInt24_3B: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::SInt24_4B: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::UInt24_4B: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::SInt32: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::UInt32: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::Float32: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::Float64: return pcm_mapper_func( in_endian, out_endian); } } if (out_encoding == PcmEncoding::SInt16) { switch (in_encoding) { case PcmEncoding::SInt8: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::UInt8: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::SInt16: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::UInt16: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::SInt18_3B: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::UInt18_3B: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::SInt20_3B: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::UInt20_3B: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::SInt20_4B: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::UInt20_4B: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::SInt24_3B: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::UInt24_3B: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::SInt24_4B: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::UInt24_4B: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::SInt32: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::UInt32: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::Float32: return pcm_mapper_func( in_endian, out_endian); case PcmEncoding::Float64: return pcm_mapper_func( in_endian, out_endian); } } return nullptr; } // Get number of bits per sample in packed format inline size_t pcm_sample_bits(PcmEncoding encoding) { switch (encoding) { case PcmEncoding::SInt8: return 8; case PcmEncoding::UInt8: return 8; case PcmEncoding::SInt16: return 16; case PcmEncoding::UInt16: return 16; case PcmEncoding::SInt18_3B: return 18; case PcmEncoding::UInt18_3B: return 18; case PcmEncoding::SInt20_3B: return 20; case PcmEncoding::UInt20_3B: return 20; case PcmEncoding::SInt20_4B: return 20; case PcmEncoding::UInt20_4B: return 20; case PcmEncoding::SInt24_3B: return 24; case PcmEncoding::UInt24_3B: return 24; case PcmEncoding::SInt24_4B: return 24; case PcmEncoding::UInt24_4B: return 24; case PcmEncoding::SInt32: return 32; case PcmEncoding::UInt32: return 32; case PcmEncoding::Float32: return 32; case PcmEncoding::Float64: return 64; } return 0; } // Get number of bits per sample in packed format inline size_t pcm_sample_bytes(PcmEncoding encoding) { switch (encoding) { case PcmEncoding::SInt8: return 1; case PcmEncoding::UInt8: return 1; case PcmEncoding::SInt16: return 2; case PcmEncoding::UInt16: return 2; case PcmEncoding::SInt18_3B: return 3; case PcmEncoding::UInt18_3B: return 3; case PcmEncoding::SInt20_3B: return 3; case PcmEncoding::UInt20_3B: return 3; case PcmEncoding::SInt20_4B: return 4; case PcmEncoding::UInt20_4B: return 4; case PcmEncoding::SInt24_3B: return 3; case PcmEncoding::UInt24_3B: return 3; case PcmEncoding::SInt24_4B: return 4; case PcmEncoding::UInt24_4B: return 4; case PcmEncoding::SInt32: return 4; case PcmEncoding::UInt32: return 4; case PcmEncoding::Float32: return 4; case PcmEncoding::Float64: return 8; } return 0; } // List of all formats inline std::vector pcm_supported_formats() { return { PcmFormat{ PcmEncoding::SInt8, PcmEndian::Native }, PcmFormat{ PcmEncoding::UInt8, PcmEndian::Native }, PcmFormat{ PcmEncoding::SInt16, PcmEndian::Native }, PcmFormat{ PcmEncoding::SInt16, PcmEndian::Big }, PcmFormat{ PcmEncoding::SInt16, PcmEndian::Little }, PcmFormat{ PcmEncoding::UInt16, PcmEndian::Native }, PcmFormat{ PcmEncoding::UInt16, PcmEndian::Big }, PcmFormat{ PcmEncoding::UInt16, PcmEndian::Little }, PcmFormat{ PcmEncoding::SInt18_3B, PcmEndian::Native }, PcmFormat{ PcmEncoding::SInt18_3B, PcmEndian::Big }, PcmFormat{ PcmEncoding::SInt18_3B, PcmEndian::Little }, PcmFormat{ PcmEncoding::UInt18_3B, PcmEndian::Native }, PcmFormat{ PcmEncoding::UInt18_3B, PcmEndian::Big }, PcmFormat{ PcmEncoding::UInt18_3B, PcmEndian::Little }, PcmFormat{ PcmEncoding::SInt20_3B, PcmEndian::Native }, PcmFormat{ PcmEncoding::SInt20_3B, PcmEndian::Big }, PcmFormat{ PcmEncoding::SInt20_3B, PcmEndian::Little }, PcmFormat{ PcmEncoding::UInt20_3B, PcmEndian::Native }, PcmFormat{ PcmEncoding::UInt20_3B, PcmEndian::Big }, PcmFormat{ PcmEncoding::UInt20_3B, PcmEndian::Little }, PcmFormat{ PcmEncoding::SInt20_4B, PcmEndian::Native }, PcmFormat{ PcmEncoding::SInt20_4B, PcmEndian::Big }, PcmFormat{ PcmEncoding::SInt20_4B, PcmEndian::Little }, PcmFormat{ PcmEncoding::UInt20_4B, PcmEndian::Native }, PcmFormat{ PcmEncoding::UInt20_4B, PcmEndian::Big }, PcmFormat{ PcmEncoding::UInt20_4B, PcmEndian::Little }, PcmFormat{ PcmEncoding::SInt24_3B, PcmEndian::Native }, PcmFormat{ PcmEncoding::SInt24_3B, PcmEndian::Big }, PcmFormat{ PcmEncoding::SInt24_3B, PcmEndian::Little }, PcmFormat{ PcmEncoding::UInt24_3B, PcmEndian::Native }, PcmFormat{ PcmEncoding::UInt24_3B, PcmEndian::Big }, PcmFormat{ PcmEncoding::UInt24_3B, PcmEndian::Little }, PcmFormat{ PcmEncoding::SInt24_4B, PcmEndian::Native }, PcmFormat{ PcmEncoding::SInt24_4B, PcmEndian::Big }, PcmFormat{ PcmEncoding::SInt24_4B, PcmEndian::Little }, PcmFormat{ PcmEncoding::UInt24_4B, PcmEndian::Native }, PcmFormat{ PcmEncoding::UInt24_4B, PcmEndian::Big }, PcmFormat{ PcmEncoding::UInt24_4B, PcmEndian::Little }, PcmFormat{ PcmEncoding::SInt32, PcmEndian::Native }, PcmFormat{ PcmEncoding::SInt32, PcmEndian::Big }, PcmFormat{ PcmEncoding::SInt32, PcmEndian::Little }, PcmFormat{ PcmEncoding::UInt32, PcmEndian::Native }, PcmFormat{ PcmEncoding::UInt32, PcmEndian::Big }, PcmFormat{ PcmEncoding::UInt32, PcmEndian::Little }, PcmFormat{ PcmEncoding::Float32, PcmEndian::Native }, PcmFormat{ PcmEncoding::Float32, PcmEndian::Big }, PcmFormat{ PcmEncoding::Float32, PcmEndian::Little }, PcmFormat{ PcmEncoding::Float64, PcmEndian::Native }, PcmFormat{ PcmEncoding::Float64, PcmEndian::Big }, PcmFormat{ PcmEncoding::Float64, PcmEndian::Little }, }; } // Format from string inline std::optional pcm_format_from_string(const std::string& str) { if (str == "s8") { return PcmFormat{ PcmEncoding::SInt8, PcmEndian::Native }; } if (str == "s8_be") { return PcmFormat{ PcmEncoding::SInt8, PcmEndian::Big }; } if (str == "s8_le") { return PcmFormat{ PcmEncoding::SInt8, PcmEndian::Little }; } if (str == "u8") { return PcmFormat{ PcmEncoding::UInt8, PcmEndian::Native }; } if (str == "u8_be") { return PcmFormat{ PcmEncoding::UInt8, PcmEndian::Big }; } if (str == "u8_le") { return PcmFormat{ PcmEncoding::UInt8, PcmEndian::Little }; } if (str == "s16") { return PcmFormat{ PcmEncoding::SInt16, PcmEndian::Native }; } if (str == "s16_be") { return PcmFormat{ PcmEncoding::SInt16, PcmEndian::Big }; } if (str == "s16_le") { return PcmFormat{ PcmEncoding::SInt16, PcmEndian::Little }; } if (str == "u16") { return PcmFormat{ PcmEncoding::UInt16, PcmEndian::Native }; } if (str == "u16_be") { return PcmFormat{ PcmEncoding::UInt16, PcmEndian::Big }; } if (str == "u16_le") { return PcmFormat{ PcmEncoding::UInt16, PcmEndian::Little }; } if (str == "s18_3") { return PcmFormat{ PcmEncoding::SInt18_3B, PcmEndian::Native }; } if (str == "s18_3be") { return PcmFormat{ PcmEncoding::SInt18_3B, PcmEndian::Big }; } if (str == "s18_3le") { return PcmFormat{ PcmEncoding::SInt18_3B, PcmEndian::Little }; } if (str == "u18_3") { return PcmFormat{ PcmEncoding::UInt18_3B, PcmEndian::Native }; } if (str == "u18_3be") { return PcmFormat{ PcmEncoding::UInt18_3B, PcmEndian::Big }; } if (str == "u18_3le") { return PcmFormat{ PcmEncoding::UInt18_3B, PcmEndian::Little }; } if (str == "s20_3") { return PcmFormat{ PcmEncoding::SInt20_3B, PcmEndian::Native }; } if (str == "s20_3be") { return PcmFormat{ PcmEncoding::SInt20_3B, PcmEndian::Big }; } if (str == "s20_3le") { return PcmFormat{ PcmEncoding::SInt20_3B, PcmEndian::Little }; } if (str == "u20_3") { return PcmFormat{ PcmEncoding::UInt20_3B, PcmEndian::Native }; } if (str == "u20_3be") { return PcmFormat{ PcmEncoding::UInt20_3B, PcmEndian::Big }; } if (str == "u20_3le") { return PcmFormat{ PcmEncoding::UInt20_3B, PcmEndian::Little }; } if (str == "s20") { return PcmFormat{ PcmEncoding::SInt20_4B, PcmEndian::Native }; } if (str == "s20_be") { return PcmFormat{ PcmEncoding::SInt20_4B, PcmEndian::Big }; } if (str == "s20_le") { return PcmFormat{ PcmEncoding::SInt20_4B, PcmEndian::Little }; } if (str == "u20") { return PcmFormat{ PcmEncoding::UInt20_4B, PcmEndian::Native }; } if (str == "u20_be") { return PcmFormat{ PcmEncoding::UInt20_4B, PcmEndian::Big }; } if (str == "u20_le") { return PcmFormat{ PcmEncoding::UInt20_4B, PcmEndian::Little }; } if (str == "s24_3") { return PcmFormat{ PcmEncoding::SInt24_3B, PcmEndian::Native }; } if (str == "s24_3be") { return PcmFormat{ PcmEncoding::SInt24_3B, PcmEndian::Big }; } if (str == "s24_3le") { return PcmFormat{ PcmEncoding::SInt24_3B, PcmEndian::Little }; } if (str == "u24_3") { return PcmFormat{ PcmEncoding::UInt24_3B, PcmEndian::Native }; } if (str == "u24_3be") { return PcmFormat{ PcmEncoding::UInt24_3B, PcmEndian::Big }; } if (str == "u24_3le") { return PcmFormat{ PcmEncoding::UInt24_3B, PcmEndian::Little }; } if (str == "s24") { return PcmFormat{ PcmEncoding::SInt24_4B, PcmEndian::Native }; } if (str == "s24_be") { return PcmFormat{ PcmEncoding::SInt24_4B, PcmEndian::Big }; } if (str == "s24_le") { return PcmFormat{ PcmEncoding::SInt24_4B, PcmEndian::Little }; } if (str == "u24") { return PcmFormat{ PcmEncoding::UInt24_4B, PcmEndian::Native }; } if (str == "u24_be") { return PcmFormat{ PcmEncoding::UInt24_4B, PcmEndian::Big }; } if (str == "u24_le") { return PcmFormat{ PcmEncoding::UInt24_4B, PcmEndian::Little }; } if (str == "s32") { return PcmFormat{ PcmEncoding::SInt32, PcmEndian::Native }; } if (str == "s32_be") { return PcmFormat{ PcmEncoding::SInt32, PcmEndian::Big }; } if (str == "s32_le") { return PcmFormat{ PcmEncoding::SInt32, PcmEndian::Little }; } if (str == "u32") { return PcmFormat{ PcmEncoding::UInt32, PcmEndian::Native }; } if (str == "u32_be") { return PcmFormat{ PcmEncoding::UInt32, PcmEndian::Big }; } if (str == "u32_le") { return PcmFormat{ PcmEncoding::UInt32, PcmEndian::Little }; } if (str == "float") { return PcmFormat{ PcmEncoding::Float32, PcmEndian::Native }; } if (str == "float_be") { return PcmFormat{ PcmEncoding::Float32, PcmEndian::Big }; } if (str == "float_le") { return PcmFormat{ PcmEncoding::Float32, PcmEndian::Little }; } if (str == "float64") { return PcmFormat{ PcmEncoding::Float64, PcmEndian::Native }; } if (str == "float64_be") { return PcmFormat{ PcmEncoding::Float64, PcmEndian::Big }; } if (str == "float64_le") { return PcmFormat{ PcmEncoding::Float64, PcmEndian::Little }; } return {}; } // Format to string inline std::string pcm_format_to_string(const PcmFormat& format) { switch (format.encoding) { case PcmEncoding::SInt8: switch (format.endian) { case PcmEndian::Native: return "s8"; case PcmEndian::Big: return "s8_be"; case PcmEndian::Little: return "s8_le"; } break; case PcmEncoding::UInt8: switch (format.endian) { case PcmEndian::Native: return "u8"; case PcmEndian::Big: return "u8_be"; case PcmEndian::Little: return "u8_le"; } break; case PcmEncoding::SInt16: switch (format.endian) { case PcmEndian::Native: return "s16"; case PcmEndian::Big: return "s16_be"; case PcmEndian::Little: return "s16_le"; } break; case PcmEncoding::UInt16: switch (format.endian) { case PcmEndian::Native: return "u16"; case PcmEndian::Big: return "u16_be"; case PcmEndian::Little: return "u16_le"; } break; case PcmEncoding::SInt18_3B: switch (format.endian) { case PcmEndian::Native: return "s18_3"; case PcmEndian::Big: return "s18_3be"; case PcmEndian::Little: return "s18_3le"; } break; case PcmEncoding::UInt18_3B: switch (format.endian) { case PcmEndian::Native: return "u18_3"; case PcmEndian::Big: return "u18_3be"; case PcmEndian::Little: return "u18_3le"; } break; case PcmEncoding::SInt20_3B: switch (format.endian) { case PcmEndian::Native: return "s20_3"; case PcmEndian::Big: return "s20_3be"; case PcmEndian::Little: return "s20_3le"; } break; case PcmEncoding::UInt20_3B: switch (format.endian) { case PcmEndian::Native: return "u20_3"; case PcmEndian::Big: return "u20_3be"; case PcmEndian::Little: return "u20_3le"; } break; case PcmEncoding::SInt20_4B: switch (format.endian) { case PcmEndian::Native: return "s20"; case PcmEndian::Big: return "s20_be"; case PcmEndian::Little: return "s20_le"; } break; case PcmEncoding::UInt20_4B: switch (format.endian) { case PcmEndian::Native: return "u20"; case PcmEndian::Big: return "u20_be"; case PcmEndian::Little: return "u20_le"; } break; case PcmEncoding::SInt24_3B: switch (format.endian) { case PcmEndian::Native: return "s24_3"; case PcmEndian::Big: return "s24_3be"; case PcmEndian::Little: return "s24_3le"; } break; case PcmEncoding::UInt24_3B: switch (format.endian) { case PcmEndian::Native: return "u24_3"; case PcmEndian::Big: return "u24_3be"; case PcmEndian::Little: return "u24_3le"; } break; case PcmEncoding::SInt24_4B: switch (format.endian) { case PcmEndian::Native: return "s24"; case PcmEndian::Big: return "s24_be"; case PcmEndian::Little: return "s24_le"; } break; case PcmEncoding::UInt24_4B: switch (format.endian) { case PcmEndian::Native: return "u24"; case PcmEndian::Big: return "u24_be"; case PcmEndian::Little: return "u24_le"; } break; case PcmEncoding::SInt32: switch (format.endian) { case PcmEndian::Native: return "s32"; case PcmEndian::Big: return "s32_be"; case PcmEndian::Little: return "s32_le"; } break; case PcmEncoding::UInt32: switch (format.endian) { case PcmEndian::Native: return "u32"; case PcmEndian::Big: return "u32_be"; case PcmEndian::Little: return "u32_le"; } break; case PcmEncoding::Float32: switch (format.endian) { case PcmEndian::Native: return "float"; case PcmEndian::Big: return "float_be"; case PcmEndian::Little: return "float_le"; } break; case PcmEncoding::Float64: switch (format.endian) { case PcmEndian::Native: return "float64"; case PcmEndian::Big: return "float64_be"; case PcmEndian::Little: return "float64_le"; } break; } return ""; } // Format from ALSA inline PcmFormat pcm_format_from_alsa(int format) { switch (format) { case SND_PCM_FORMAT_S8: #ifdef PCM_BIG_ENDIAN return PcmFormat{ PcmEncoding::SInt8, PcmEndian::Big }; #else return PcmFormat{ PcmEncoding::SInt8, PcmEndian::Little }; #endif case SND_PCM_FORMAT_U8: #ifdef PCM_BIG_ENDIAN return PcmFormat{ PcmEncoding::UInt8, PcmEndian::Big }; #else return PcmFormat{ PcmEncoding::UInt8, PcmEndian::Little }; #endif case SND_PCM_FORMAT_S16_BE: return PcmFormat{ PcmEncoding::SInt16, PcmEndian::Big }; case SND_PCM_FORMAT_S16_LE: return PcmFormat{ PcmEncoding::SInt16, PcmEndian::Little }; case SND_PCM_FORMAT_U16_BE: return PcmFormat{ PcmEncoding::UInt16, PcmEndian::Big }; case SND_PCM_FORMAT_U16_LE: return PcmFormat{ PcmEncoding::UInt16, PcmEndian::Little }; case SND_PCM_FORMAT_S18_3BE: return PcmFormat{ PcmEncoding::SInt18_3B, PcmEndian::Big }; case SND_PCM_FORMAT_S18_3LE: return PcmFormat{ PcmEncoding::SInt18_3B, PcmEndian::Little }; case SND_PCM_FORMAT_U18_3BE: return PcmFormat{ PcmEncoding::UInt18_3B, PcmEndian::Big }; case SND_PCM_FORMAT_U18_3LE: return PcmFormat{ PcmEncoding::UInt18_3B, PcmEndian::Little }; case SND_PCM_FORMAT_S20_3BE: return PcmFormat{ PcmEncoding::SInt20_3B, PcmEndian::Big }; case SND_PCM_FORMAT_S20_3LE: return PcmFormat{ PcmEncoding::SInt20_3B, PcmEndian::Little }; case SND_PCM_FORMAT_U20_3BE: return PcmFormat{ PcmEncoding::UInt20_3B, PcmEndian::Big }; case SND_PCM_FORMAT_U20_3LE: return PcmFormat{ PcmEncoding::UInt20_3B, PcmEndian::Little }; case SND_PCM_FORMAT_S20_BE: return PcmFormat{ PcmEncoding::SInt20_4B, PcmEndian::Big }; case SND_PCM_FORMAT_S20_LE: return PcmFormat{ PcmEncoding::SInt20_4B, PcmEndian::Little }; case SND_PCM_FORMAT_U20_BE: return PcmFormat{ PcmEncoding::UInt20_4B, PcmEndian::Big }; case SND_PCM_FORMAT_U20_LE: return PcmFormat{ PcmEncoding::UInt20_4B, PcmEndian::Little }; case SND_PCM_FORMAT_S24_3BE: return PcmFormat{ PcmEncoding::SInt24_3B, PcmEndian::Big }; case SND_PCM_FORMAT_S24_3LE: return PcmFormat{ PcmEncoding::SInt24_3B, PcmEndian::Little }; case SND_PCM_FORMAT_U24_3BE: return PcmFormat{ PcmEncoding::UInt24_3B, PcmEndian::Big }; case SND_PCM_FORMAT_U24_3LE: return PcmFormat{ PcmEncoding::UInt24_3B, PcmEndian::Little }; case SND_PCM_FORMAT_S24_BE: return PcmFormat{ PcmEncoding::SInt24_4B, PcmEndian::Big }; case SND_PCM_FORMAT_S24_LE: return PcmFormat{ PcmEncoding::SInt24_4B, PcmEndian::Little }; case SND_PCM_FORMAT_U24_BE: return PcmFormat{ PcmEncoding::UInt24_4B, PcmEndian::Big }; case SND_PCM_FORMAT_U24_LE: return PcmFormat{ PcmEncoding::UInt24_4B, PcmEndian::Little }; case SND_PCM_FORMAT_S32_BE: return PcmFormat{ PcmEncoding::SInt32, PcmEndian::Big }; case SND_PCM_FORMAT_S32_LE: return PcmFormat{ PcmEncoding::SInt32, PcmEndian::Little }; case SND_PCM_FORMAT_U32_BE: return PcmFormat{ PcmEncoding::UInt32, PcmEndian::Big }; case SND_PCM_FORMAT_U32_LE: return PcmFormat{ PcmEncoding::UInt32, PcmEndian::Little }; case SND_PCM_FORMAT_FLOAT_BE: return PcmFormat{ PcmEncoding::Float32, PcmEndian::Big }; case SND_PCM_FORMAT_FLOAT_LE: return PcmFormat{ PcmEncoding::Float32, PcmEndian::Little }; case SND_PCM_FORMAT_FLOAT64_BE: return PcmFormat{ PcmEncoding::Float64, PcmEndian::Big }; case SND_PCM_FORMAT_FLOAT64_LE: return PcmFormat{ PcmEncoding::Float64, PcmEndian::Little }; } return {}; } // Format to ALSA inline int pcm_format_to_alsa(const PcmFormat& format) { switch (format.encoding) { case PcmEncoding::SInt8: switch (format.endian) { case PcmEndian::Native: return SND_PCM_FORMAT_S8; case PcmEndian::Big: return SND_PCM_FORMAT_S8; case PcmEndian::Little: return SND_PCM_FORMAT_S8; } break; case PcmEncoding::UInt8: switch (format.endian) { case PcmEndian::Native: return SND_PCM_FORMAT_U8; case PcmEndian::Big: return SND_PCM_FORMAT_U8; case PcmEndian::Little: return SND_PCM_FORMAT_U8; } break; case PcmEncoding::SInt16: switch (format.endian) { case PcmEndian::Native: #ifdef PCM_BIG_ENDIAN return SND_PCM_FORMAT_S16_BE; #else return SND_PCM_FORMAT_S16_LE; #endif case PcmEndian::Big: return SND_PCM_FORMAT_S16_BE; case PcmEndian::Little: return SND_PCM_FORMAT_S16_LE; } break; case PcmEncoding::UInt16: switch (format.endian) { case PcmEndian::Native: #ifdef PCM_BIG_ENDIAN return SND_PCM_FORMAT_U16_BE; #else return SND_PCM_FORMAT_U16_LE; #endif case PcmEndian::Big: return SND_PCM_FORMAT_U16_BE; case PcmEndian::Little: return SND_PCM_FORMAT_U16_LE; } break; case PcmEncoding::SInt18_3B: switch (format.endian) { case PcmEndian::Native: #ifdef PCM_BIG_ENDIAN return SND_PCM_FORMAT_S18_3BE; #else return SND_PCM_FORMAT_S18_3LE; #endif case PcmEndian::Big: return SND_PCM_FORMAT_S18_3BE; case PcmEndian::Little: return SND_PCM_FORMAT_S18_3LE; } break; case PcmEncoding::UInt18_3B: switch (format.endian) { case PcmEndian::Native: #ifdef PCM_BIG_ENDIAN return SND_PCM_FORMAT_U18_3BE; #else return SND_PCM_FORMAT_U18_3LE; #endif case PcmEndian::Big: return SND_PCM_FORMAT_U18_3BE; case PcmEndian::Little: return SND_PCM_FORMAT_U18_3LE; } break; case PcmEncoding::SInt20_3B: switch (format.endian) { case PcmEndian::Native: #ifdef PCM_BIG_ENDIAN return SND_PCM_FORMAT_S20_3BE; #else return SND_PCM_FORMAT_S20_3LE; #endif case PcmEndian::Big: return SND_PCM_FORMAT_S20_3BE; case PcmEndian::Little: return SND_PCM_FORMAT_S20_3LE; } break; case PcmEncoding::UInt20_3B: switch (format.endian) { case PcmEndian::Native: #ifdef PCM_BIG_ENDIAN return SND_PCM_FORMAT_U20_3BE; #else return SND_PCM_FORMAT_U20_3LE; #endif case PcmEndian::Big: return SND_PCM_FORMAT_U20_3BE; case PcmEndian::Little: return SND_PCM_FORMAT_U20_3LE; } break; case PcmEncoding::SInt20_4B: switch (format.endian) { case PcmEndian::Native: #ifdef PCM_BIG_ENDIAN return SND_PCM_FORMAT_S20_BE; #else return SND_PCM_FORMAT_S20_LE; #endif case PcmEndian::Big: return SND_PCM_FORMAT_S20_BE; case PcmEndian::Little: return SND_PCM_FORMAT_S20_LE; } break; case PcmEncoding::UInt20_4B: switch (format.endian) { case PcmEndian::Native: #ifdef PCM_BIG_ENDIAN return SND_PCM_FORMAT_U20_BE; #else return SND_PCM_FORMAT_U20_LE; #endif case PcmEndian::Big: return SND_PCM_FORMAT_U20_BE; case PcmEndian::Little: return SND_PCM_FORMAT_U20_LE; } break; case PcmEncoding::SInt24_3B: switch (format.endian) { case PcmEndian::Native: #ifdef PCM_BIG_ENDIAN return SND_PCM_FORMAT_S24_3BE; #else return SND_PCM_FORMAT_S24_3LE; #endif case PcmEndian::Big: return SND_PCM_FORMAT_S24_3BE; case PcmEndian::Little: return SND_PCM_FORMAT_S24_3LE; } break; case PcmEncoding::UInt24_3B: switch (format.endian) { case PcmEndian::Native: #ifdef PCM_BIG_ENDIAN return SND_PCM_FORMAT_U24_3BE; #else return SND_PCM_FORMAT_U24_3LE; #endif case PcmEndian::Big: return SND_PCM_FORMAT_U24_3BE; case PcmEndian::Little: return SND_PCM_FORMAT_U24_3LE; } break; case PcmEncoding::SInt24_4B: switch (format.endian) { case PcmEndian::Native: #ifdef PCM_BIG_ENDIAN return SND_PCM_FORMAT_S24_BE; #else return SND_PCM_FORMAT_S24_LE; #endif case PcmEndian::Big: return SND_PCM_FORMAT_S24_BE; case PcmEndian::Little: return SND_PCM_FORMAT_S24_LE; } break; case PcmEncoding::UInt24_4B: switch (format.endian) { case PcmEndian::Native: #ifdef PCM_BIG_ENDIAN return SND_PCM_FORMAT_U24_BE; #else return SND_PCM_FORMAT_U24_LE; #endif case PcmEndian::Big: return SND_PCM_FORMAT_U24_BE; case PcmEndian::Little: return SND_PCM_FORMAT_U24_LE; } break; case PcmEncoding::SInt32: switch (format.endian) { case PcmEndian::Native: #ifdef PCM_BIG_ENDIAN return SND_PCM_FORMAT_S32_BE; #else return SND_PCM_FORMAT_S32_LE; #endif case PcmEndian::Big: return SND_PCM_FORMAT_S32_BE; case PcmEndian::Little: return SND_PCM_FORMAT_S32_LE; } break; case PcmEncoding::UInt32: switch (format.endian) { case PcmEndian::Native: #ifdef PCM_BIG_ENDIAN return SND_PCM_FORMAT_U32_BE; #else return SND_PCM_FORMAT_U32_LE; #endif case PcmEndian::Big: return SND_PCM_FORMAT_U32_BE; case PcmEndian::Little: return SND_PCM_FORMAT_U32_LE; } break; case PcmEncoding::Float32: switch (format.endian) { case PcmEndian::Native: #ifdef PCM_BIG_ENDIAN return SND_PCM_FORMAT_FLOAT_BE; #else return SND_PCM_FORMAT_FLOAT_LE; #endif case PcmEndian::Big: return SND_PCM_FORMAT_FLOAT_BE; case PcmEndian::Little: return SND_PCM_FORMAT_FLOAT_LE; } break; case PcmEncoding::Float64: switch (format.endian) { case PcmEndian::Native: #ifdef PCM_BIG_ENDIAN return SND_PCM_FORMAT_FLOAT64_BE; #else return SND_PCM_FORMAT_FLOAT64_LE; #endif case PcmEndian::Big: return SND_PCM_FORMAT_FLOAT64_BE; case PcmEndian::Little: return SND_PCM_FORMAT_FLOAT64_LE; } break; } return SND_PCM_FORMAT_UNKNOWN; } } // namespace signal_estimator signal-estimator-0.0.9/src/base/io/PcmMapper.cpp000066400000000000000000000034041452044147100215050ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "io/PcmMapper.hpp" #include "io/PcmFuncs.hpp" #include #include namespace signal_estimator { PcmMapper::PcmMapper( const PcmFormat& in_fmt, size_t in_chans, const PcmFormat& out_fmt, size_t out_chans) : in_fmt_(in_fmt) , out_fmt_(out_fmt) , in_chans_(in_chans) , out_chans_(out_chans) , in_sample_sz_(pcm_sample_bytes(in_fmt.encoding)) , out_sample_sz_(pcm_sample_bytes(out_fmt.encoding)) , map_func_(pcm_mapper_func( in_fmt_.encoding, out_fmt_.encoding, in_fmt_.endian, out_fmt_.endian)) { assert(in_fmt == PcmFormat() || out_fmt == PcmFormat()); assert(map_func_); } size_t PcmMapper::input_bytes(size_t samples_per_chan) const { return samples_per_chan * in_chans_ * in_sample_sz_; } size_t PcmMapper::output_bytes(size_t samples_per_chan) const { return samples_per_chan * out_chans_ * out_sample_sz_; } void PcmMapper::map( const uint8_t* in_samples, uint8_t* out_samples, size_t samples_per_chan) { assert(in_samples); assert(out_samples); for (size_t ns = 0; ns < samples_per_chan; ns++) { size_t in_pos = 0, out_pos = 0; while (in_pos < in_chans_ && out_pos < out_chans_) { map_func_(in_samples, out_samples); in_pos++; in_samples += in_sample_sz_; out_pos++; out_samples += out_sample_sz_; } while (out_pos < out_chans_) { map_func_(in_samples - in_sample_sz_, out_samples); out_pos++; out_samples += out_sample_sz_; } while (in_pos < in_chans_) { in_pos++; in_samples += in_sample_sz_; } } } } // namespace signal_estimator signal-estimator-0.0.9/src/base/io/PcmMapper.hpp000066400000000000000000000020151452044147100215070ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "io/PcmFormat.hpp" #include #include namespace signal_estimator { // PCM format mapper // Maps encoding, endian, and channel count // Input or output format should be default format (or both) class PcmMapper { public: PcmMapper(const PcmFormat& in_fmt, size_t in_chans, const PcmFormat& out_fmt, size_t out_chans); PcmMapper(const PcmMapper&) = delete; PcmMapper& operator=(const PcmMapper&) = delete; size_t input_bytes(size_t samples_per_chan) const; size_t output_bytes(size_t samples_per_chan) const; void map(const uint8_t* in_samples, uint8_t* out_samples, size_t samples_per_chan); private: const PcmFormat in_fmt_; const PcmFormat out_fmt_; const size_t in_chans_; const size_t out_chans_; const size_t in_sample_sz_; const size_t out_sample_sz_; void (*const map_func_)(const uint8_t* in_data, uint8_t* out_data); }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/processing/000077500000000000000000000000001452044147100206615ustar00rootroot00000000000000signal-estimator-0.0.9/src/base/processing/ContinuousGenerator.cpp000066400000000000000000000012041452044147100253770ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "processing/ContinuousGenerator.hpp" #include #include namespace signal_estimator { ContinuousGenerator::ContinuousGenerator(const Config& config) : config_(config) { } void ContinuousGenerator::generate(Frame& frame) { for (size_t sn = 0; sn < frame.size();) { for (size_t cn = 0; cn < config_.channel_count; cn++) { frame[sn++] = saturated_cast(MaxSample * config_.gain * std::sin(2 * (float)M_PI / config_.sample_rate * 500 * pos_)); } pos_++; } } } // namespace signal_estimator signal-estimator-0.0.9/src/base/processing/ContinuousGenerator.hpp000066400000000000000000000011051452044147100254040ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/Config.hpp" #include "processing/IGenerator.hpp" namespace signal_estimator { // generate continuous sine wave class ContinuousGenerator : public IGenerator { public: ContinuousGenerator(const Config& config); ContinuousGenerator(const ContinuousGenerator&) = delete; ContinuousGenerator& operator=(const ContinuousGenerator&) = delete; void generate(Frame& frame) override; private: const Config config_; size_t pos_ {}; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/processing/CorrelationLatencyEstimator.cpp000066400000000000000000000155121452044147100270620ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "processing/CorrelationLatencyEstimator.hpp" #include "core/Realtime.hpp" #include namespace signal_estimator { CorrelationLatencyEstimator::CorrelationLatencyEstimator( const Config& config, IReporter& reporter) : config_(config) , reporter_(reporter) , hw_avg_(config_.report_sma_window) , thread_(&CorrelationLatencyEstimator::run_, this) , causality_timeout_lim_(config_.frames_to_ns(impulse.size())) , in_processor_(config) , out_processor_(config) { } CorrelationLatencyEstimator::~CorrelationLatencyEstimator() { queue_in_.push(nullptr); if (thread_.joinable()) { thread_.join(); } } void CorrelationLatencyEstimator::add_output(FramePtr frame) { queue_out_.push(std::move(frame)); } void CorrelationLatencyEstimator::add_input(FramePtr frame) { queue_in_.push(std::move(frame)); } void CorrelationLatencyEstimator::run_() { Timestamp in_peak, out_peak; double in_peak_ts = 0, out_peak_ts = 0; while (true) { while (auto out_frame = queue_out_.try_pop()) { if (const auto tmp_out_peak = out_processor_(*out_frame, true, 0)) { causality_timeout_counter_ = tmp_out_peak.hw + causality_timeout_lim_; out_peak = tmp_out_peak; out_peak_ts = tmp_out_peak.hw; } } if (out_peak_ts < in_peak_ts) { report_(out_peak, in_peak); out_peak_ts = in_peak_ts = 0; } do { auto in_frame = queue_in_.wait_pop(); if (!in_frame) { return; } if (const auto tmp_in_peak = in_processor_(*in_frame, false, causality_timeout_counter_)) { in_peak = tmp_in_peak; in_peak_ts = tmp_in_peak.hw; } } while (!queue_in_.empty()); if (out_peak_ts < in_peak_ts) { report_(out_peak, in_peak); out_peak_ts = in_peak_ts = 0; } } } void CorrelationLatencyEstimator::report_(Timestamp out_peak, Timestamp in_peak) { const double impulse_duration = config_.frames_to_ns(impulse.size()); LatencyReport rep; rep.sw_hw = (in_peak.sw_hw - out_peak.sw_hw - impulse_duration) / Millisecond; rep.hw = (in_peak.hw - out_peak.hw - impulse_duration) / Millisecond; rep.hw_avg = hw_avg_(rep.hw); reporter_.report(rep); } CorrelationLatencyEstimator::Processor::Processor(const Config& config) : config_(config) , mmax_(config_.impulse_peak_detection_width) , mmavg_(config_.impulse_peak_detection_width) { std::fill(buff_.begin(), buff_.end(), 0.f); hw_search_start_ = 0; hw_search_len_ = double(config_.impulse_interval * Second) - config_.frames_to_ns(impulse.size() * 2); } CorrelationLatencyEstimator::Timestamp CorrelationLatencyEstimator::Processor::operator()( const Frame& frame, const bool plain_simple, double skip_until_ts) { // Frames should be smaller than buffer. if (frame.size() / config_.channel_count > buff_len_) { return {}; } // If one more frame won't fit into buff_ -- compute. Timestamp result; if (frame.size() / config_.channel_count > buff_len_ - inter_buff_i_) { if (plain_simple) { result = seek_max_(buff_.data(), buff_.data(), inter_buff_i_, skip_until_ts); } else { result = seek_correlation_( buff_.data(), buff_.data(), inter_buff_i_, skip_until_ts); } inter_buff_i_ = 0; } // Update the timestamp of the beginning of the buffer. buff_begin_ts_ = compute_ts_(frame, inter_buff_i_); // Fill buff till new samples fit inside buff_. // Take only left channel. size_t samples_in_a_frame = 0; for (size_t i = 0; i < frame.size(); i += config_.channel_count, samples_in_a_frame++) { buff_[inter_buff_i_ + samples_in_a_frame] = ((float)frame[i] / MaxSample); } inter_buff_i_ += samples_in_a_frame; intra_buff_counter_ += samples_in_a_frame; return result; } CorrelationLatencyEstimator::Timestamp CorrelationLatencyEstimator::Processor::seek_correlation_( const float* from, float* to, const size_t sz, double skip_until_ts) { // FFT convolution optimal_filter_.perform(from, to, sz); // Abs(conv_out) std::transform(to, to + sz, to, [](const float x) { return std::abs(x); }); Timestamp res; for (size_t i = 0; i < sz; ++i) { const double cur_ts = (buff_begin_ts_.hw + config_.frames_to_ns(i)); if (skip_until_ts > cur_ts) { hw_search_start_ = skip_until_ts; hw_search_activated_ = false; } else if ((hw_search_start_ + hw_search_len_) > cur_ts) { hw_search_activated_ = true; const float movmax = mmax_(to[i]); const float movavg = mmavg_(movmax); if (movmax > movavg * config_.impulse_avg_2_peak_ration_threshold && movmax > max_corr_val_) { max_corr_val_ = movmax; const double idx_2_ns = config_.frames_to_ns(i); max_corr_ts_.sw_hw = buff_begin_ts_.sw_hw + idx_2_ns; max_corr_ts_.hw = buff_begin_ts_.hw + idx_2_ns; } } else if (hw_search_activated_) { hw_search_activated_ = false; max_corr_val_ = 0; res = max_corr_ts_; max_corr_ts_ = { 0, 0 }; return res; } } return res; } CorrelationLatencyEstimator::Timestamp CorrelationLatencyEstimator::Processor::seek_max_( const float* from, float* to, const size_t sz, double skip_until_ts) { Timestamp res; for (size_t i = 0; i < sz; ++i) { if (!max_timeout_activated_) { if (std::abs(from[i]) > 1e-5f && skip_until_ts < (buff_begin_ts_.hw + config_.frames_to_ns(i))) { const double idx_2_ns = config_.frames_to_ns(i); max_timeout_counter_ = 0; max_timeout_activated_ = true; res.sw_hw = buff_begin_ts_.sw_hw + idx_2_ns; res.hw = buff_begin_ts_.hw + idx_2_ns; to[i] = 1.f; } else { to[i] = 0.f; } } else { to[i] = 0.f; max_timeout_counter_++; if (max_timeout_counter_ > buff_len_ * 1.5) { max_timeout_activated_ = false; } } } return res; } CorrelationLatencyEstimator::Timestamp CorrelationLatencyEstimator::Processor::compute_ts_( const Frame& frame, size_t frame_offset) const { const double frame_offset_ns = config_.frames_to_ns(frame_offset); Timestamp ts; ts.sw_hw = (double)frame.sw_frame_time() - frame_offset_ns; ts.hw = (double)frame.hw_frame_time() - frame_offset_ns; return ts; } } // namespace signal_estimator signal-estimator-0.0.9/src/base/processing/CorrelationLatencyEstimator.hpp000066400000000000000000000053641452044147100270730ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/Frame.hpp" #include "core/FrameQueue.hpp" #include "processing/FFTConvolution.hpp" #include "processing/IEstimator.hpp" #include "processing/Impulse.hpp" #include "processing/MovAvg.hpp" #include "processing/MovMax.hpp" #include "reports/IReporter.hpp" #include #include #include namespace signal_estimator { class CorrelationLatencyEstimator : public IEstimator { public: CorrelationLatencyEstimator(const Config& config, IReporter& reporter); ~CorrelationLatencyEstimator(); CorrelationLatencyEstimator(const CorrelationLatencyEstimator&) = delete; CorrelationLatencyEstimator& operator=(const CorrelationLatencyEstimator&) = delete; void add_output(FramePtr frame) override; void add_input(FramePtr frame) override; private: struct Timestamp { double sw_hw = 0; double hw = 0; explicit operator bool() const { return sw_hw > 0 || hw > 0; } }; class Processor { public: Processor(const Config& config); Timestamp operator()( const Frame& frame, const bool plain_simple, double skip_until_ts); private: Timestamp seek_correlation_( const float* from, float* to, const size_t sz, double skip_until_ts); Timestamp seek_max_( const float* from, float* to, const size_t sz, double skip_until_ts); // Return what time stamp was frame_offset samples before frame's timestamp. // frame_offset Frame // |.......................|*********| Timestamp compute_ts_(const Frame& frame, size_t frame_offset) const; const Config& config_; static constexpr size_t buff_len_ = impulse.size(); FFTConvolution optimal_filter_; MovMax mmax_; MovAvg mmavg_; std::array buff_; Timestamp buff_begin_ts_; size_t inter_buff_i_ = 0; size_t intra_buff_counter_ = 0; double hw_search_start_ = 0; double hw_search_len_ = 0; bool hw_search_activated_ = false; Timestamp max_corr_ts_; float max_corr_val_ = 0; bool max_timeout_activated_ = false; size_t max_timeout_counter_ = 0; }; void run_(); void report_(Timestamp out_peak, Timestamp in_peak); const Config& config_; IReporter& reporter_; MovAvg hw_avg_; FrameQueue queue_in_; FrameQueue queue_out_; std::thread thread_; const double causality_timeout_lim_; double causality_timeout_counter_ = 0; Processor in_processor_, out_processor_; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/processing/FFTConvolution.hpp000066400000000000000000000072051452044147100242550ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include #include #include #include #include #include namespace signal_estimator { template & taps_re> class FFTConvolution { public: FFTConvolution() : ksfft_state_fwd_(kiss_fft_alloc(fft_len, 0, 0, 0)) , ksfft_state_inv_(kiss_fft_alloc(fft_len, 1, 0, 0)) { std::array taps = {}; std::transform( taps_re.rbegin(), taps_re.rend(), taps.begin(), [](float x) -> kiss_fft_cpx { return kiss_fft_cpx { x, 0.f }; }); std::fill(full_input_buf.begin(), full_input_buf.end(), kiss_fft_cpx { 0, 0 }); std::fill(ftaps.begin(), ftaps.end(), kiss_fft_cpx { 0, 0 }); std::fill(fft_out.begin(), fft_out.end(), kiss_fft_cpx { 0, 0 }); std::fill(fir_tail.begin(), fir_tail.end(), kiss_fft_cpx { 0, 0 }); kiss_fft(ksfft_state_fwd_, taps.data(), ftaps.data()); } ~FFTConvolution() { free(ksfft_state_fwd_); free(ksfft_state_inv_); } FFTConvolution(const FFTConvolution&) = delete; FFTConvolution& operator=(const FFTConvolution&) = delete; void perform(const float* input_buf, float* out_buf, const size_t sz) { assert(sz <= frame_len); std::transform(input_buf, input_buf + sz, full_input_buf.begin(), [](float x) -> kiss_fft_cpx { return kiss_fft_cpx { x, 0 }; }); std::fill( full_input_buf.begin() + sz, full_input_buf.end(), kiss_fft_cpx { 0.f, 0.f }); kiss_fft(ksfft_state_fwd_, full_input_buf.data(), fft_out.data()); for (auto pout = fft_out.begin(), ptaps = ftaps.begin(); pout != fft_out.end(); pout++, ptaps++) { *pout = multiply_(*pout, *ptaps); } std::fill( full_input_buf.begin(), full_input_buf.end(), kiss_fft_cpx { 0.f, 0.f }); kiss_fft(ksfft_state_inv_, fft_out.data(), full_input_buf.data()); std::transform(full_input_buf.begin(), full_input_buf.begin() + sz, out_buf, [](kiss_fft_cpx& y) -> float { return y.r / float(fft_len); }); const auto fir_tail_len_runtime_const = std::min(fir_tail_len, sz); for (size_t i = 0; i < fir_tail_len_runtime_const; i++) out_buf[i] += fir_tail[i].r / float(fft_len); if (sz < fir_tail_len) { std::copy(fir_tail.begin() + sz, fir_tail.end(), fir_tail.begin()); std::fill(fir_tail.begin() + (fir_tail_len - sz), fir_tail.end(), kiss_fft_cpx { 0, 0 }); for (size_t i = 0; i < fir_tail_len; ++i) { fir_tail[i].r += full_input_buf[sz + i].r; fir_tail[i].i += full_input_buf[sz + i].i; } } else { std::copy(full_input_buf.begin() + sz, full_input_buf.begin() + sz + fir_tail_len, fir_tail.begin()); } } private: static kiss_fft_cpx multiply_(const kiss_fft_cpx& x, const kiss_fft_cpx& y) { return kiss_fft_cpx { x.r * y.r - x.i * y.i, x.r * y.i + x.i * y.r }; } kiss_fft_cfg ksfft_state_fwd_; kiss_fft_cfg ksfft_state_inv_; static constexpr size_t fir_tail_len = taps_len - 1; static constexpr size_t fft_len = frame_len + fir_tail_len + 1; std::array full_input_buf = {}; std::array ftaps = {}; std::array fft_out = {}; std::array fir_tail = {}; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/processing/IEstimator.hpp000066400000000000000000000007021452044147100234510ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/Frame.hpp" namespace signal_estimator { // estimate and report some signal characteristic class IEstimator { public: virtual ~IEstimator() = default; // called from output thread virtual void add_output(FramePtr frame) = 0; // called from input thread virtual void add_input(FramePtr frame) = 0; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/processing/IGenerator.hpp000066400000000000000000000005331452044147100234320ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/Frame.hpp" #include #include namespace signal_estimator { // generate output signal class IGenerator { public: virtual ~IGenerator() = default; virtual void generate(Frame& frame) = 0; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/processing/IODelayEstimator.cpp000066400000000000000000000026141452044147100245460ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "processing/IODelayEstimator.hpp" #include "core/Time.hpp" #include "reports/IReporter.hpp" namespace signal_estimator { IODelayEstimator::IODelayEstimator( const Config& config, const DevInfo& dev_info, IReporter& reporter) : config_(config) , dev_info_(dev_info) , thread_(&IODelayEstimator::run_, this) , sw_delay_avg_(config.io_delay_window) , hw_delay_avg_(config.io_delay_window) , reporter_(reporter) { } IODelayEstimator::~IODelayEstimator() { queue_.push(nullptr); if (thread_.joinable()) { thread_.join(); } } void IODelayEstimator::add_output(FramePtr frame) { if (dev_info_.dir == Dir::Output) { queue_.push(std::move(frame)); } } void IODelayEstimator::add_input(FramePtr frame) { if (dev_info_.dir == Dir::Input) { queue_.push(std::move(frame)); } } void IODelayEstimator::run_() { while (auto frame = queue_.wait_pop()) { sw_delay_avg_.add((double)frame->sw_delay() / Millisecond); hw_delay_avg_.add((double)frame->hw_delay() / Millisecond); if (sw_delay_avg_.is_full() && report_limiter_.allow() > 0) { IODelayReport rep; rep.sw_avg = sw_delay_avg_.get(); rep.hw_avg = hw_delay_avg_.get(); reporter_.report(rep); } } } } // namespace signal_estimator signal-estimator-0.0.9/src/base/processing/IODelayEstimator.hpp000066400000000000000000000021671452044147100245560ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/Config.hpp" #include "core/FrameQueue.hpp" #include "core/RateLimiter.hpp" #include "core/Time.hpp" #include "processing/IEstimator.hpp" #include "processing/MovAvg.hpp" #include "processing/MovPercentile.hpp" #include "reports/IReporter.hpp" #include #include namespace signal_estimator { // calculates jitter of frame timestamps class IODelayEstimator : public IEstimator { public: IODelayEstimator(const Config& config, const DevInfo& dev_info, IReporter& reporter); ~IODelayEstimator() override; IODelayEstimator(const IODelayEstimator&) = delete; IODelayEstimator& operator=(const IODelayEstimator&) = delete; void add_output(FramePtr frame) override; void add_input(FramePtr frame) override; private: void run_(); const Config config_; const DevInfo dev_info_; FrameQueue queue_; std::thread thread_; MovAvg sw_delay_avg_; MovAvg hw_delay_avg_; RateLimiter report_limiter_ { 2 }; IReporter& reporter_; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/processing/IOJitterEstimator.cpp000066400000000000000000000042521452044147100247510ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "processing/IOJitterEstimator.hpp" #include "core/Time.hpp" #include "reports/IReporter.hpp" namespace signal_estimator { IOJitterEstimator::JitterStats::JitterStats(const Config& config, const DevInfo& dev_info) : dev_avg(config.io_jitter_window) , dev_per(config.io_jitter_window, config.io_jitter_percentile / 100.) , ideal_period((double)config.samples_to_ns(dev_info.period_size) / Millisecond) { } void IOJitterEstimator::JitterStats::update(nanoseconds_t next_ts) { if (prev_ts) { // delta between two frames const double delta = double(next_ts - prev_ts) / Millisecond; // deviation of delta from ideal period const double deviation = std::abs(delta - ideal_period); // statistics dev_avg.add(deviation); dev_per.add(deviation); } prev_ts = next_ts; } IOJitterEstimator::IOJitterEstimator( const Config& config, const DevInfo& dev_info, IReporter& reporter) : config_(config) , dev_info_(dev_info) , thread_(&IOJitterEstimator::run_, this) , sw_stats_(config, dev_info) , hw_stats_(config, dev_info) , reporter_(reporter) { } IOJitterEstimator::~IOJitterEstimator() { queue_.push(nullptr); if (thread_.joinable()) { thread_.join(); } } void IOJitterEstimator::add_output(FramePtr frame) { if (dev_info_.dir == Dir::Output) { queue_.push(std::move(frame)); } } void IOJitterEstimator::add_input(FramePtr frame) { if (dev_info_.dir == Dir::Input) { queue_.push(std::move(frame)); } } void IOJitterEstimator::run_() { while (auto frame = queue_.wait_pop()) { sw_stats_.update(frame->sw_frame_time()); hw_stats_.update(frame->hw_frame_time()); if (sw_stats_.dev_avg.is_full() && report_limiter_.allow() > 0) { IOJitterReport rep; rep.swdev_avg = sw_stats_.dev_avg.get(); rep.swdev_per = sw_stats_.dev_per.get(); rep.hwdev_avg = hw_stats_.dev_avg.get(); rep.hwdev_per = hw_stats_.dev_per.get(); reporter_.report(rep); } } } } // namespace signal_estimator signal-estimator-0.0.9/src/base/processing/IOJitterEstimator.hpp000066400000000000000000000031311452044147100247510ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/Config.hpp" #include "core/FrameQueue.hpp" #include "core/RateLimiter.hpp" #include "core/Time.hpp" #include "processing/IEstimator.hpp" #include "processing/MovAvg.hpp" #include "processing/MovPercentile.hpp" #include "reports/IReporter.hpp" #include #include namespace signal_estimator { // calculates jitter of frame timestamps class IOJitterEstimator : public IEstimator { public: IOJitterEstimator(const Config& config, const DevInfo& dev_info, IReporter& reporter); ~IOJitterEstimator() override; IOJitterEstimator(const IOJitterEstimator&) = delete; IOJitterEstimator& operator=(const IOJitterEstimator&) = delete; void add_output(FramePtr frame) override; void add_input(FramePtr frame) override; private: void run_(); struct JitterStats { // previous frame time nanoseconds_t prev_ts { 0 }; // average deviation of frame time delta from ideal period MovAvg dev_avg; // Nth percentile of deviation of frame time delta from ideal period MovPercentile dev_per; // ideal period const double ideal_period; JitterStats(const Config& config, const DevInfo& dev_info); void update(nanoseconds_t next_ts); }; const Config config_; const DevInfo dev_info_; FrameQueue queue_; std::thread thread_; JitterStats sw_stats_; JitterStats hw_stats_; RateLimiter report_limiter_ { 2 }; IReporter& reporter_; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/processing/Impulse.cpp000066400000000000000000010067361452044147100230200ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT // Generated by generate_impulse.py. DO NOT EDIT! #include "processing/Impulse.hpp" const std::array impulse = { (float)0.0012395095228391422, (float)0.00413211315296901, (float)-0.01845988009201055, (float)-0.018065617863618846, (float)0.0017677490268725345, (float)-0.0008751016190447923, (float)-0.009428100031166049, (float)-0.0005409462836304911, (float)0.0037745381668783497, (float)-0.004017410344996493, (float)-0.00755643424548805, (float)-0.0017595484462735414, (float)0.014470797167747376, (float)0.02372093704812063, (float)0.000990225315134192, (float)-0.0185676705717511, (float)0.0042298478187250245, (float)0.01607513669510567, (float)-0.016877667313884414, (float)-0.0210524110733704, (float)0.02846720660749127, (float)0.05096914459278386, (float)0.018350815719874857, (float)-0.01661726879941145, (float)-0.020941465969699792, (float)0.0005851048771277117, (float)0.009283930264630709, (float)-0.02686374024052426, (float)-0.04280828380428273, (float)0.020772429071831976, (float)0.06081514549245125, (float)-0.011133163451871136, (float)-0.0848048794345409, (float)-0.06252307896050258, (float)-0.01945639847835392, (float)-0.015278462662747854, (float)0.00020529883241623, (float)0.043748198271567375, (float)0.061435570200440555, (float)0.041943503986056244, (float)0.041416519440967775, (float)0.06171673917914706, (float)0.012911144828557323, (float)-0.08980656319123512, (float)-0.08170909042306163, (float)0.022782403040322915, (float)0.007943470109845354, (float)-0.09258251993785496, (float)-0.04864890200723196, (float)0.07054371178485469, (float)0.06402258216626827, (float)0.018791370695730378, (float)0.03024118208821112, (float)-0.01700101266013, (float)-0.08693024496776579, (float)-0.01864879831001164, (float)0.08888799091833001, (float)0.08336081804833918, (float)0.0644408534059644, (float)0.09294957382065146, (float)0.04423068235802279, (float)-0.06757038317145099, (float)-0.07449424336068063, (float)0.020214512513188596, (float)0.06448105797030587, (float)0.030695882076035318, (float)-0.013194754893739445, (float)-0.08981970553202141, (float)-0.18981620247786385, (float)-0.14233290104252133, (float)0.053070592846926244, (float)0.09359371215483826, (float)-0.07335204043767898, (float)-0.12915932404884534, (float)-0.036513741825761524, (float)-0.02231543232404934, (float)-0.005688316673885352, (float)0.1170240203808939, (float)0.1372953541446825, (float)0.06576530525683101, (float)0.10581047408601661, (float)0.07006826451749631, (float)-0.14884803946395986, (float)-0.16610896968358863, (float)0.03605337480476827, (float)0.004475249680455687, (float)-0.1739838382947014, (float)-0.09370470586158977, (float)0.11680660663882386, (float)0.20301407627925508, (float)0.1970301428865048, (float)0.03604925996540622, (float)-0.24712152793134456, (float)-0.2721428703525281, (float)0.004312744862414692, (float)0.13602962280818004, (float)-0.0037944146557555, (float)-0.11591265831477907, (float)-0.03181527188445971, (float)0.17841635634326533, (float)0.3409104782339364, (float)0.31598815237861294, (float)0.18232385177950272, (float)0.0796575330842648, (float)0.009718552420672386, (float)-0.011544961200100661, (float)-0.017164135243394035, (float)-0.17093972462328294, (float)-0.34957083321881044, (float)-0.23842118716550803, (float)-0.017898935916998274, (float)-0.04796322163896177, (float)-0.13548244671787985, (float)-0.013662427062508874, (float)0.09805308948566081, (float)0.0009388268270844657, (float)-0.1501785941477209, (float)-0.15823491400526238, (float)0.030038287578569495, (float)0.23882624630089508, (float)0.18751518841635165, (float)-0.044872839795016335, (float)-0.1369776483220222, (float)-0.08583161173812351, (float)-0.03591586456268455, (float)0.027387237581836147, (float)0.03470721756334962, (float)-0.022479133615774038, (float)0.10481602692012595, (float)0.29581032587671086, (float)0.07742080686596757, (float)-0.3420318797227336, (float)-0.30732896596633735, (float)0.07697329463980883, (float)0.23277977395905355, (float)0.11142133409620017, (float)-0.021793051361738487, (float)-0.10512665351797904, (float)-0.11883843219886782, (float)-0.025443626789503387, (float)0.07776218627855729, (float)0.09821449799678278, (float)0.07024225817174998, (float)0.047594115928570074, (float)0.049946245584280215, (float)0.08674369377964924, (float)0.15648327531737322, (float)0.2118145422736681, (float)0.15771255265877504, (float)0.012775974215237493, (float)-0.05160666079381475, (float)-0.03251017568579274, (float)-0.13931153769287874, (float)-0.34678991444040436, (float)-0.35224248940325165, (float)-0.05969757687866119, (float)0.23415677130732046, (float)0.16375036208833993, (float)-0.1809339365217693, (float)-0.21471002021774113, (float)0.1815111896297302, (float)0.26016976719615315, (float)-0.181658829957373, (float)-0.25020477627541027, (float)0.2472976544700635, (float)0.3457752455243554, (float)-0.10122732563505805, (float)-0.22780086333287888, (float)0.017975170521524888, (float)-0.011071345785684795, (float)-0.27301778965124474, (float)-0.33206859757590523, (float)-0.17903564975520866, (float)-0.022379283275857028, (float)0.0104514391811846, (float)-0.018971241476418637, (float)0.11765017863681333, (float)0.2883425903401867, (float)0.10737685373903051, (float)-0.1314027420499203, (float)0.11057450462902092, (float)0.4333747541191322, (float)0.2619635357317731, (float)-0.007494957688134521, (float)0.08412545743097545, (float)0.22210383149833757, (float)0.10977094306996706, (float)-0.1160902157497729, (float)-0.3001607870919959, (float)-0.29614166987332596, (float)-0.05053991047567967, (float)0.14479116009554918, (float)0.08167497471659461, (float)-0.041331257310327725, (float)-0.07722999766603313, (float)-0.06267647457355124, (float)0.035085591706971515, (float)0.12909260592371719, (float)0.029275140932112705, (float)-0.11811510946508455, (float)-0.035802039103526945, (float)0.17748523159964588, (float)0.24495438518763182, (float)0.08406138828871947, (float)-0.17262866965409004, (float)-0.2773934558724011, (float)-0.18961360941182734, (float)-0.19430632224954555, (float)-0.3177674056398776, (float)-0.22766782405121375, (float)-0.013019985910702966, (float)-0.03657158523114724, (float)-0.0764380624675053, (float)0.15754888977640766, (float)0.2573593633420277, (float)0.02029183214465843, (float)-0.010450028397307203, (float)0.26709756277323876, (float)0.2652125972318825, (float)-0.010282429346556553, (float)0.00030448661801690824, (float)0.21712139201716013, (float)0.1494825479851131, (float)-0.14554039578035213, (float)-0.2873714092297901, (float)-0.1620705650788834, (float)0.10470751895551952, (float)0.23751017783862702, (float)0.014868212153566741, (float)-0.30564987380479136, (float)-0.2676954586199313, (float)0.06798344620231847, (float)0.30005981681348287, (float)0.3008632645017335, (float)0.17395132649288467, (float)0.03750698041239883, (float)0.014441150889721664, (float)0.036955247647070526, (float)-0.08830169685263001, (float)-0.21064508168286808, (float)-0.04690532229335289, (float)0.176996328406443, (float)0.07506968306306834, (float)-0.17863082990443127, (float)-0.19534493549170043, (float)-0.031447908410769235, (float)0.016890476543795285, (float)-0.09150246850646572, (float)-0.1507253442201431, (float)-0.036887297296639164, (float)0.10093522489701379, (float)0.05568647467789743, (float)-0.0956808818099133, (float)-0.11773266526066443, (float)0.0014481053229436077, (float)0.07846695618293019, (float)0.02389394750630228, (float)-0.08704001846694827, (float)-0.14362058878852288, (float)-0.1390957824325656, (float)-0.13979026045433504, (float)-0.10934104035763627, (float)0.028434205618006896, (float)0.19771661586219968, (float)0.3035441157955888, (float)0.32030953064760875, (float)0.1344276763952692, (float)-0.20323534020449957, (float)-0.25612018104710377, (float)0.110794722599279, (float)0.36350124013756957, (float)0.2027033681171795, (float)0.01380755367785281, (float)0.07696376246774098, (float)0.1923249240021469, (float)0.1492133257558178, (float)-0.028325281452311085, (float)-0.17869709504124895, (float)-0.19012417759828237, (float)-0.1697804323358011, (float)-0.1973267641815637, (float)-0.12375177596788309, (float)0.02741508435169008, (float)0.04505826160656635, (float)0.033087157619153415, (float)0.10355343397600686, (float)-0.024778561583554556, (float)-0.33896139734518593, (float)-0.3648923698588274, (float)-0.08900034957729702, (float)0.0905528256895193, (float)0.13858346048924125, (float)0.1701577043681033, (float)0.14891030557971055, (float)0.15707270005384322, (float)0.1796756317042902, (float)0.008096846349468731, (float)-0.1922986679138795, (float)-0.14871780967662684, (float)-0.10523699326888027, (float)-0.1897944165586842, (float)-0.06952795287863228, (float)0.1816901232006098, (float)0.15873069777841725, (float)-0.021493710626382043, (float)-0.0583570630124501, (float)0.02031171026278021, (float)0.15835779360369207, (float)0.22824880361081681, (float)0.034702305399041886, (float)-0.14130234161577152, (float)0.0340679970968665, (float)0.20452119607377528, (float)0.0765730167489529, (float)-0.045665479915142596, (float)-0.10087699742600355, (float)-0.2778218689823291, (float)-0.30858942021663127, (float)-0.0010590564877815023, (float)0.27657108266169256, (float)0.28151405197106594, (float)0.11660777690128271, (float)-0.10062317153483238, (float)-0.16519572950831793, (float)-0.017792115912520785, (float)0.025804245216586696, (float)-0.10278334185899776, (float)-0.13871322040123557, (float)-0.11833472489128743, (float)-0.08630001241462014, (float)0.12947638571353873, (float)0.2214159520193925, (float)-0.10920644125038076, (float)-0.22283695843724874, (float)0.22441520412125496, (float)0.4060911110455348, (float)0.04406148799886686, (float)-0.07579570131361213, (float)0.08927731879848966, (float)-0.11056979386662427, (float)-0.40499115883574427, (float)-0.18273132174473714, (float)0.1749093464819708, (float)0.10620457590597726, (float)-0.0936216461831254, (float)-0.023067982527817405, (float)0.08116465774290185, (float)-0.03834236396085171, (float)-0.13020539605707665, (float)0.012418185695281516, (float)0.15783010701747835, (float)0.15127401618111386, (float)0.10267478635702183, (float)-0.02752297517699065, (float)-0.19531546212812334, (float)-0.05629735605103824, (float)0.22128561676813083, (float)0.03364666797271283, (float)-0.33504918545148, (float)-0.1466926315246489, (float)0.2709766021005783, (float)0.2643453119190607, (float)0.0964153948502923, (float)0.06020489121548987, (float)-0.06776856962011718, (float)-0.18080112235277937, (float)-0.0627102939615025, (float)0.03536337652623972, (float)0.061097250592269656, (float)0.19156740043435447, (float)0.15227090790587036, (float)-0.14745815492537875, (float)-0.20459854720816156, (float)0.004252253207351354, (float)-0.0009431785650444492, (float)-0.15153893989957842, (float)-0.16107244369298113, (float)-0.16358244172088227, (float)-0.2051803857548493, (float)-0.1338815381201575, (float)-0.012462917639906736, (float)0.10556150986727185, (float)0.2085958601604139, (float)0.09311881720919828, (float)-0.12136539279283606, (float)0.033058629459404396, (float)0.37402991501360683, (float)0.2663504564888995, (float)-0.14791276801803024, (float)-0.20943903073526218, (float)0.09494903267581033, (float)0.2569837177690399, (float)0.1524366517980374, (float)0.10888658178575004, (float)0.2113883520750797, (float)0.13334425432604924, (float)-0.17401680737057346, (float)-0.3311965875289473, (float)-0.27080404081363785, (float)-0.1975991507877363, (float)-0.004206753051675224, (float)0.2485893887568611, (float)0.11365167186089346, (float)-0.2576341085154012, (float)-0.290536245513927, (float)-0.10990833223845475, (float)-0.03552493670551804, (float)0.09404935564801484, (float)0.20412943345244816, (float)0.10260685833499951, (float)0.09587987884752845, (float)0.14757299757420253, (float)-0.13009947834833857, (float)-0.2518878429965872, (float)0.18411905736958434, (float)0.32939358746262437, (float)-0.1180374298923575, (float)-0.26249622137531237, (float)-0.07059340949149498, (float)-0.17936658646907358, (float)-0.27042449388230333, (float)-0.06162528867775805, (float)0.0055963168512018786, (float)0.06171324484975424, (float)0.3534770423720227, (float)0.28767523298295156, (float)-0.1408955408063925, (float)-0.10039417973538423, (float)0.2756556262900684, (float)0.3028490797000173, (float)0.1145862557049216, (float)-0.06903451857645458, (float)-0.2765284758870392, (float)-0.19497988998315685, (float)0.08189262341654102, (float)0.003813264946195743, (float)-0.13197488123926485, (float)0.09307468076762158, (float)0.11332235020330048, (float)-0.16434284989431291, (float)0.0038090461467753345, (float)0.397742703944525, (float)0.3029014287769494, (float)0.03678021624800556, (float)-0.05388347794463382, (float)-0.2617837752978848, (float)-0.3796306608607813, (float)-0.0676889522987246, (float)0.15588413974931783, (float)-0.06514856410821912, (float)-0.2515627586367362, (float)-0.11347213853494442, (float)0.09836547572026273, (float)0.13411321610999677, (float)-0.02384324265170594, (float)-0.10833205153541263, (float)0.02379041195905963, (float)0.009188458896475892, (float)-0.22742601634874035, (float)-0.19434910403256275, (float)0.03759254107863644, (float)0.0006826170846442738, (float)-0.062520679397715, (float)0.08805193844524968, (float)0.09256528862377546, (float)0.06936432037782646, (float)0.3326978171155192, (float)0.3200642765830155, (float)-0.17603184531380583, (float)-0.2790944291234252, (float)0.1295056263301156, (float)0.2200417692633124, (float)0.047609883044598296, (float)0.13264258750744062, (float)0.14463965192375328, (float)-0.16644276559061552, (float)-0.2735220345795851, (float)0.024588316017859258, (float)0.2911906587603987, (float)0.252645397053314, (float)0.0022655076288129734, (float)-0.19875879499564852, (float)-0.1503394341140557, (float)-0.02175444973808529, (float)-0.06645706920281587, (float)-0.16985959408176315, (float)-0.16786307839971484, (float)-0.09356598608397003, (float)0.08535483232207489, (float)0.31619138469672714, (float)0.3173925714383525, (float)0.08972300079983209, (float)-0.033059156208868755, (float)-0.02392077178457691, (float)-0.15133544128289914, (float)-0.37869481135572725, (float)-0.368457545227665, (float)-0.07170730024609204, (float)0.12201475503623332, (float)0.03112697585165875, (float)-0.001399610139889098, (float)0.12041363391932747, (float)-0.02743232996469276, (float)-0.3866805157339561, (float)-0.38308327613957815, (float)-0.10543162743596068, (float)-0.03967649134624542, (float)-0.04351532094448618, (float)0.08992013818311238, (float)0.1349062682304508, (float)0.18582416442264318, (float)0.4398156904697219, (float)0.5, (float)0.22694187199811272, (float)0.12130741354241326, (float)0.19777233703880465, (float)0.09598183472036724, (float)0.015082468330805225, (float)0.1028882162734242, (float)0.044864481759207916, (float)-0.07185329932480128, (float)0.016315560127471238, (float)0.008316967366524037, (float)-0.21056620328874598, (float)-0.22094708748053324, (float)-0.03601016783890217, (float)-0.02479443183376998, (float)-0.12235724080728912, (float)-0.14002598525369642, (float)-0.09221501899062477, (float)0.039569911670972645, (float)0.11075362649865213, (float)-0.10147972260466347, (float)-0.35353264822316804, (float)-0.33448974023859296, (float)-0.17566505873926783, (float)0.011055607370958285, (float)0.15512073521534028, (float)-0.001130981985102033, (float)-0.2201742837334941, (float)0.004013648804663061, (float)0.2550939637480226, (float)0.012212175831511074, (float)-0.1276644648277817, (float)0.14890226431209938, (float)0.11718948454136097, (float)-0.2033321836923125, (float)-0.05200557945990932, (float)0.2871193186378175, (float)0.21551648799599912, (float)0.14107621698934655, (float)0.2805409830313088, (float)0.16028972743361042, (float)-0.054289411418762056, (float)0.08716673460796305, (float)0.19886277237674957, (float)-0.028270010463558166, (float)-0.18083014229206124, (float)-0.13920934247992287, (float)-0.1448493181374638, (float)-0.09979430001597761, (float)0.01655450884718545, (float)-0.021738635732212182, (float)-0.06983672142390421, (float)0.04143994333852216, (float)0.05192841150984551, (float)-0.03875265394473924, (float)0.06289456408440051, (float)0.1877063989952608, (float)0.12608990248622795, (float)0.12187378442645164, (float)0.1341842714082368, (float)-0.11883351534231071, (float)-0.3138884782037062, (float)-0.16483433051449958, (float)-0.12534678969796972, (float)-0.3116641241618594, (float)-0.2013275255101716, (float)0.11089311074178461, (float)0.11688656504712291, (float)0.004655134789863417, (float)0.028193162242509614, (float)-0.09266600300493952, (float)-0.242789022236979, (float)-0.018064392227590487, (float)0.20686379756726267, (float)-0.002153708432377435, (float)-0.184763056322701, (float)-0.012077809241812731, (float)0.16652198587522876, (float)0.2638535059591197, (float)0.34374126822609524, (float)0.09411777365628082, (float)-0.2977901906254247, (float)-0.16490978641386916, (float)0.1842632342921447, (float)0.035834881969805575, (float)-0.1282086493757006, (float)0.23862998947374187, (float)0.4029082295587616, (float)-0.020736650026710032, (float)-0.19193250664845413, (float)0.09474412593873965, (float)0.0969442201562847, (float)-0.13062256811173342, (float)-0.009283105019199267, (float)0.17314036562330712, (float)-0.018207881398297557, (float)-0.2204463446909441, (float)-0.1324018863561683, (float)0.0004563811879886052, (float)0.056756940744625825, (float)0.09746665431998087, (float)0.049038537690757125, (float)-0.08077686985520333, (float)-0.2075287457357351, (float)-0.3496220816686205, (float)-0.3828804588683086, (float)-0.17661233593244785, (float)0.004372757861714332, (float)-7.654237175271226e-05, (float)0.11767781763084463, (float)0.36984316226352765, (float)0.3616470879270277, (float)0.14841384676914943, (float)0.043149492514905505, (float)-0.045175473360875316, (float)-0.16618466964766365, (float)-0.12733266820861588, (float)-0.05839524142177494, (float)-0.07859833988512722, (float)0.09454216498733244, (float)0.31022604667231407, (float)0.044085379191040254, (float)-0.3660384547004127, (float)-0.25888423779220154, (float)0.020215701845417093, (float)0.004409667336399765, (float)0.09444738307903341, (float)0.4158706993044934, (float)0.3889330140282116, (float)0.023685136128814083, (float)-0.07759024958369459, (float)0.08461668419216219, (float)0.09008272660968604, (float)-0.03864583729900353, (float)-0.027676664192539127, (float)0.10408630013136463, (float)0.08576503684779516, (float)-0.18942682649790155, (float)-0.4239661286300022, (float)-0.3431726507737531, (float)-0.16231196638815945, (float)-0.11943413929570852, (float)-0.05020545025066677, (float)0.09989085297071082, (float)0.13399161912707647, (float)0.08808090661958205, (float)0.04307878462305798, (float)-0.10233560003673035, (float)-0.1761682640893376, (float)0.03522975628735686, (float)0.19883776193953076, (float)0.09734008254745521, (float)0.07120293509462537, (float)0.10818507399029607, (float)-0.13262373599689592, (float)-0.3283215499882783, (float)-0.07514532158968927, (float)0.19780393279420103, (float)0.15328671902011776, (float)0.14043729076090494, (float)0.2238482556110644, (float)0.10717817134412719, (float)-0.027356971721159605, (float)0.06918125093376845, (float)0.10724576938493882, (float)-0.03700442213465548, (float)-0.017047459339237136, (float)0.16383363342412757, (float)0.1095551295812867, (float)-0.15009483356222525, (float)-0.24078865108949396, (float)-0.13474797048302212, (float)-0.04670266474867481, (float)-0.005376769012173558, (float)-0.003885600596267385, (float)-0.10560213070147577, (float)-0.19425129755838427, (float)-0.15354812358601663, (float)-0.12576185067400303, (float)-0.07958119542975252, (float)0.20111873136272984, (float)0.3747557670939038, (float)0.0011416042007607718, (float)-0.3658122709364944, (float)-0.10639216721313788, (float)0.2180435438035883, (float)0.07597097718220439, (float)-0.07370503359467688, (float)-0.039963291353372225, (float)-0.1339274011185866, (float)-0.09633951299517246, (float)0.22144645532848656, (float)0.1869811328191991, (float)-0.1892200838536536, (float)-0.14606473665531497, (float)0.13521344347168582, (float)0.04708445530794332, (float)-0.04473813068783464, (float)0.15043650784871532, (float)0.150117662963277, (float)0.01810472357262238, (float)0.23580799191400748, (float)0.44308133679277795, (float)0.2129132454336212, (float)-0.013782094799124884, (float)0.05044479076306613, (float)0.04564145804124624, (float)-0.16343314873390158, (float)-0.3177681230084668, (float)-0.22910398059287337, (float)0.060121638131920375, (float)0.19645988089618283, (float)-0.09203841587397599, (float)-0.419838084382165, (float)-0.3548693620941228, (float)-0.1619641891473781, (float)-0.10962419569378587, (float)0.0015021152168852388, (float)0.1271531721374632, (float)-0.008588167854555991, (float)-0.20176368424100768, (float)-0.12346077041371242, (float)0.06665553184452569, (float)0.1370449049905812, (float)0.1558524031057662, (float)0.17872321399801389, (float)0.14404296331248514, (float)0.046700703781309576, (float)-0.09407585275274853, (float)-0.2188912468554667, (float)-0.1411004807725054, (float)0.1738077620396046, (float)0.36483941314789164, (float)0.17831446132624154, (float)-0.0309005265066552, (float)0.07264156693660917, (float)0.13011969915081553, (float)-0.12498996172361386, (float)-0.18281761575360167, (float)0.18576579689104478, (float)0.33034485348553955, (float)-0.0015459275986586158, (float)-0.21370900121055914, (float)-0.0853510793015053, (float)0.022210316871170626, (float)0.024093829535345505, (float)0.017392882716281883, (float)-0.06804945562345956, (float)-0.16761550135775502, (float)-0.14811096935803164, (float)-0.07399255219073587, (float)0.014508616701028286, (float)0.08289783787814997, (float)0.01013395766131255, (float)-0.05238225405080457, (float)0.0700822530128875, (float)0.07610422496832137, (float)-0.14539031188680895, (float)-0.1933744481392844, (float)-0.09882859059446869, (float)-0.1908798654136963, (float)-0.18548093637642415, (float)0.12004568099550975, (float)0.25013237683642686, (float)0.09672245706577086, (float)0.06173947012496669, (float)0.12598597555619126, (float)0.14084204440304368, (float)0.2136777802306788, (float)0.19762741049548713, (float)0.0009751227097664758, (float)-0.04182606931550201, (float)0.03450919061166663, (float)-0.07771634717826606, (float)-0.15465561909137884, (float)-0.11913375983671999, (float)-0.31916064670155525, (float)-0.4280202370813672, (float)-0.00877687171118855, (float)0.32537613374043683, (float)0.177207632152374, (float)0.0929366845684908, (float)0.10181167494212447, (float)-0.13948090285910233, (float)-0.2040256892449699, (float)0.06703812877925278, (float)0.07372495793341426, (float)-0.09504702494400112, (float)0.05191433188740734, (float)0.20347207395177322, (float)0.10402907518007048, (float)0.035018993095407965, (float)-0.06524639715205441, (float)-0.1957119310183877, (float)-0.00160091389974085, (float)0.1552914844732406, (float)-0.14477836952637368, (float)-0.19049437725942514, (float)0.28616091602537497, (float)0.3880539292689614, (float)0.07731083992026913, (float)0.05606875215171512, (float)0.038326999530131085, (float)-0.20800315089854074, (float)-0.06132023354090849, (float)0.24778828775907302, (float)-0.0363196018536444, (float)-0.3835512512153215, (float)-0.16442388940965189, (float)0.05791580550560558, (float)-0.008222208572431453, (float)-0.02100518237190016, (float)-0.10344702007881129, (float)-0.24717512371031714, (float)-0.028386970264240648, (float)0.20186200758113154, (float)-0.03502010297835816, (float)-0.15461032597506444, (float)0.10366077961641317, (float)0.039890117996257066, (float)-0.24901472952873432, (float)-0.05048825894762058, (float)0.24093311520493116, (float)0.007503505565234607, (float)-0.23342172812324274, (float)-0.03005902526130069, (float)0.18781599235768967, (float)0.1797550143043408, (float)0.16423038237196408, (float)0.17374989738317995, (float)0.1586702070666676, (float)0.1220218380726649, (float)-0.06967043426320382, (float)-0.3342779703972693, (float)-0.2907366355747587, (float)0.023257932097158523, (float)0.16944337450792626, (float)0.11526301914885773, (float)0.14041889062027335, (float)0.20678714609263507, (float)0.1440976491136252, (float)0.015811237330995834, (float)-0.0951763877027839, (float)-0.15821681498860252, (float)-0.05349040196652432, (float)0.14158679202325775, (float)0.09085373397370772, (float)-0.17241365165593225, (float)-0.2316917503156551, (float)-0.08662283871696884, (float)-0.04696662694452248, (float)-0.0013703727348841409, (float)0.15498550493950775, (float)0.024988656472576386, (float)-0.3455984060686783, (float)-0.24800739622060303, (float)0.21599764059269894, (float)0.17393622525525326, (float)-0.23343558478723012, (float)-0.1680798251672211, (float)0.15840567172307177, (float)0.12342073837225345, (float)0.05205248179033283, (float)0.2113931184726782, (float)0.07480498291202177, (float)-0.30830822635505095, (float)-0.21944424042011285, (float)0.1486478862031981, (float)0.10326505997833503, (float)-0.08436714346591634, (float)0.03521299072494118, (float)0.0707021334995255, (float)-0.1352661069823638, (float)-0.08405247781517237, (float)0.15850160772200822, (float)0.10661035242976213, (float)-0.02914182200667462, (float)0.0622437593293119, (float)0.05215859365806268, (float)-0.11880928783187825, (float)-0.03560224507849095, (float)0.15132960474033416, (float)0.05032349599805568, (float)-0.02434702670541641, (float)0.2186537250752142, (float)0.3543003060951013, (float)0.13439456557322957, (float)-0.10557385920553922, (float)-0.16064053324830654, (float)-0.10550968099337564, (float)-0.026122105930963598, (float)-0.03391412175861007, (float)-0.06440340882364286, (float)0.05287796763401763, (float)0.06813032880513376, (float)-0.21765331940383484, (float)-0.2768422225989356, (float)0.10516214267247553, (float)0.17757615168243407, (float)-0.26093307882061595, (float)-0.39464401206979594, (float)-0.05997329505601545, (float)0.10312805059411752, (float)0.06279850715080933, (float)0.1275156244911689, (float)0.07379096773093383, (float)-0.14508870824167366, (float)-0.07614733276379773, (float)0.21373707420198926, (float)0.16481974779054281, (float)-0.17644799196097544, (float)-0.2615240907616816, (float)0.004168217836757255, (float)0.2181254942375849, (float)0.1480511498621585, (float)-0.004226824611998207, (float)0.0335224643152804, (float)0.17129796872598532, (float)0.10426433243970319, (float)-0.1359357138190236, (float)-0.14926946566046717, (float)0.17218585718343887, (float)0.3427554050600389, (float)0.03723421195012781, (float)-0.23974666249647492, (float)-0.00023842666544760362, (float)0.2316219261485359, (float)-0.0687043066277178, (float)-0.30301995152390815, (float)-0.03245121087685461, (float)0.053486678247745265, (float)-0.29690450768574883, (float)-0.35029368087032564, (float)-0.054077556704286614, (float)0.02041682161469973, (float)0.07819857414960328, (float)0.37133314802748757, (float)0.3907640980971949, (float)0.10596317244897273, (float)0.05933427427531593, (float)0.07825737488661666, (float)-0.140336888792413, (float)-0.20351428359741663, (float)-0.068571850867288, (float)-0.12099115220878337, (float)-0.10150316224416432, (float)0.20279429276521185, (float)0.2863232568732546, (float)0.07984709494952164, (float)-0.006474768815827177, (float)-0.10120779867504436, (float)-0.24821732900426333, (float)-0.09164568108943615, (float)0.03741866878580157, (float)-0.24986255376511174, (float)-0.3173350874703107, (float)0.03903851757334042, (float)0.03893390684249758, (float)-0.20285912161888012, (float)0.01457152810378961, (float)0.22585330121864625, (float)-0.047952017502599587, (float)-0.15547914364867585, (float)0.08054155926369501, (float)0.10077298638523761, (float)0.06826848190312443, (float)0.24074782509399037, (float)0.1629890985731165, (float)-0.08197592070423042, (float)0.07692977150733539, (float)0.27931329416016126, (float)0.026718213147263022, (float)-0.1614689938065955, (float)0.06485492330808798, (float)0.2138353856096917, (float)0.089496469908924, (float)-0.003309334087124128, (float)-0.024080664462070984, (float)-0.10547035744789841, (float)-0.189149268472113, (float)-0.15724228637383808, (float)-0.005571932280781258, (float)0.11646157527641093, (float)0.10734019033078324, (float)0.08315293116343657, (float)0.03265385922479412, (float)-0.16648380689945544, (float)-0.23627471046651585, (float)-0.010631901197541366, (float)0.030603277533180595, (float)-0.17348866109759484, (float)-0.06958849597023026, (float)0.09076811902249808, (float)-0.20244644512592497, (float)-0.29399199958148553, (float)0.17815323091783158, (float)0.2437248263131312, (float)-0.2369671579169549, (float)-0.21692399152240938, (float)0.19798558726667673, (float)0.16080532370707212, (float)-0.02423797399748351, (float)0.1118548711641744, (float)0.2056150725914585, (float)0.17116023898716912, (float)0.18513877902883624, (float)0.0032742633979464474, (float)-0.20835994965389243, (float)0.019850994134318543, (float)0.25255137756684415, (float)0.03330209166455156, (float)-0.10592011122315644, (float)0.004649674288668006, (float)-0.16442538821693709, (float)-0.42628661516044924, (float)-0.3019217017846696, (float)-0.1039499053328137, (float)-0.05632993916891824, (float)0.13753667101976494, (float)0.3580854652574046, (float)0.3066229506446394, (float)0.17622176347071483, (float)0.08819683388987425, (float)-0.07012699431813739, (float)-0.13176390925003906, (float)0.012599676684398166, (float)0.1290391635103539, (float)0.0934493311153223, (float)-0.08849828131348732, (float)-0.32166690955199595, (float)-0.22100531839957083, (float)0.1901370509703862, (float)0.20189042550947248, (float)-0.19376161981422327, (float)-0.16281210696375478, (float)0.2536258876865652, (float)0.3067389720497353, (float)0.08115167946716957, (float)-0.001978635865946262, (float)-0.09751433649683512, (float)-0.22509175527263153, (float)-0.16289767837916908, (float)-0.1263510079630872, (float)-0.21219084254282086, (float)-0.07004374177000312, (float)0.1785972234842267, (float)0.11944526842655105, (float)-0.043277604782671446, (float)-0.05720220978895751, (float)-0.09952394732967057, (float)-0.04356054659336934, (float)0.265539002110816, (float)0.2824494282712391, (float)-0.18430145221865285, (float)-0.33418607289157815, (float)0.07644628548037413, (float)0.2445543746910055, (float)-0.047442327441059765, (float)-0.13997885624309436, (float)0.10631196143296007, (float)0.21763072726132832, (float)0.13498361184356153, (float)0.14606116523675738, (float)0.18228897599006505, (float)0.013629679626252717, (float)-0.20172866684853907, (float)-0.192565313238926, (float)-0.1108817201729051, (float)-0.18858702180792067, (float)-0.19688717180271198, (float)0.07625760268675412, (float)0.2997638363891945, (float)0.19357566098649348, (float)-0.040993903071295884, (float)-0.2338787855734646, (float)-0.3336092996111319, (float)-0.15279064727166466, (float)0.16086981531051583, (float)0.16721167289173602, (float)0.045004903832282894, (float)0.17476543583599374, (float)0.16596180103667207, (float)-0.17772170639486246, (float)-0.15983594631993983, (float)0.26374733700347924, (float)0.2490422085931641, (float)-0.0813172955503124, (float)0.03305816739533918, (float)0.26805805252537274, (float)0.0909503843673569, (float)-0.06289046061339898, (float)-0.004211260570768319, (float)-0.1505581055993026, (float)-0.3122191796982495, (float)-0.17486580704763022, (float)-0.1508749149858496, (float)-0.29107287489178313, (float)-0.09100528178745401, (float)0.17750435591491392, (float)0.0030021952243425207, (float)-0.1542059620177407, (float)0.077951844577516, (float)0.17715452984167016, (float)-0.04740870613675174, (float)-0.13835242629742905, (float)-0.016756230285929874, (float)0.041931399167884166, (float)-0.01855140074770237, (float)-0.11865862353269115, (float)-0.11775739382016763, (float)0.05506382813585771, (float)0.14705746589791654, (float)0.07059249497163347, (float)0.18467460958068035, (float)0.46077207348379745, (float)0.4081909227932569, (float)0.08347064545020622, (float)-0.043070574462053764, (float)0.06248670856411623, (float)0.1709072965785219, (float)0.13498125121864912, (float)-0.13104849702905422, (float)-0.35966888853050677, (float)-0.198319749081675, (float)0.03303370636654422, (float)-0.06232855471751301, (float)-0.13257342623459814, (float)0.050628968154763025, (float)0.10261137159458593, (float)0.017187030242382672, (float)0.08112044612720237, (float)0.001767404554840704, (float)-0.37097146015612115, (float)-0.4384176001716455, (float)-0.05707904782962394, (float)0.09821020200575352, (float)-0.14210939494889185, (float)-0.25496693557611655, (float)-0.11401084050100915, (float)-0.030669294212264525, (float)-0.024758029684723723, (float)0.08814764592606468, (float)0.19752495615481377, (float)0.06984504747405397, (float)-0.13741205772891285, (float)-0.05511385408847253, (float)0.2191836412902178, (float)0.265504862718167, (float)0.13684042864329385, (float)0.1682976568432193, (float)0.18926407771118683, (float)-0.07800018250902517, (float)-0.2502811740310551, (float)0.06003358840970949, (float)0.3976301764611667, (float)0.23475307712456503, (float)-0.05846800171643822, (float)0.056422400306051494, (float)0.2463014388363223, (float)0.014213065618138062, (float)-0.24357174019355315, (float)-0.0575984650549255, (float)0.08440596017051104, (float)-0.22561897802403436, (float)-0.391237153784567, (float)-0.03821021677605996, (float)0.25775982443905304, (float)0.14606282301535795, (float)-0.08846309177514668, (float)-0.2903404808225361, (float)-0.3840883519388423, (float)-0.1956194918106929, (float)0.06749683123771859, (float)0.07716279650602845, (float)-0.049591197445393816, (float)-0.13633842459295864, (float)-0.12881797281661314, (float)0.09791277695140554, (float)0.285280426836974, (float)0.063319994606173, (float)-0.0820823585525168, (float)0.2757684631021879, (float)0.4170370359361479, (float)-0.00032714702366455715, (float)-0.1666035976981002, (float)0.09177130145668028, (float)0.1408745462975694, (float)0.009516607881974459, (float)-0.0860754707554751, (float)-0.3303383423971999, (float)-0.3995803663769486, (float)-0.0048171042809966765, (float)0.1700674348098745, (float)-0.094637398226134, (float)-0.07607919734586557, (float)0.1455611434070176, (float)0.015797217768452977, (float)-0.0695160652290922, (float)0.15393749756477582, (float)0.16518198668986617, (float)0.017127883300753887, (float)0.0824264810378967, (float)0.07589137749446628, (float)-0.013826052685348273, (float)0.1475286437483288, (float)0.14421032717012128, (float)-0.20782700784396135, (float)-0.18106841284713532, (float)0.14240006862120963, (float)0.022749566010252752, (float)-0.12268994448254236, (float)0.1868814215960447, (float)0.23685502421944946, (float)-0.12601319237837044, (float)-0.16271926183101845, (float)-0.04139964876570621, (float)-0.19241994943915167, (float)-0.12089207830463887, (float)0.20866703419346447, (float)0.12261249606985818, (float)-0.13727700613441005, (float)-0.026844968626344185, (float)0.025605258318131, (float)-0.2233875853382597, (float)-0.2640926113502741, (float)-0.08866680645489673, (float)-0.06592099971157564, (float)-0.048277789304857176, (float)0.06098573283691743, (float)0.05220023317127311, (float)0.09205010569586569, (float)0.3339460600905751, (float)0.35670667114337934, (float)-0.011697226128157007, (float)-0.2760845579120498, (float)-0.15888448672346564, (float)0.031211046633312887, (float)-0.0033711729912618794, (float)-0.1617857731636405, (float)-0.13666741770202395, (float)0.13906457687369023, (float)0.33606853691547184, (float)0.18831503397010257, (float)-0.10219463830927425, (float)-0.13296041160238706, (float)0.16057732138248074, (float)0.3342196791097985, (float)0.02000502861488822, (float)-0.35455772563402416, (float)-0.19039014003549454, (float)0.13098081002368175, (float)-0.019490335007224704, (float)-0.22715730935398032, (float)0.044095845460223417, (float)0.32406501815671346, (float)0.17796855571640724, (float)-0.04181604205951034, (float)-0.07646275163540257, (float)-0.014953357188888862, (float)0.09886636153078185, (float)0.05675064267750259, (float)-0.22297036142955176, (float)-0.2529005577971478, (float)0.04872649726223725, (float)0.021908672939417978, (float)-0.26544742361239426, (float)-0.0794190627602712, (float)0.30692072024480804, (float)0.13875223715082596, (float)-0.26774579604270254, (float)-0.29040792542506777, (float)-0.10630847707780192, (float)-0.01942930709496578, (float)0.010285017243408775, (float)0.0312019338283641, (float)0.14005405015329336, (float)0.329420639620772, (float)0.2644864769896309, (float)-0.03963696663324855, (float)-0.09378629415303462, (float)0.06616595085539327, (float)0.02530760455908808, (float)-0.06847550496841824, (float)0.01331440703052309, (float)0.015007331530307304, (float)-0.08727028788839505, (float)-0.03624290549124936, (float)-0.0032468254838002105, (float)-0.1661781724927128, (float)-0.22322878273820126, (float)-0.0717998252419447, (float)0.0172332345761185, (float)0.0388106225021582, (float)0.16525915794448504, (float)0.33009038084314585, (float)0.35009720362024765, (float)0.11038887843450532, (float)-0.21844016871810676, (float)-0.16653263294918574, (float)0.23851819565295623, (float)0.30558613386516364, (float)-0.059813896017957904, (float)-0.20414191505177334, (float)-0.0817306539432669, (float)-0.12889078169446194, (float)-0.16437357943843228, (float)0.040126937218577935, (float)0.09356183598056748, (float)-0.08680109309848534, (float)-0.0834272456243925, (float)0.006158137235074162, (float)-0.16017489123797635, (float)-0.2801190362191639, (float)-0.04507394648088184, (float)0.13821288666411255, (float)-0.048930169560975956, (float)-0.23110832153319286, (float)-0.10171393932487635, (float)0.05705128563860537, (float)0.03368765094817068, (float)0.1025948583787974, (float)0.34908523630382604, (float)0.3550109215593267, (float)0.023299714105022552, (float)-0.16521072436022452, (float)-0.057927452208603666, (float)0.007599133111543814, (float)-0.03205930556166857, (float)-0.011795150085574748, (float)0.01146728056586724, (float)-0.0006418677676307769, (float)0.019612074785394874, (float)0.03033870849326343, (float)0.08370362329183538, (float)0.1992122714170577, (float)0.07198222368936912, (float)-0.20666793771528125, (float)-0.0540934297395636, (float)0.2639313794249771, (float)0.01413654872286098, (float)-0.302338792946369, (float)0.017947563332033768, (float)0.25254244918421, (float)-0.10553386017809971, (float)-0.23620059871330187, (float)0.05509739020025845, (float)0.03462174476443276, (float)-0.15119529867718448, (float)-0.01099400810081751, (float)0.055656295227901116, (float)-0.13531866282817961, (float)-0.13648457307444034, (float)-0.06727397726700463, (float)-0.1807383354194173, (float)-0.04360870029697437, (float)0.33066704960909643, (float)0.24431096121366974, (float)-0.1650429991168676, (float)-0.14785246219515458, (float)0.1638923593671205, (float)0.1767356512660189, (float)-0.008459175875771644, (float)0.009832213473502624, (float)0.14862716501062442, (float)0.07213886041795245, (float)-0.1983895812198186, (float)-0.2928981289171541, (float)-0.10855597375205166, (float)0.03234419504795523, (float)0.0098514258867039, (float)0.04468901140601985, (float)0.1803242763414136, (float)0.2972223880462139, (float)0.316734929784258, (float)0.07917613889837631, (float)-0.29831675369498717, (float)-0.2959469102754516, (float)0.0491450897297328, (float)0.1315841732633955, (float)0.007241296746232917, (float)0.0751177880755642, (float)0.04179802689411899, (float)-0.26302931356495074, (float)-0.33239321989766124, (float)-0.12801622186406839, (float)-0.05254787872532485, (float)0.0467992349802374, (float)0.25627860822763315, (float)0.16219718733212987, (float)-0.11095070787237296, (float)-0.12184449746211673, (float)-0.09712352565380862, (float)-0.18540924618366225, (float)-0.03257501957495643, (float)0.19715794004511236, (float)0.13506193187085547, (float)0.08248891144661569, (float)0.13301940358791906, (float)-0.06474879096588544, (float)-0.17709103798747455, (float)0.1820586853720529, (float)0.39478413451651023, (float)0.10489748470258621, (float)-0.12833831467263135, (float)-0.14007604295974854, (float)-0.1277811206885092, (float)0.11309734972387035, (float)0.38864997874340845, (float)0.17049748642957013, (float)-0.11976624485906665, (float)0.04017581033316088, (float)0.07362152693632416, (float)-0.26997154778679483, (float)-0.2898570956670255, (float)-0.010142660479293195, (float)-0.0898251201274736, (float)-0.332866894288135, (float)-0.30224333923952995, (float)-0.20290711837203013, (float)-0.10368775009219154, (float)0.11357937656103967, (float)0.14908560885768524, (float)-0.0406246251039655, (float)-0.02623369488131071, (float)0.1027171191108288, (float)0.007778194527092069, (float)-0.04986180028214027, (float)0.09159447575289918, (float)0.07019381010152166, (float)-0.09955671520351245, (float)-0.03885908764676431, (float)0.20911651354546867, (float)0.38641247688785313, (float)0.37898315953360867, (float)0.13697661324278768, (float)-0.07627413993889132, (float)0.08033985464332079, (float)0.2902270751096167, (float)0.1482922320593465, (float)-0.01590523998033217, (float)0.04131101231755447, (float)0.005295102421311709, (float)-0.10116411390178096, (float)-0.05583132512090193, (float)-0.13264865856806077, (float)-0.33049964631027035, (float)-0.16257945576895105, (float)0.10505191489536511, (float)-0.14324452788210582, (float)-0.4810145715040674, (float)-0.3451528997683161, (float)-0.1516825088963161, (float)-0.1398549079745797, (float)0.05596380831008965, (float)0.22201021090727102, (float)-0.003974798770751111, (float)-0.09021363539540679, (float)0.2345266510737931, (float)0.24782250829231917, (float)-0.16833694090554382, (float)-0.20190682721221204, (float)0.1411428293953471, (float)0.10042115190884605, (float)-0.18803050220363396, (float)-0.05732387295927498, (float)0.2801218085390921, (float)0.2757986639521463, (float)0.14619394527176446, (float)0.2451920597532336, (float)0.2903751539748538, (float)0.054958348400603464, (float)-0.12436780145478267, (float)-0.05318768823715125, (float)0.01987222677437285, (float)-0.0012913897156618243, (float)0.005087762696630207, (float)0.0008296233570696323, (float)-0.017667139887280768, (float)0.0612689025638457, (float)0.07321516148108306, (float)-0.12820606401560963, (float)-0.20870126599013877, (float)-0.037593480237091484, (float)-0.04661398681845544, (float)-0.24210374420900937, (float)-0.14981109447952287, (float)0.05258160225434512, (float)-0.07640643225224494, (float)-0.16691250558348958, (float)0.10176686451040666, (float)0.1610912161330122, (float)-0.2155814199229124, (float)-0.3684883358014226, (float)-0.08042029988221845, (float)0.14664484628693125, (float)0.15052823664394724, (float)0.14727416781118094, (float)0.1745371089737497, (float)0.1973247714977974, (float)0.1594648510482271, (float)-0.03931357057975448, (float)-0.18600698372133456, (float)-0.010854619355137063, (float)0.18792253368319817, (float)0.06142262557460373, (float)-0.15857132152863018, (float)-0.2437339568047769, (float)-0.2456447897381717, (float)-0.03601514856817221, (float)0.33490807618518686, (float)0.37083921355706007, (float)0.08445541092150817, (float)0.03205499392273828, (float)0.1102429163010684, (float)-0.10222137623372478, (float)-0.24358805509246848, (float)0.006675450652996745, (float)0.09770547312002849, (float)-0.20167907266240967, (float)-0.2772263815026098, (float)0.0658514189627433, (float)0.3253880978379664, (float)0.2920270669738581, (float)0.15386658025920844, (float)0.012775194593153705, (float)-0.09379072488360041, (float)-0.14833163108947894, (float)-0.17001612016829498, (float)-0.08302108536134216, (float)0.0637886203703934, (float)-0.014777278492942964, (float)-0.27378666464631285, (float)-0.3166717690250966, (float)-0.14966015837150232, (float)-0.05005767076849784, (float)0.054804709437194274, (float)0.1791930404911905, (float)0.03983835033936549, (float)-0.1688958908103286, (float)0.020644844532523812, (float)0.27798741804734217, (float)0.08713075074327079, (float)-0.08329322565962459, (float)0.2295929653701751, (float)0.39779007986048315, (float)0.01277481455604939, (float)-0.23556428517295402, (float)-0.03203494821549903, (float)0.032712955121770394, (float)-0.11141627664035318, (float)-0.017196586096305897, (float)0.06550909807417483, (float)-0.15435597459905287, (float)-0.13288520767014902, (float)0.23700348936182783, (float)0.1961376300801105, (float)-0.19999556871001867, (float)-0.15159051090512132, (float)0.16503259143585874, (float)0.14791808692654976, (float)0.0907367540283623, (float)0.2373242449873018, (float)0.16769828911226828, (float)-0.057221890195322395, (float)-0.030753330606432885, (float)-0.014425817499834083, (float)-0.23281351384844773, (float)-0.30416258091546056, (float)-0.19405731219003183, (float)-0.2278971011765205, (float)-0.2772515856938957, (float)-0.166668862518782, (float)-0.04540682897070679, (float)0.08627379951005536, (float)0.1948516701373639, (float)0.07431893894146233, (float)-0.03306260806504451, (float)0.15320268652447103, (float)0.25206797263761704, (float)0.12602028570091348, (float)0.185846274682702, (float)0.24001992294094154, (float)-0.09292773723097295, (float)-0.3108844375179622, (float)-0.08387318419523564, (float)0.07883221015150707, (float)0.06695889113033691, (float)0.1528000611645608, (float)0.1054086018327878, (float)-0.08207006442001726, (float)0.004266470356096094, (float)0.113745747158708, (float)-0.09485923066403845, (float)-0.1593889704212225, (float)0.03411310870201263, (float)-0.0038405541474071272, (float)-0.08627881256816679, (float)0.09400502894937389, (float)0.07580489080101882, (float)-0.17935342984930205, (float)-0.1502461805019161, (float)-0.0808438046450806, (float)-0.2490395307556932, (float)-0.10908102443235117, (float)0.23484986572644828, (float)0.03151686779556738, (float)-0.2689802137685652, (float)0.06294789803416724, (float)0.3209018520948711, (float)-0.0010852484324084396, (float)-0.06198836449196766, (float)0.31666356430287834, (float)0.27203125996756017, (float)-0.08087803860186424, (float)0.018133200822819016, (float)0.23761335671369643, (float)-0.011129809338766358, (float)-0.27631791344076295, (float)-0.15061556759135936, (float)-0.08809856896452803, (float)-0.2617940550473108, (float)-0.19595796280141833, (float)0.11937367358439427, (float)0.1806691668508176, (float)-0.026392724524773068, (float)-0.10716694092959228, (float)0.038012878416227525, (float)0.26062095851937445, (float)0.3315931488879786, (float)0.030476196271247938, (float)-0.3324446245012457, (float)-0.19656680978180574, (float)0.12147449844252095, (float)-0.02959006042218252, (float)-0.24152379953291264, (float)0.03684408743304702, (float)0.25712991035055943, (float)0.07526207129318617, (float)0.07585414659574817, (float)0.2466029913718983, (float)0.0001275659599263331, (float)-0.3270381426523229, (float)-0.1732052644745973, (float)0.06383835641804542, (float)0.04361857720482154, (float)0.05120007023664483, (float)0.044171268048807916, (float)-0.16795113354187, (float)-0.23291458206802385, (float)0.013692703364179428, (float)0.13878784308824088, (float)-0.024717414560335275, (float)-0.14874416848538205, (float)-0.02804634807204302, (float)0.18253606870445324, (float)0.18004284218124672, (float)-0.04583734522945412, (float)-0.1109119107143301, (float)0.04752481994891819, (float)0.05159577202330106, (float)-0.025044628214150603, (float)0.1209916853835964, (float)0.16373366412723284, (float)-0.07504061658271642, (float)-0.04586703214711606, (float)0.22976699855883032, (float)0.057749175084374084, (float)-0.330492965672416, (float)-0.1755811942891089, (float)0.23589958937310493, (float)0.2584246599378292, (float)0.05781030364420411, (float)-0.07468524620710584, (float)-0.17431442853762044, (float)-0.09937622771159621, (float)0.11830080008532874, (float)-0.0018070954985878684, (float)-0.3961658791556933, (float)-0.37543045919575546, (float)0.03370421654941026, (float)0.13779891358115617, (float)-0.05865326420279368, (float)-0.029225787906395188, (float)0.13992767000326892, (float)0.12150377658100704, (float)0.11823174048963035, (float)0.2183100564616764, (float)0.04571308170188944, (float)-0.27583751131452017, (float)-0.17941930485171775, (float)0.12848720131446034, (float)0.06568539468398683, (float)-0.07374848607214118, (float)0.17997476877300408, (float)0.39236183740942226, (float)0.1404534075513425, (float)-0.15931099409875285, (float)-0.13414289116790515, (float)-0.005294257456927648, (float)-0.021354977753792415, (float)-0.17098933660362434, (float)-0.28541435251494457, (float)-0.1507663966980182, (float)0.15899758918220272, (float)0.309067737497451, (float)0.23825772956954125, (float)0.13175670173621717, (float)0.005470898455731924, (float)-0.16648106514518313, (float)-0.2867650476131245, (float)-0.30396864795961503, (float)-0.17820786441990044, (float)0.09468103857842339, (float)0.27052670181658145, (float)0.15876587619202748, (float)-0.03277746149723143, (float)-0.07591602437996783, (float)0.001909931174170404, (float)0.11977845459520595, (float)0.14455961505660814, (float)-0.026454956116089313, (float)-0.18815000075820598, (float)-0.15318823770685253, (float)-0.09174385348442364, (float)-0.07862969696273078, (float)0.03522695370738959, (float)0.15783532325983396, (float)0.1440481083871049, (float)0.13607671140156127, (float)0.1551822458504269, (float)0.022528538585860295, (float)-0.1614931993021939, (float)-0.18130612016861067, (float)-0.10371939103319885, (float)-0.05156542432928151, (float)-0.016981606645370913, (float)0.017249144619498013, (float)0.0724591647043697, (float)0.10066253814522796, (float)-0.002425544520714245, (float)-0.09578170462175625, (float)0.030791548498325123, (float)0.2005539016473669, (float)0.18096397667531913, (float)0.09202374919422399, (float)0.04120237170553199, (float)-0.04430709757862903, (float)-0.1579654377693294, (float)-0.2733501986426624, (float)-0.3347813865293377, (float)-0.16230750132917302, (float)0.13355767188639325, (float)0.18265812099996823, (float)0.07037475409911993, (float)0.07502430865213311, (float)0.01345307180004594, (float)-0.13872694441030584, (float)0.035165461173915856, (float)0.3848620882133436, (float)0.3181504670691604, (float)-0.02539375172002355, (float)-0.1402536519411869, (float)-0.10676155247316456, (float)-0.15957985287983603, (float)-0.20191489325383577, (float)-0.15653432277776105, (float)-0.061195405212564925, (float)0.02920397346407351, (float)0.00667871069550761, (float)-0.025967896422398495, (float)0.14092271250608868, (float)0.24981347044574181, (float)0.015085905494449504, (float)-0.15198460586684842, (float)0.06205061212143183, (float)0.2115256153462081, (float)0.08565046273162899, (float)0.058558966634072, (float)0.07704109955052832, (float)-0.18805881535718033, (float)-0.376176953337962, (float)-0.09191660657120895, (float)0.15973926010009684, (float)-0.06509838350138211, (float)-0.2816307881999361, (float)-0.09614755990679666, (float)0.11824920129648257, (float)0.11536008154804707, (float)0.09972230471983402, (float)0.05855914707910605, (float)-0.08727108579317663, (float)-0.055532033556428474, (float)0.20350693733612618, (float)0.2844739037751162, (float)0.09420735776960512, (float)-0.11314490411772965, (float)-0.24559962639393937, (float)-0.19723090711221056, (float)0.06528937277678597, (float)0.17242932499778615, (float)0.06136763948149511, (float)0.15031193372105195, (float)0.2296116236837142, (float)-0.1049431217900169, (float)-0.261041437807866, (float)0.08547261154621265, (float)0.12325624749143833, (float)-0.18540280992185698, (float)-0.011107980174120898, (float)0.25877402802892907, (float)-0.061328154010642344, (float)-0.26087131544970044, (float)0.03170093563309253, (float)0.03871265656986715, (float)-0.198270939707685, (float)-0.11682571601096957, (float)-0.10326109609945124, (float)-0.2630590608630257, (float)-0.025358855811747894, (float)0.22833266329677473, (float)-0.016766839686171778, (float)-0.09499306821638287, (float)0.16559261768848355, (float)0.07020871400059747, (float)-0.09179777982201741, (float)0.15024395761634063, (float)0.16047327624948818, (float)-0.08706254634927754, (float)0.17299210436994533, (float)0.4474056067152708, (float)0.010074668540930453, (float)-0.33715296532650724, (float)-0.06356580492599773, (float)0.10577940277682155, (float)0.02857082328324238, (float)0.1241948815997028, (float)0.10842465829382428, (float)-0.1264697905334032, (float)-0.06689355823503927, (float)0.13900931297603789, (float)-0.057723909705207334, (float)-0.3954171462753433, (float)-0.3654547200138605, (float)-0.07529120706132646, (float)0.09984765029832156, (float)-0.023917887346401923, (float)-0.21922524084543146, (float)-0.04181085244886954, (float)0.3268142552965117, (float)0.22975285630963727, (float)-0.1782743437457408, (float)-0.14605991116440595, (float)0.25332963455484714, (float)0.33264528711935826, (float)0.030418052156847855, (float)-0.13977623889966762, (float)0.030720931647634096, (float)0.2250059820975825, (float)0.12300913999826561, (float)-0.12058054353382826, (float)-0.1494782739352463, (float)0.02074909079886226, (float)0.13090844827704734, (float)0.09675206568369527, (float)-0.032657294063532294, (float)-0.16071031631488866, (float)-0.17378076292811248, (float)-0.12453576030470986, (float)-0.07390251159251361, (float)0.07336034013912912, (float)0.16929296370913258, (float)-0.03500616715045479, (float)-0.21733852053292782, (float)-0.039990097012530416, (float)0.0798048083189813, (float)-0.12527205392595384, (float)-0.1880599636435478, (float)0.0061427793996366, (float)0.009609028862350143, (float)-0.13906056948634962, (float)-0.06311021222355398, (float)0.13073803110126506, (float)0.15733936124423642, (float)0.07213263192381789, (float)0.06961101566248781, (float)0.19435434638336715, (float)0.27151608037713093, (float)0.1480017991192241, (float)0.01690399370586017, (float)0.03440013294821031, (float)-0.05896574288926534, (float)-0.28060896524169054, (float)-0.19083757104428412, (float)0.1768494221137549, (float)0.29289547495394175, (float)0.0827673542951466, (float)-0.12087875497458266, (float)-0.15806634109590234, (float)-0.0411337513461465, (float)0.0471105757844655, (float)-0.08360310395278477, (float)-0.1813898527114753, (float)-0.016177604850080376, (float)0.05629699260679369, (float)-0.07454379015119515, (float)0.032149204342858666, (float)0.2311106917414559, (float)-0.020068609659751744, (float)-0.36326120621585795, (float)-0.1807546277979653, (float)0.15691917048442464, (float)0.0988761890131078, (float)-0.12180623747728338, (float)-0.16297673589960213, (float)-0.12878316444855342, (float)-0.1512636118156331, (float)-0.1385725096301385, (float)0.016284985258393794, (float)0.2138211941895352, (float)0.24382387781526974, (float)0.17180531240001204, (float)0.23129236136794432, (float)0.2830028725906651, (float)0.08998879242409083, (float)-0.08768313565813203, (float)0.03085996163497081, (float)0.20029558376171605, (float)0.1329467104742443, (float)-0.1065708470227036, (float)-0.2857553536233442, (float)-0.16985783744425365, (float)0.15774060869271453, (float)0.24683992183082912, (float)0.033889480228141144, (float)-0.08609695619216483, (float)-0.1434999330171169, (float)-0.35567524163153696, (float)-0.39908104457554666, (float)-0.14154444690372261, (float)-0.019583919087036033, (float)0.009011066225300464, (float)0.25554478818339704, (float)0.26829815315192695, (float)-0.17070148033387325, (float)-0.23714528923146067, (float)0.23269719685475138, (float)0.25589548595019734, (float)-0.23750688628786135, (float)-0.28341405699076505, (float)0.12024952968028935, (float)0.2200836715145825, (float)0.08958911713983145, (float)0.1667991150508743, (float)0.2307895610121287, (float)0.027830204044780683, (float)-0.15818792078225233, (float)-0.11691831358768194, (float)-0.004760383690752907, (float)0.0465960983212873, (float)0.003920654415751425, (float)-0.16960345565861407, (float)-0.31792439032206266, (float)-0.17039019817446246, (float)0.14808992775317673, (float)0.19518051234326028, (float)-0.016944367960027802, (float)-0.013583731301902458, (float)0.22412590717281783, (float)0.22118796462427773, (float)-0.03261529179934954, (float)-0.10071048734800658, (float)0.02649736639902896, (float)0.048203692719263745, (float)-0.01267426856373322, (float)-0.011759717206027791, (float)0.027324834266142576, (float)0.08572614993250639, (float)0.0691940425376545, (float)-0.12861163908039738, (float)-0.1992141826592971, (float)0.11576763847507779, (float)0.32844900986234143, (float)0.05179666413416153, (float)-0.2300301727535142, (float)-0.18333757883919446, (float)-0.14752007950688864, (float)-0.1838567965571237, (float)-0.09112555410759153, (float)-0.11256200330291269, (float)-0.305649552265969, (float)-0.1898010641033124, (float)0.16065791923832146, (float)0.15595170727952581, (float)-0.05431821326196906, (float)0.026036748935299427, (float)0.15576910260587046, (float)0.03769505551409993, (float)0.030918526886903337, (float)0.2633504256733159, (float)0.2872749446117564, (float)0.059837614802481474, (float)0.04988196078424141, (float)0.2631144453218568, (float)0.23814541848031145, (float)-0.013859197319410092, (float)-0.049143659070783614, (float)0.06587772275116743, (float)-0.11360034583346579, (float)-0.3849099950709701, (float)-0.20413114049233586, (float)0.16250866282946136, (float)0.11728491449160577, (float)-0.12413997323705356, (float)-0.11185884080810797, (float)-0.00577637423141448, (float)0.03205987098509742, (float)0.10111305233698616, (float)-0.0025709183748097654, (float)-0.3449315520322848, (float)-0.3815718782642434, (float)0.007478075890672185, (float)0.16127072326375863, (float)-0.057891080528816204, (float)-0.06817053332846978, (float)0.185633725751283, (float)0.20517629702283008, (float)-0.040643925627854946, (float)-0.14188406899564815, (float)0.0064169016143175075, (float)0.12401374252271105, (float)0.016089079111073823, (float)-0.1831367107002753, (float)-0.23332417003581044, (float)-0.0880738457925653, (float)0.14135665939088307, (float)0.3256864319687362, (float)0.32927685406280305, (float)0.14111420194760246, (float)-0.05004680353738, (float)-0.11711702160455194, (float)-0.09993038022778807, (float)-0.012031109002477388, (float)0.1027775337171137, (float)0.06569691554808336, (float)-0.14411599342451942, (float)-0.23226566096333268, (float)0.012122397223784965, (float)0.3435149974550106, (float)0.3494688126303333, (float)0.08934917755173921, (float)-0.008870305492036927, (float)0.03532126974548365, (float)-0.14173617716439027, (float)-0.3700600480360682, (float)-0.2917967640731197, (float)-0.11865039911787137, (float)0.0048806916117583865, (float)0.24621499595129898, (float)0.24589798719429837, (float)-0.19984366589848238, (float)-0.2603126334306637, (float)0.23787328104095434, (float)0.20855045922602994, (float)-0.31339914067572144, (float)-0.2297512664479737, (float)0.13190427628523724, (float)-0.07218100094540048, (float)-0.26434599649379853, (float)-0.031125335759829235, (float)0.02760257424290473, (float)0.034032519187437736, (float)0.3414202826478, (float)0.27212017431158125, (float)-0.21582395329763499, (float)-0.15730527740329395, (float)0.19869251393828036, (float)0.0252555634038883, (float)-0.11827465922554962, (float)0.2393684875148249, (float)0.32947790761985346, (float)-0.02660088586243049, (float)-0.16882587131270735, (float)-0.09302661808913357, (float)-0.04814775981556719, (float)0.06325798732929884, (float)0.03510265270429911, (float)-0.2248131159414392, (float)-0.2164167534569718, (float)0.04796575528740583, (float)0.03092391389369544, (float)-0.09000201460854283, (float)0.06985448751245722, (float)0.20627606178391386, (float)0.14203343136317798, (float)0.14831234094891496, (float)0.16966164806479625, (float)0.01988279514126155, (float)-0.15021081403083472, (float)-0.23439449090769135, (float)-0.1968974833685194, (float)0.07693653180311423, (float)0.29487459326111326, (float)0.023208749577271887, (float)-0.3583983690863935, (float)-0.19347572162704318, (float)0.22000772666466903, (float)0.16710812123569602, (float)-0.195823781738585, (float)-0.18310107515172638, (float)0.19113969397544425, (float)0.28825108254839327, (float)-0.0363493518479535, (float)-0.29014060967449873, (float)-0.23953626146180806, (float)-0.07866993423141619, (float)0.10740836528171563, (float)0.28541572153243, (float)0.2821574170038371, (float)0.09552685080313278, (float)-0.11943888604510443, (float)-0.30445385622710147, (float)-0.3389194095777695, (float)-0.15885010238561606, (float)-0.028661694855280296, (float)-0.05041474378990313, (float)0.00538055714865937, (float)0.07560002606615263, (float)0.037690434120752986, (float)0.15451538007734364, (float)0.32161869603639837, (float)0.123913054262203, (float)-0.03977138437348679, (float)0.27714223091625356, (float)0.40901005303013943, (float)0.0007182578020646377, (float)-0.1891383248664599, (float)-0.01721963502622043, (float)-0.07713926647141382, (float)-0.14429917137837245, (float)0.14888404292313467, (float)0.27148462780118326, (float)-0.004614160929369007, (float)-0.21096755970137274, (float)-0.30907704943117076, (float)-0.4053756205647381, (float)-0.23598949488821178, (float)0.001949672729681841, (float)-0.06423244135694715, (float)-0.013206566431176783, (float)0.3281184909058315, (float)0.24309213728839119, (float)-0.22725902313391047, (float)-0.17236851894229654, (float)0.25489306167356063, (float)0.19620264420282688, (float)-0.11362954944318573, (float)-0.019380626990592887, (float)0.1882803277044632, (float)0.055372946733073074, (float)-0.19293883036497786, (float)-0.29777434498689553, (float)-0.2913140707562996, (float)-0.1417774584323837, (float)0.1212599054907294, (float)0.28900257380678296, (float)0.2932008477991525, (float)0.17506282430647127, (float)-0.04887074769269251, (float)-0.15223592497216987, (float)0.03147266600579031, (float)0.13884210364585875, (float)-0.045953218497342144, (float)-0.05153841469706511, (float)0.23162546531368788, (float)0.18450095722321277, (float)-0.18042099375623033, (float)-0.17742048887082656, (float)0.08003167289737453, (float)0.021468863521646835, (float)-0.10934366090959127, (float)0.026374123345638167, (float)0.06275225706469671, (float)-0.08947157968563597, (float)-0.03786107995472425, (float)0.0737159905041979, (float)-0.0793345144428488, (float)-0.18285728993988207, (float)-0.028046509715169025, (float)0.008404213762132826, (float)-0.15751173592843037, (float)-0.17928261959112105, (float)-0.04060557845130091, (float)0.05469367486468385, (float)0.16558794178862016, (float)0.34140401061880005, (float)0.3772589239379045, (float)0.17162824307538144, (float)-0.06931311756014774, (float)-0.13647191245365198, (float)-0.08030187893979768, (float)-0.04205486080645794, (float)-0.02895197670283821, (float)-0.025633651725908483, (float)-0.05957517855277444, (float)-0.06170387069179557, (float)-0.027030702800860416, (float)-0.12240964630999811, (float)-0.24123038497161692, (float)-0.05154745792243585, (float)0.24586080112317515, (float)0.1421007737059668, (float)-0.21680757176797022, (float)-0.30312855371017333, (float)-0.09348605385500613, (float)0.10538398135498427, (float)0.16874390313062343, (float)0.11759173868092615, (float)0.045204947435686656, (float)0.04525738766455904, (float)0.058288289720874284, (float)0.04806248805717469, (float)0.11103431553817103, (float)0.1929699101274286, (float)0.11765135121227698, (float)-0.09788936312483329, (float)-0.2637095104448868, (float)-0.180480756284728, (float)0.13954128264085153, (float)0.30156506550336776, (float)0.07235400716833149, (float)-0.15877766675195965, (float)-0.12637280375189003, (float)-0.09369716556026657, (float)-0.07672114153484892, (float)0.11040857771997553, (float)0.17774240242434722, (float)-0.04515755257927563, (float)-0.1625631753504783, (float)-0.07399271602950155, (float)-0.021057550852717516, (float)0.08345668314064228, (float)0.19831329860271385, (float)0.00977699291850135, (float)-0.20701916117827723, (float)-0.025753018271168226, (float)0.16645783628678315, (float)-0.035521201534670185, (float)-0.3028552870838137, (float)-0.2927503571871765, (float)-0.023197228350840152, (float)0.2867891113861793, (float)0.22423895510864209, (float)-0.15666175104411537, (float)-0.14751369112398904, (float)0.2681761644889554, (float)0.3261270650124263, (float)0.05734832249504359, (float)0.00033500346053400194, (float)-0.06498537050104476, (float)-0.31552900611071577, (float)-0.25883279212780863, (float)0.06545199176722202, (float)0.08343916088452316, (float)-0.08350235410295907, (float)-0.031665176132314385, (float)0.03647719997396443, (float)-0.0937405565061194, (float)-0.16386073837798576, (float)0.031258793039471676, (float)0.31766053142969863, (float)0.3487525636451842, (float)0.0491705486665811, (float)-0.14775231601272348, (float)0.04862689867613265, (float)0.22075505418438698, (float)0.019257453426240006, (float)-0.18230570699449264, (float)-0.03239207227395398, (float)0.18959565791318245, (float)0.10146709719689037, (float)-0.18407238009427376, (float)-0.23631204673481357, (float)-0.006997019821844058, (float)0.026744231207813243, (float)-0.22936073771917054, (float)-0.21391702607588792, (float)0.1430769383057766, (float)0.21278268819078877, (float)-0.06630203365206798, (float)-0.13175498899887805, (float)0.07270503665277331, (float)0.17236117535806922, (float)0.12853090394668387, (float)0.0993395464142855, (float)0.04622497856721321, (float)-0.13014758736287804, (float)-0.30433097501344986, (float)-0.19002675317284992, (float)0.12992931543166383, (float)0.16058154822362444, (float)-0.10177355915704679, (float)-0.147243276049007, (float)-0.040090110948442025, (float)-0.11717113515229538, (float)-0.043366522704663645, (float)0.3209380902477703, (float)0.3669658226474868, (float)0.04415203150004575, (float)-0.10685285357676055, (float)-0.17659253211260248, (float)-0.31974611592263913, (float)-0.1440278932227776, (float)0.20157819727986956, (float)0.1854991402814636, (float)0.08158030588323487, (float)0.19725373379297967, (float)0.1443544283949695, (float)-0.07860482563461299, (float)-0.06887829500303837, (float)0.03144687442162862, (float)0.03902488116112391, (float)0.053783822859572, (float)-0.11338087575546293, (float)-0.3511070687997947, (float)-0.07178561046527901, (float)0.36922939133637017, (float)0.14465482985096892, (float)-0.2585911797016102, (float)-0.09990178118045843, (float)0.12185549506607903, (float)0.04145689662652808, (float)0.09662116646294315, (float)0.18624007063261325, (float)-0.05183449015003426, (float)-0.23297856781670653, (float)-0.13176623159992262, (float)-0.13987358553340418, (float)-0.2219074087856078, (float)-0.04468560066180516, (float)0.17626688153555745, (float)0.14319388424109716, (float)0.015781164729261957, (float)0.019691141245909982, (float)0.15573258612568314, (float)0.2175928197889336, (float)0.02252549722464517, (float)-0.16861508006432083, (float)-0.017863623131581872, (float)0.18106556574336588, (float)0.048905368940633284, (float)-0.1748872881260837, (float)-0.22045109430911253, (float)-0.18051121531515205, (float)-0.09763102127727287, (float)-0.041217590910937664, (float)-0.1652984887674815, (float)-0.233020955685839, (float)0.010534152611364289, (float)0.19336110504268358, (float)0.05027542060484134, (float)-0.018037124702644323, (float)0.16189397950397152, (float)0.24836825343202887, (float)0.20097674969959, (float)0.23653091041231236, (float)0.2435768773371168, (float)0.09327743530240602, (float)-0.012762392226221652, (float)0.03362158831245013, (float)0.030842279492371335, (float)-0.14443836716958378, (float)-0.29425658242525365, (float)-0.16611595665380435, (float)0.13763831913562508, (float)0.25268341417898604, (float)0.10246953279504038, (float)-0.05839584754078696, (float)-0.13518600312195642, (float)-0.18052882495462708, (float)-0.12314997227139636, (float)-0.02148186123279644, (float)-0.09443347675186736, (float)-0.23620225440855416, (float)-0.1877224802756609, (float)-0.06562152117662451, (float)-0.032838319486122494, (float)0.019186416441182567, (float)0.030112175280729517, (float)-0.1364880200647786, (float)-0.2054824532014296, (float)-0.01738561175078589, (float)0.0938980230084423, (float)0.11887514552260305, (float)0.35710584134105156, (float)0.4631260521685157, (float)0.08495107922155347, (float)-0.1528043575850954, (float)0.1326821599371606, (float)0.24945209445023245, (float)-0.05175779078423861, (float)-0.15516259039036892, (float)-0.046242606706885854, (float)-0.1268377085569386, (float)-0.1050122364752384, (float)0.18494155279318686, (float)0.17715495134152784, (float)-0.16645696830187887, (float)-0.20405614616973847, (float)0.06918541285285532, (float)0.13908156405161057, (float)-0.030460902696128275, (float)-0.14029776144079775, (float)-0.05992854932665287, (float)0.08358970043864186, (float)0.014872477682857658, (float)-0.17203880070443994, (float)-0.014716350960520022, (float)0.31664495618562744, (float)0.19869645002575395, (float)-0.13796208009396116, (float)-0.1218316256677677, (float)-0.05291898545108021, (float)-0.21754975404978713, (float)-0.160881019594084, (float)0.14451936203752438, (float)0.18368488820063608, (float)0.061486749399443784, (float)0.10779513609926407, (float)0.08086677097056495, (float)-0.11949396878435041, (float)-0.17720031735092814, (float)-0.12880379420736712, (float)-0.1957670368731608, (float)-0.19192228464641298, (float)0.05044107020185525, (float)0.25823829677171567, (float)0.1315834854931137, (float)-0.20250368013555362, (float)-0.31105984620283617, (float)-0.08463462792099144, (float)0.05721891974905981, (float)-0.00574143416076461, (float)0.13913936752755734, (float)0.4005085190656688, (float)0.26502066718401635, (float)-0.011409801594181663, (float)0.07852995208169247, (float)0.18720290779566465, (float)0.0002014136855239953, (float)-0.03185048775270927, (float)0.19602294302201678, (float)0.16551810237919656, (float)-0.1597435049684291, (float)-0.31530232406883174, (float)-0.15214871621216686, (float)0.0978203748122772, (float)0.13877060256524767, (float)-0.07905143480072448, (float)-0.19911086138143788, (float)-0.03709332909650449, (float)0.031358067791994494, (float)-0.16322548352918168, (float)-0.22053160539979455, (float)0.0318508553767213, (float)0.25236458121474864, (float)0.17674394361071127, (float)-0.0671594204214784, (float)-0.14891817960840656, (float)-0.0018202138369775576, (float)0.012400830991757412, (float)-0.18178455167241708, (float)-0.14325702665388412, (float)0.08146671460005742, (float)-0.015609364467185124, (float)-0.22535808453703668, (float)-0.08107209830019901, (float)0.1015792813957104, (float)0.09854335345179994, (float)0.26909966660484264, (float)0.4037805336713945, (float)0.03791394150859341, (float)-0.3035052321009767, (float)-0.10045446849758208, (float)0.1180007133522389, (float)0.045250965602774945, (float)0.07563626757245427, (float)0.11355273026717222, (float)-0.15425934729898366, (float)-0.29535034299020757, (float)0.02405209362358113, (float)0.31729077511588133, (float)0.24765276509955206, (float)0.07168409565424208, (float)-0.07519466267328717, (float)-0.2575307391771001, (float)-0.298731612434142, (float)-0.026624714677290072, (float)0.2913624227853512, (float)0.265222897228608, (float)-0.016852738174734715, (float)-0.15209002044090286, (float)-0.0816883821989905, (float)-0.014968916671874916, (float)0.06418691046100672, (float)0.13816875429636893, (float)-0.023136207418970267, (float)-0.2491520350530069, (float)-0.17329175523599422, (float)-0.07737561680802986, (float)-0.22546318890380268, (float)-0.11744491327247526, (float)0.2923061428908298, (float)0.21883978061905077, (float)-0.2563215684613194, (float)-0.26880825591851504, (float)0.03148197515419109, (float)0.040839328947396177, (float)0.09219998548049811, (float)0.404626038632231, (float)0.38536219142988853, (float)0.019293630157060645, (float)-0.08966165134754314, (float)-0.011461094597141903, (float)-0.025339933241085355, (float)0.06977794106697395, (float)0.1202845774095644, (float)-0.19768450458328424, (float)-0.3557206198113085, (float)0.02047014263847286, (float)0.2086862964414082, (float)-0.07027395241467578, (float)-0.09783210237776366, (float)0.13794532329684575, (float)0.019753406402193627, (float)-0.1354731595847718, (float)0.1401199946989325, (float)0.22678652154698692, (float)-0.21816942052454275, (float)-0.3937104658405942, (float)-0.010298611623752266, (float)0.16598505709071176, (float)-0.10383167165451519, (float)-0.24245048186413368, (float)-0.08844344025798401, (float)0.00835593555738531, (float)-0.014673619475149533, (float)0.042918425511623795, (float)0.17740583310069227, (float)0.22999944207999368, (float)0.1901135904170186, (float)0.16968847394684533, (float)0.14057170782034614, (float)0.02086539755598118, (float)-0.016491891538489175, (float)0.1462598828609245, (float)0.15692362938727358, (float)-0.17448653223718, (float)-0.3650508692761691, (float)-0.15168703792689475, (float)0.031185737419526065, (float)0.01036514109444851, (float)0.08159405102678544, (float)0.14887825185702155, (float)-0.04534562347292078, (float)-0.20840951274083427, (float)-0.08357364518270959, (float)0.015455638755568938, (float)-0.1097129902220297, (float)-0.2162444056047527, (float)-0.16118644787233385, (float)-0.05359725536478048, (float)0.005889426756858044, (float)0.001527614519588559, (float)0.009071597784439632, (float)0.09149137845292572, (float)0.17266418670673908, (float)0.20935670453707586, (float)0.22087161643176226, (float)0.10836464559570243, (float)-0.06690791542983121, (float)0.011929890582350456, (float)0.24774407526720096, (float)0.18471056040813352, (float)-0.05990912116806203, (float)-0.051422656416444966, (float)0.01844666214922326, (float)-0.19334656726578045, (float)-0.40896190479889283, (float)-0.32396995747849927, (float)-0.14482393546368624, (float)-0.07441283604390761, (float)-0.008001830057330508, (float)0.12945885200373317, (float)0.20174359233654224, (float)0.09543910544627714, (float)-0.007183529913403042, (float)0.11188015136127918, (float)0.22506046414027878, (float)0.07845848444925059, (float)-0.022632131275490786, (float)0.10088181198936153, (float)0.07932572905904735, (float)-0.06714630062479333, (float)0.029726068464366692, (float)0.08195830235538623, (float)-0.1553074475464082, (float)-0.12356770592756114, (float)0.2129589148581827, (float)0.13713386131287983, (float)-0.18834384823420172, (float)-0.15661075412525632, (float)-0.11195423778795072, (float)-0.2951492821874064, (float)-0.19563552947533855, (float)0.043134272564188114, (float)-0.04525305682151275, (float)0.006690641507203938, (float)0.3503921936030029, (float)0.21391929212718666, (float)-0.23906331305639497, (float)-0.15169257647773238, (float)0.13445380232604384, (float)0.04619406002084513, (float)0.022755895558457577, (float)0.11382915927313178, (float)-0.17084598268786144, (float)-0.36618016377834167, (float)0.019164610228789854, (float)0.25763885847063994, (float)-0.009504468702751474, (float)-0.04949512366876809, (float)0.273017657841868, (float)0.34802437449796403, (float)0.13518567272495274, (float)-0.04284172784069606, (float)-0.11792931401329271, (float)-0.0169038688530738, (float)0.177452313846704, (float)0.09974889338689283, (float)-0.1825005309005737, (float)-0.23060236788005356, (float)-0.10893638768111026, (float)-0.14684273768392803, (float)-0.20837488381032823, (float)-0.027726978477538758, (float)0.24684406190579689, (float)0.2774635514117566, (float)-0.012592172025604313, (float)-0.31029127009547725, (float)-0.2820972347911355, (float)-0.06371467339158395, (float)0.010626525449855307, (float)0.015603422772806153, (float)0.17720891999609661, (float)0.3398019756330076, (float)0.2560723160500623, (float)0.028221083800686882, (float)-0.07547961020220126, (float)0.027801031901154696, (float)0.14701269036280384, (float)0.04253694415732753, (float)-0.20277204215807929, (float)-0.2595848993474817, (float)-0.057360920488596964, (float)0.13487738207359806, (float)0.10882313157422575, (float)-0.06875624886867081, (float)-0.161543493821189, (float)-0.06273938515058235, (float)0.014657432856013255, (float)-0.08063334317659725, (float)-0.11696408372045723, (float)-0.0026946422825232484, (float)-0.039044785049057416, (float)-0.21649264965353082, (float)-0.16520379667713683, (float)0.026581222520931643, (float)0.03374982654130529, (float)0.06268680941655018, (float)0.2948087536107164, (float)0.28264648049649815, (float)-0.12354705101400948, (float)-0.2768430825149201, (float)0.09706111340421185, (float)0.38176412649216745, (float)0.2049994568807272, (float)-0.010587374145243522, (float)0.07936139420873796, (float)0.23038336815689764, (float)0.14862718080549592, (float)-0.07510043003820817, (float)-0.16518427702552646, (float)-0.01611816231973391, (float)0.16295447169903643, (float)0.08667190528288905, (float)-0.1691905652837757, (float)-0.23911162033250502, (float)-0.05371943686685997, (float)0.05684395827250665, (float)-0.10145415774502342, (float)-0.3456255842842285, (float)-0.3959277472300413, (float)-0.17505274516341623, (float)0.08723980195134576, (float)0.10513569312632791, (float)-0.030961904012532546, (float)-0.025239740523119607, (float)0.0726092317965854, (float)0.046470674351500284, (float)-0.005250079036868087, (float)0.06949440570281105, (float)0.15748136866116624, (float)0.1512264193928985, (float)0.058794668416383276, (float)-0.1121296421695252, (float)-0.21670422127623404, (float)-0.08103588820242183, (float)0.17229649390111718, (float)0.3275935627896498, (float)0.3161344328911661, (float)0.09615484808365019, (float)-0.14543997130206088, (float)-0.03274986769060655, (float)0.209316512487178, (float)-0.006864265571449971, (float)-0.3871945893906754, (float)-0.24320745145574624, (float)0.08713901627457407, (float)-0.03450780657507958, (float)-0.24101957848124297, (float)-0.014173255527983781, (float)0.2998672034556947, (float)0.24994367191273748, (float)-0.03622082702201393, (float)-0.2543287277166832, (float)-0.2635273819457042, (float)-0.09133312398553771, (float)0.12407046130886913, (float)0.2852659905535166, (float)0.29941317418562347, (float)0.07804992823308264, (float)-0.1530386449255824, (float)-0.08696898761907453, (float)0.08135308638501974, (float)0.07974424890869318, (float)0.09301368286971474, (float)0.13426071954153895, (float)-0.10723873334174222, (float)-0.38992593826962085, (float)-0.21581617628586808, (float)0.12254271051158154, (float)0.06883781962933856, (float)-0.2228560479609335, (float)-0.32491106243401524, (float)-0.15771064616421818, (float)0.1069868361950276, (float)0.17767154946461164, (float)-0.014391433152301635, (float)-0.06584225081387472, (float)0.13752983158306997, (float)0.10131224292838904, (float)-0.14481591837951655, (float)0.02977939952662433, (float)0.4178673650416841, (float)0.2794863978398414, (float)-0.07346334629929868, (float)0.05572609430638101, (float)0.265739357289455, (float)0.007869853426088263, (float)-0.2444783462884309, (float)-0.10348008226773474, (float)-0.001090449553214847, (float)-0.1041468645674465, (float)-0.08378855816807552, (float)-0.024489123952252893, (float)-0.1646345878914109, (float)-0.24458892353656808, (float)-0.09827109001422064, (float)0.01658986877274729, (float)0.07812925089778637, (float)0.2155290546145842, (float)0.20778013948380317, (float)0.021132552978056555, (float)0.04120653973389732, (float)0.21042151503431353, (float)0.1129822434369918, (float)-0.0741908188009838, (float)0.02405272419100471, (float)0.16290460936715004, (float)0.04790545264033261, (float)-0.15369961912020216, (float)-0.3060225223999422, (float)-0.3477136492251951, (float)-0.09177441085888435, (float)0.2418429588643855, (float)0.1312992500337823, (float)-0.2319372691009574, (float)-0.21655847881106335, (float)0.065022457896864, (float)0.09048361564649815, (float)-0.06743907086431013, (float)-0.1082562266105134, (float)-0.10700934738984047, (float)-0.08724687876539955, (float)0.12463866393933373, (float)0.36329833861973404, (float)0.31344500188744734, (float)0.10419678566058789, (float)-0.03700425508219536, (float)-0.202230322004218, (float)-0.29437241675637604, (float)-0.006255346766994667, (float)0.34867450454776416, (float)0.20361504647980333, (float)-0.10614730998576156, (float)0.020204710306104785, (float)0.21042040755788785, (float)-0.03971845917381345, (float)-0.32584176246999536, (float)-0.2670223995449698, (float)-0.11179414100120853, (float)0.05699162085131454, (float)0.275347458143607, (float)0.19946017806265254, (float)-0.15119398978620952, (float)-0.18591515068139838, (float)0.1006361308796572, (float)0.1547961081675667, (float)-0.025436297791116683, (float)-0.08867070233290253, (float)-0.013864497939250526, (float)0.13174365774201513, (float)0.24485314046820442, (float)0.0433136712989753, (float)-0.3430742682081842, (float)-0.35027773616261626, (float)0.007120613996177785, (float)0.13794534774730682, (float)-0.06729651015413632, (float)-0.17250995153200832, (float)-0.004399657651812512, (float)0.16936573025061116, (float)0.12352003350659897, (float)-0.02749557756710812, (float)-0.08711100175812778, (float)-0.09421973797579199, (float)-0.08071723440739957, (float)0.106920584315332, (float)0.35779062516318594, (float)0.30756619754706105, (float)0.016366405799092865, (float)-0.13869034376182185, (float)-0.09827983207647956, (float)-0.018145377406605483, (float)-0.0018968701766361874, (float)-0.10558667261324757, (float)-0.12589913919233012, (float)0.13582639265508611, (float)0.2755230948892285, (float)-0.05121416854328833, (float)-0.36001577418084924, (float)-0.27406123428826296, (float)-0.10845653667143171, (float)0.014543925493737307, (float)0.18134008752089895, (float)0.13870523389339698, (float)-0.05556863367328713, (float)0.00816043713201216, (float)0.08944306284622669, (float)-0.13214280198265482, (float)-0.18124960430839937, (float)0.10545286071614667, (float)0.19193441623640461, (float)0.11268909557613162, (float)0.189752922318549, (float)0.12415454807512852, (float)-0.0856647641508623, (float)0.01583972478028038, (float)0.103497935846216, (float)-0.20254361904075027, (float)-0.2631822750223623, (float)0.08541333963514491, (float)0.03867731404092981, (float)-0.2615372777389762, (float)-0.02652463046903675, (float)0.2844364044848994, (float)0.021909299929753687, (float)-0.13970759985424497, (float)0.2156969325500242, (float)0.2784588116746624, (float)-0.18632046161267432, (float)-0.32805009664113616, (float)0.07544841992188706, (float)0.31245656779987363, (float)0.10514140597770742, (float)-0.09304145304246142, (float)-0.02916343768890945, (float)-0.0006851970264294592, (float)-0.21945563441705235, (float)-0.38312282958669774, (float)-0.2191074152657737, (float)-0.007605862734787756, (float)-0.03881905714795556, (float)-0.08182295735312606, (float)0.06026538802965614, (float)0.16584692389060224, (float)0.15106559812632614, (float)0.17127252688060585, (float)0.11862821582832542, (float)-0.07682690035830785, (float)-0.04629107473125319, (float)0.2627820934618635, (float)0.29597379204423013, (float)-0.022890898243597524, (float)-0.1585878319860381, (float)-0.08642027513748853, (float)-0.12493094248645381, (float)-0.0943514377253418, (float)0.08394863752571843, (float)0.0422469854927441, (float)-0.062483397779237185, (float)0.18013459201285723, (float)0.3529896071380566, (float)0.09025396248849869, (float)-0.09269569419743454, (float)-0.070890918479711, (float)-0.2940365190386698, (float)-0.4304155345388484, (float)-0.05498957996230352, (float)0.17663442026144877, (float)-0.09677501667151613, (float)-0.21349281676664586, (float)-0.03092418483576925, (float)0.023398724811843685, (float)0.10355346955419434, (float)0.2761119731341683, (float)0.12883096837724387, (float)-0.059418376630739365, (float)0.2210246389674839, (float)0.410235125560816, (float)0.0027499920071376014, (float)-0.33667201797144286, (float)-0.14663002352606005, (float)0.05256927673381249, (float)-0.07517919011648017, (float)-0.2244826630382515, (float)-0.15583384267183034, (float)-0.006275128386923481, (float)0.0024138685951246423, (float)-0.04839713518178395, (float)0.08308417049613119, (float)0.2030374461077307, (float)-0.0074054447495914425, (float)-0.22422956684581466, (float)-0.1020541811438995, (float)0.020440786342381098, (float)-0.04582335559813854, (float)-0.01850458045355722, (float)0.052395723712210164, (float)0.0017022151113073672, (float)0.033188744743059995, (float)0.11478740039376865, (float)0.05969153805272132, (float)0.1477308035537293, (float)0.3951499879967571, (float)0.28050475832965627, (float)-0.045646869989879824, (float)0.012878162967116379, (float)0.21004283628197498, (float)0.06591207910509674, (float)-0.2058658135889171, (float)-0.33213688770979233, (float)-0.2830828446178369, (float)-0.06461973210950023, (float)-0.016097884246829283, (float)-0.26499962929680027, (float)-0.16552623534023167, (float)0.3097448122108723, (float)0.2119997861117283, (float)-0.314775151406562, (float)-0.19813887155078952, (float)0.25687041280160156, (float)0.12138097665848833, (float)-0.16677324660636822, (float)-0.005224210447800779, (float)0.07923710156923625, (float)-0.19771720018955638, (float)-0.2908029639013852, (float)-0.004499057278682063, (float)0.29808850072758936, (float)0.3125427579461525, (float)0.021308296525361523, (float)-0.17765367201691604, (float)0.02718840569302465, (float)0.15432911089825183, (float)-0.1530333273663285, (float)-0.2249877544089968, (float)0.23859295426545038, (float)0.38455027540755665, (float)-0.03508063167913426, (float)-0.17009073507041547, (float)0.10329860364369509, (float)0.09607452727452534, (float)-0.09745395295436218, (float)0.014116190339621129, (float)0.11969060934546989, (float)-0.06678799356135542, (float)-0.07301028484115289, (float)0.16529504398201453, (float)0.04250588271446047, (float)-0.3458249428521106, (float)-0.31642566616138124, (float)0.052559021236864754, (float)0.2346333620975344, (float)0.2078510955551852, (float)0.05262797656276143, (float)-0.2501021007906521, (float)-0.3161475729742811, (float)0.053390299546722524, (float)0.3125288949060897, (float)0.20392287590046843, (float)0.09485467160045313, (float)-0.037795063320445306, (float)-0.3215458701991825, (float)-0.2669874180701628, (float)0.15970301735192005, (float)0.16128471809751657, (float)-0.27738032328652074, (float)-0.32287234061093123, (float)0.036018333068356966, (float)0.15027145599963854, (float)0.003928526536085448, (float)-0.03105348074571982, (float)0.08242772678692663, (float)0.1840837757939306, (float)0.15691660041055155, (float)0.04285640046258789, (float)0.004001779542515662, (float)-0.022653138920415948, (float)-0.12601028029751898, (float)-0.032692416173625706, (float)0.2440111332507365, (float)0.196769742201545, (float)-0.06268716960590662, (float)0.01865890848752602, (float)0.1394143166600825, (float)-0.1289469174393903, (float)-0.21633212917911826, (float)0.1732488888214024, (float)0.3217618245928518, (float)0.0144033927655187, (float)-0.19342686788561547, (float)-0.2507722567773963, (float)-0.3511822265656018, (float)-0.23177521536697615, (float)0.08323757224475742, (float)0.12317799515218135, (float)-0.08231438087322035, (float)-0.15221508814780077, (float)-0.08945649905848221, (float)-0.0076142444077990255, (float)0.13147430783317818, (float)0.19753642072349173, (float)0.057914442958585124, (float)-0.09131278286087752, (float)-0.03605266346862695, (float)0.17508028961120925, (float)0.3565672011687931, (float)0.30906111801251807, (float)0.03719754649094102, (float)-0.15142167391521835, (float)-0.11970827982058395, (float)-0.10054497005560459, (float)-0.13155362918953983, (float)-0.027349541095253362, (float)0.022175051794502125, (float)-0.18200475280457215, (float)-0.2128981307211196, (float)0.14313161293443416, (float)0.2588456399495597, (float)-0.0580188196333469, (float)-0.07634908157264797, (float)0.26387024736569353, (float)0.19395149950907328, (float)-0.1458143286497815, (float)-0.049629814756501606, (float)0.1010013290958948, (float)-0.23611077947095335, (float)-0.415896834221705, (float)-0.034819121680345615, (float)0.16078049438324396, (float)-0.09881258450687537, (float)-0.20007513694541396, (float)-0.04785043938707846, (float)0.030424209656067354, (float)0.1404446936238073, (float)0.3294044457730418, (float)0.3252853778190521, (float)0.14411703446055416, (float)-0.049566108018831566, (float)-0.23495543374317973, (float)-0.19318353113656891, (float)0.15520966103041944, (float)0.2827174204248828, (float)-0.04293752561383367, (float)-0.2520837691612473, (float)-0.1060148221824159, (float)-0.07037669924217448, (float)-0.20986499471103517, (float)-0.056928677422059495, (float)0.32328952473753464, (float)0.3346521020451206, (float)-0.03884185078312618, (float)-0.16841566904954164, (float)0.05185865577360109, (float)0.06914192264423866, (float)-0.13280178302054585, (float)-0.058433507737039966, (float)0.08591123600414714, (float)-0.16256100854220204, (float)-0.33741224619296606, (float)0.019111543458282306, (float)0.34151241057754855, (float)0.2452646910056433, (float)0.10208650487534429, (float)-0.019615783721593297, (float)-0.1975848561490072, (float)-0.07444334820522584, (float)0.1923046719561952, (float)-0.03094404903395728, (float)-0.39632918701163083, (float)-0.2065511351058964, (float)0.09371498788068498, (float)-0.033086666873546944, (float)-0.11816367449215112, (float)0.10869486454850677, (float)0.18823197280031484, (float)0.03333880456068164, (float)0.024009130755135322, (float)0.1871508015004418, (float)0.22463770389079565, (float)0.03185326370614808, (float)-0.15092079382703097, (float)-0.08034600009283749, (float)0.0557899337627106, (float)0.0035649962015764603, (float)-0.008894609018992196, (float)0.1407545558258028, (float)0.10107402812922263, (float)-0.08690947134360108, (float)-0.02817939438824889, (float)0.06840841037960901, (float)-0.10026518802444864, (float)-0.2082654093889526, (float)-0.13539811635198717, (float)-0.17604749377462273, (float)-0.19364944270544385, (float)-0.007678593274483145, (float)0.07937574428919279, (float)0.05806812518280305, (float)0.19165447218661635, (float)0.2277058663981729, (float)-0.007542559595462235, (float)-0.10877034665301404, (float)0.01623545130837104, (float)0.048612756933619, (float)-0.017004138460462358, (float)-0.0852114531681784, (float)-0.1233435821552741, (float)0.07797141494515553, (float)0.3493212293916549, (float)0.17456705088560814, (float)-0.20852355823444044, (float)-0.21868674720376652, (float)-0.04684269448820266, (float)0.05728917246184561, (float)0.26913730529222396, (float)0.3151729199429013, (float)-0.05281754637488299, (float)-0.251204823881618, (float)-0.09102526273447824, (float)-0.14793432238256393, (float)-0.28810213324100853, (float)-0.03847012308232939, (float)0.17113436968712462, (float)0.04067522065033221, (float)0.033716288919845294, (float)0.10618443325375695, (float)-0.09957511503248317, (float)-0.20009811519177417, (float)0.009271170372306882, (float)0.016427388861181096, (float)-0.16486260959779248, (float)-0.05082994789244704, (float)0.20956741295165646, (float)0.26220381754792366, (float)0.1509488117155495, (float)-0.05672732133052032, (float)-0.1852175971176725, (float)0.023506613956339233, (float)0.22495818140370002, (float)0.005972399747687745, (float)-0.18196220346693673, (float)0.04140577394707377, (float)0.21276762408384375, (float)0.09290581605688723, (float)-0.003922388067488954, (float)-0.06790084498880769, (float)-0.172814754638222, (float)-0.05952353598440678, (float)0.16019077445404373, (float)0.02361724442060295, (float)-0.3067727900196856, (float)-0.2811761506250743, (float)0.06947297326945731, (float)0.3037393248976176, (float)0.26735742833498194, (float)0.12140865281066741, (float)-5.6862965070399265e-05, (float)-0.1326047907035447, (float)-0.3000169446496221, (float)-0.34218764031283033, (float)-0.1773445222568478, (float)-0.014622588781853142, (float)-0.004533744172970467, (float)-0.020839779968521564, (float)0.05406362769220532, (float)0.17251357004757734, (float)0.20850664725276732, (float)0.0886542821556268, (float)-0.01727422056821038, (float)0.07529222945175958, (float)0.1191192382380652, (float)-0.09320660652841974, (float)-0.1436738276892751, (float)0.20100726106343048, (float)0.38546977884826394, (float)0.13202682600874102, (float)-0.05439888356810088, (float)0.032986089893450886, (float)0.014392277097565062, (float)-0.1971062576926795, (float)-0.30771751090611643, (float)-0.18525594313733898, (float)0.07467263510477996, (float)0.23971578399387386, (float)0.11300834704507721, (float)-0.12190852448054695, (float)-0.15092513246286862, (float)-0.0630822660495496, (float)-0.08458871823235714, (float)-0.1670039169073907, (float)-0.21043542411521576, (float)-0.16119861762900034, (float)0.06718192230870029, (float)0.29131961884635116, (float)0.1654428871942608, (float)-0.14209055032739365, (float)-0.1430591849594994, (float)0.11079503457105748, (float)0.19288219007178492, (float)0.10708834712887656, (float)0.14433168323082746, (float)0.1926542834745824, (float)-0.052511195098364424, (float)-0.3367755133628583, (float)-0.15600336582865665, (float)0.22525170192746674, (float)0.15895536654052475, (float)-0.11275581355030227, (float)0.0030163498422697507, (float)0.13286276282840942, (float)-0.1617488399904685, (float)-0.2477680920111701, (float)0.1751331910497039, (float)0.2564486548111147, (float)-0.20205777103585493, (float)-0.30513401869905676, (float)0.08929293660921934, (float)0.29773347950353973, (float)0.21458711419607798, (float)0.048405158555958665, (float)-0.23500351190841076, (float)-0.3353992474067265, (float)0.011139358248469825, (float)0.23695455912467528, (float)-0.015674840255470734, (float)-0.11243535005612677, (float)0.21376808959410185, (float)0.30162327748171974, (float)-0.058516419202998146, (float)-0.3113609677627049, (float)-0.2559243236273165, (float)-0.1338711252649113, (float)0.03850219463897214, (float)0.24858839818500103, (float)0.1835308008675115, (float)-0.16806688365811903, (float)-0.28378118802585306, (float)0.029987935895299495, (float)0.2959428081963775, (float)0.23154426300233516, (float)0.07107579119526652, (float)-0.09724293733387084, (float)-0.30028094101313574, (float)-0.2543748052413076, (float)0.042976631138017245, (float)0.09393264133118594, (float)-0.08141676662296207, (float)-0.025891622091163108, (float)0.07746183855019052, (float)-0.03564119647362618, (float)0.03292689412149707, (float)0.24595928881103005, (float)0.012616349646288836, (float)-0.3370895736717113, (float)-0.13473791967406623, (float)0.16530084330968808, (float)0.09737274067337105, (float)0.12239330013383763, (float)0.2875885831622265, (float)0.1520376397376732, (float)-0.0047329786507940876, (float)0.07454475305162496, (float)-0.037186087082310006, (float)-0.2216878695285025, (float)0.0109480367653545, (float)0.23342267929110694, (float)0.04200966218552477, (float)-0.05558506071128801, (float)0.02958569029392783, (float)-0.1455754411308393, (float)-0.2780182159756366, (float)-0.04406249339913971, (float)0.031076199316774224, (float)-0.17719747423576238, (float)-0.16683491544177353, (float)-0.07203329121915894, (float)-0.17064799221351734, (float)-0.040818465696614493, (float)0.3469202173712287, (float)0.36185698978057035, (float)0.07192544059701447, (float)0.02468647080642818, (float)0.059310093513138366, (float)-0.13176804813682408, (float)-0.24738166667815306, (float)-0.11646601181110317, (float)-0.03708449835198875, (float)-0.07786013168136975, (float)-0.04197912461073627, (float)0.0053318185886443575, (float)-0.09002858044028642, (float)-0.1527164120348308, (float)0.045354303455447276, (float)0.32562980633771327, (float)0.34580825061115456, (float)0.13120466362358887, (float)-0.04940975291776028, (float)-0.11625599884786206, (float)-0.09520910015133006, (float)0.01503972562586283, (float)0.05453328955726286, (float)-0.06294525989881732, (float)-0.036540953104487274, (float)0.2436660491385486, (float)0.3514940791026905, (float)0.1384662805836957, (float)-0.01530029870867306, (float)-0.04049217000042894, (float)-0.1609045805576184, (float)-0.20090371504292726, (float)-0.00989745894255316, (float)0.029829129299710728, (float)-0.18100660613015285, (float)-0.12684567802970811, (float)0.20936332023894186, (float)0.17552806500794305, (float)-0.21138028698541536, (float)-0.20910013431676483, (float)0.16654565760457735, (float)0.17151109829604677, (float)-0.16402740340797012, (float)-0.2075547047484777, (float)-0.08253704477539438, (float)-0.2124795621574563, (float)-0.24463710716895087, (float)0.08361128018265623, (float)0.20120574132385866, (float)-0.08157178442443552, (float)-0.17916822647780056, (float)-0.008714007026627129, (float)0.0360710525696256, (float)0.10037715961460181, (float)0.3459139268636561, (float)0.3422406622765654, (float)-0.0010716225217378566, (float)-0.17192854578439384, (float)-0.08459836282022605, (float)-0.09462320286508402, (float)-0.1858904871628643, (float)-0.1040220941823133, (float)0.13327578423558373, (float)0.30462844671257544, (float)0.2324917195962488, (float)-0.002046455346688256, (float)-0.07743201855887315, (float)0.07980914718444816, (float)0.17147221206771, (float)0.07786754880704114, (float)-0.010207126429117235, (float)0.03026931441872471, (float)0.1487575142566625, (float)0.15410362267016686, (float)-0.09166592184253691, (float)-0.2656063081848886, (float)-0.024366956981590294, (float)0.18425754934439748, (float)-0.09432302519744248, (float)-0.30787179512362073, (float)-0.0438435859234261, (float)0.043594671854004466, (float)-0.29743450571149194, (float)-0.30258446737602235, (float)0.11611066196853757, (float)0.12857382480840474, (float)-0.27810038832858985, (float)-0.34675492820788106, (float)-0.0749545041964928, (float)0.03481833837975507, (float)0.07828197530226612, (float)0.2892580673923274, (float)0.36344789311938636, (float)0.11335757887839008, (float)-0.13073238469663692, (float)-0.19833076085429013, (float)-0.2346288793503386, (float)-0.15143501166494816, (float)0.16325396949658635, (float)0.3597666694090566, (float)0.18667433855193438, (float)0.005417127489101969, (float)0.08141029989062992, (float)0.12508264834439844, (float)-0.013799795086499011, (float)-0.07110558678550177, (float)0.02427665332274695, (float)0.07137151416963053, (float)0.042067787526497064, (float)0.037231853257490975, (float)0.07378434389133315, (float)0.14697199115568305, (float)0.19480766133647787, (float)0.11254308050986274, (float)-0.031546976302202434, (float)-0.13826437757459292, (float)-0.28199424641731097, (float)-0.36028001397672016, (float)-0.10345849231587617, (float)0.23433937936306173, (float)0.1122465103924795, (float)-0.27324420486598755, (float)-0.3195274044312157, (float)-0.11015782365339533, (float)-0.035106712567645, (float)0.025014803063116108, (float)0.15808070610108846, (float)0.051971403812327135, (float)-0.2000262939051089, (float)-0.11897124497607682, (float)0.16873669465749427, (float)0.17851143572985587, (float)-0.011653940040290108, (float)-0.09072745752645076, (float)-0.05731992281627864, (float)0.09717448188741756, (float)0.32102822515494756, (float)0.23127613618349943, (float)-0.1717994459425098, (float)-0.2688947186496515, (float)0.047418739237135986, (float)0.19867015655858666, (float)0.06669845145079668, (float)0.004777378274573619, (float)0.01573110702017402, (float)-0.02966524987027056, (float)-0.031173181241742485, (float)-0.02576979754533008, (float)-0.12860056759932728, (float)-0.187556278050588, (float)-0.08308515018690028, (float)0.092383366602975, (float)0.27426333213391546, (float)0.3119227981036137, (float)0.033366102388151485, (float)-0.2628958229036159, (float)-0.149413229174556, (float)0.17277997775534049, (float)0.250519647269702, (float)0.06949301117363424, (float)-0.1564182192614722, (float)-0.28749800331444786, (float)-0.21736739624494117, (float)-0.011583550840848847, (float)0.08645014231751494, (float)-0.013423842763720013, (float)-0.14079738365023348, (float)-0.06494208056839242, (float)0.18441558465320346, (float)0.20647697571931334, (float)-0.11779783866269858, (float)-0.20348938628155033, (float)0.1942381062340455, (float)0.36781686757082843, (float)-0.017592206689097844, (float)-0.2993667622888849, (float)-0.11243453449881471, (float)0.15398102330745536, (float)0.2113872217256619, (float)0.021971615351235426, (float)-0.3116191228263994, (float)-0.35076200387273293, (float)0.020160320983924482, (float)0.17908100695282667, (float)-0.05965564354509853, (float)-0.0909095982146121, (float)0.1311391705159067, (float)0.0608849570107286, (float)-0.1496743127098289, (float)0.023766546043340844, (float)0.3563484774736767, (float)0.3257884775081124, (float)0.012986678631731408, (float)-0.1627356422047844, (float)-0.08187641964427982, (float)0.015241815350527358, (float)-0.04202186023747434, (float)-0.06709309367941753, (float)0.060818272352648195, (float)0.04010567377038233, (float)-0.23347282313495504, (float)-0.3294545788214487, (float)-0.1074178061065874, (float)0.04451708153544896, (float)0.07687553530153655, (float)0.26232356288254316, (float)0.3740797605500157, (float)0.061691746621510696, (float)-0.2811585949723233, (float)-0.11962772839717702, (float)0.23560502571944458, (float)0.2011776572463845, (float)-0.053621602531511506, (float)-0.017022865473845013, (float)0.20264530894721794, (float)0.13091489483235164, (float)-0.18076350779799477, (float)-0.2560135063303204, (float)-0.04742609304779518, (float)-0.014488883673867884, (float)-0.2807562882572025, (float)-0.3850911096959696, (float)-0.14841753772871458, (float)-0.0005865649946663055, (float)-0.05362209918238589, (float)0.0842156248448195, (float)0.2739323372852831, (float)0.07658119068527659, (float)-0.0864658043412341, (float)0.2296633650947645, (float)0.32542938703700786, (float)-0.15767149768610708, (float)-0.2954445467552431, (float)0.1494060814688944, (float)0.270133738917818, (float)0.06568668365423005, (float)0.17365063784317347, (float)0.219866318146473, (float)-0.08787695929119345, (float)-0.05564730164234403, (float)0.2502582958124681, (float)-0.006475379753716566, (float)-0.4292327815773404, (float)-0.20342484399136235, (float)0.09614026762861874, (float)-0.11472392541056341, (float)-0.1818496521271208, (float)0.1441080506274641, (float)0.13548548808202027, (float)-0.2583189980380552, (float)-0.34168855511147295, (float)-0.0997708688332395, (float)0.002303401695712092, (float)0.04773630079280975, (float)0.2464325836100412, (float)0.2520924191735239, (float)-0.11914007725905175, (float)-0.2975144595065776, (float)0.05667203823256637, (float)0.3776397367885421, (float)0.23759494809965312, (float)-0.005912177898529258, (float)-0.08072778922855009, (float)-0.12545872911059316, (float)-0.11213577658738674, (float)0.0026394068131787574, (float)0.04292099201189822, (float)0.07152558667948958, (float)0.18606987671714706, (float)0.08980265644777138, (float)-0.18748531499264465, (float)-0.12769884035782894, (float)0.17324277404529748, (float)0.1623499297535648, (float)-0.0635710439827618, (float)-0.13792920543186743, (float)-0.11624215485913074, (float)-0.05981531033151214, (float)0.0292900139226021, (float)-0.015806954687019883, (float)-0.08086646519299702, (float)0.04454756904911465, (float)0.055245912850303704, (float)-0.15522954159915597, (float)-0.06026915762446084, (float)0.30886916528504327, (float)0.24327974788765427, (float)-0.20657017484053405, (float)-0.2966183453835102, (float)0.05670959627694135, (float)0.27403568099860365, (float)0.11947876676215585, (float)-0.08786883454512823, (float)-0.11142061990288514, (float)-0.11323303846603769, (float)-0.12826250383428164, (float)0.06396282842989477, (float)0.17958092901381653, (float)-0.18857672273382017, (float)-0.42847228528838127, (float)0.002129175560717929, (float)0.2620889877645265, (float)-0.09219634261893929, (float)-0.11429517295589245, (float)0.299401154351351, (float)0.21072078192649846, (float)-0.11046271605643465, (float)0.059674748258550896, (float)0.1780188646157253, (float)-0.0711413158358525, (float)-0.01102075069553098, (float)0.2623735538948103, (float)0.13107887392107376, (float)-0.0676775148846391, (float)0.02058647122180923, (float)-0.0017611711079933824, (float)-0.18080979486504584, (float)-0.1973740874736334, (float)-0.13275204043966707, (float)-0.05742639163672787, (float)0.08257675523096289, (float)0.0724811291149702, (float)-0.08174110150152436, (float)-0.07410547743476521, (float)0.034073589468229123, (float)0.10078453087781591, (float)0.187805408714178, (float)0.07922051136049564, (float)-0.24143344412879664, (float)-0.17905003879429443, (float)0.26103779495465795, (float)0.33282858034631607, (float)0.05330053187032226, (float)-0.014683383701546062, (float)0.006256963690229665, (float)-0.17857384536313778, (float)-0.3599787708380928, (float)-0.3508887106417149, (float)-0.19696069422940457, (float)-0.025175966618940303, (float)-0.01735778713217642, (float)-0.04079489940416418, (float)0.15411204929788697, (float)0.25584846130638905, (float)0.042514857417589556, (float)-0.017710688185591388, (float)0.1659748800192085, (float)0.15903926183029762, (float)0.08723393091745538, (float)0.11869328879582784, (float)-0.10079579641235839, (float)-0.3242909122698263, (float)-0.014889174419968666, (float)0.2782381488180185, (float)0.054803835718772786, (float)-0.06363806629381509, (float)0.10245134188882209, (float)0.0028081866333178715, (float)-0.15971856728546113, (float)-0.0051596527440671315, (float)0.08771855531989221, (float)0.03870660326632771, (float)0.14178943181549486, (float)0.09543187603769847, (float)-0.19750127405989407, (float)-0.16766832623648115, (float)0.1139181850868858, (float)0.11691897017256904, (float)0.060505686062196466, (float)0.18348714063459823, (float)0.10777495802377439, (float)-0.15527349768508233, (float)-0.21334750902698593, (float)-0.14672182557310867, (float)-0.09733331199457523, (float)0.01914659402710308, (float)-0.000479894248558688, (float)-0.24066435937735464, (float)-0.26871464335347806, (float)-0.009940496467859305, (float)0.07226074828057184, (float)-0.08851145601619989, (float)-0.1815686485731518, (float)-0.1564938792764122, (float)-0.09729495467592388, (float)-0.003833600153250047, (float)0.0956747986927653, (float)0.19489700713071456, (float)0.2835338813040461, (float)0.279353716155607, (float)0.2439874172418295, (float)0.290851602689866, (float)0.27164138606256677, (float)0.10240654032591283, (float)0.023059635438158588, (float)0.07807834714125311, (float)0.0246147527996162, (float)-0.09102153252768407, (float)-0.06898008998758161, (float)-0.06695243811324723, (float)-0.25600300739443643, (float)-0.41517029986904763, (float)-0.36076896021379234, (float)-0.2251801587260666, (float)-0.09448334660419168, (float)0.06440430346601589, (float)0.13324546194636977, (float)0.024511783543738345, (float)-0.04807430625391694, (float)0.07418943560264996, (float)0.17754670545931295, (float)0.07047524038950043, (float)-0.07006023918982361, (float)0.004505088166405346, (float)0.24475884421364547, (float)0.3348726262668706, (float)0.09402684653104473, (float)-0.14469197531372727, (float)0.01679368005440985, (float)0.2560573384306873, (float)0.09346456871662794, (float)-0.12107803930751813, (float)-0.023932850784534287, (float)-0.09393782230651024, (float)-0.4320159016589786, (float)-0.31987263070009125, (float)0.13538375979921347, (float)0.06947579835345107, (float)-0.32679942278332774, (float)-0.31358687500082266, (float)-0.10369660203855471, (float)-0.05100950828686276, (float)0.10191906367335972, (float)0.2546138444023424, (float)0.0884208034326206, (float)0.004287528087142569, (float)0.29061862498625124, (float)0.4230446339932055, (float)0.19196212987108396, (float)0.047760683522750605, (float)0.09038962269750672, (float)0.05549348021348325, (float)-0.036720917998462776, (float)-0.0474607588033608, (float)-0.03906651812840667, (float)-0.1526441612107546, (float)-0.3470912329858735, (float)-0.28388691718111797, (float)0.10525284525190678, (float)0.18755092677539906, (float)-0.23440662747698524, (float)-0.28637956970695067, (float)0.22453852526557613, (float)0.2531284845805572, (float)-0.25517625537045374, (float)-0.19106050721445644, (float)0.30159466774500426, (float)0.2120402093449906, (float)-0.11580568801628334, (float)0.05303586010804959, (float)0.18679932396826243, (float)-0.0761001709521023, (float)-0.05680018155996367, (float)0.23834384743522313, (float)0.05005669144043561, (float)-0.345090685459329, (float)-0.18666012006706642, (float)0.1649238109548777, (float)0.10798989408731431, (float)-0.02510268263177774, (float)0.08933190438875954, (float)0.16946672715428998, (float)0.13580947987867228, (float)0.13219204149319316, (float)0.0121843036037543, (float)-0.21381673903490156, (float)-0.23691238941390977, (float)-0.15294943761641921, (float)-0.2377756741466912, (float)-0.27979682176688736, (float)-0.12442206777599377, (float)-0.052645416441184485, (float)-0.04607604987031667, (float)0.13474179556470037, (float)0.22057983658582886, (float)0.024887574586617965, (float)-0.01821410629767262, (float)0.15981998054185043, (float)0.09822098263096797, (float)-0.03523354100006854, (float)0.19855245269810456, (float)0.3678862177117383, (float)0.036896917829099256, (float)-0.2397104425485517, (float)-0.09147231907583724, (float)-0.03605789614073364, (float)-0.22550088539004207, (float)-0.14132327330551148, (float)0.19020926354678222, (float)0.24181705030063003, (float)0.08862819178226143, (float)0.15094402573869897, (float)0.2578711574053953, (float)0.03379708119108733, (float)-0.26770519876775517, (float)-0.1720920399329359, (float)0.173329214877139, (float)0.24540132349805707, (float)-0.029114828308124067, (float)-0.2428966110882067, (float)-0.17411761920840826, (float)-0.03961940527716302, (float)-0.08037941962233475, (float)-0.21402248621959508, (float)-0.2125431222465765, (float)-0.051158259354141956, (float)0.08553741386111548, (float)0.07348072182930289, (float)-0.04337353773044035, (float)-0.1604237534867089, (float)-0.1840379483650146, (float)-0.0946741412818359, (float)-0.0018815842201297674, (float)0.036645854125204436, (float)0.1456593837881783, (float)0.31028620273845176, (float)0.25408704805127336, (float)-0.016409304117116795, (float)-0.11414080481664587, (float)-0.016836595210388324, (float)-0.07043401077054759, (float)-0.13233556281540004, (float)0.15870213963611285, (float)0.42738976080617674, (float)0.20680060824447152, (float)-0.04199791763640506, (float)0.10086878566877118, (float)0.14248172412844362, (float)-0.09666538871876894, (float)-0.06010967936216233, (float)0.11063934321898918, (float)-0.17270330155390215, (float)-0.4126948880864217, (float)-0.02143984939903857, (float)0.2461275867395136, (float)-0.08930963921074524, (float)-0.17066447225368025, (float)0.21059639005158515, (float)0.1589069661533174, (float)-0.28821367699647304, (float)-0.3287641206286259, (float)-0.10085812810474046, (float)-0.07145509895445329, (float)-0.042688615036251855, (float)0.0459319228661967, (float)0.0036346461186488517, (float)0.09132459919244373, (float)0.34205014363191705, (float)0.2135093652269003, (float)-0.18879684107894856, (float)-0.1857861743120374, (float)0.07939993860408308, (float)0.018704979881761792, (float)-0.20058169125541028, (float)-0.1282109745190207, (float)0.14611744830627127, (float)0.28947186152546645, (float)0.16824860787798318, (float)-0.06032041011128121, (float)-0.10315756457691583, (float)0.00792956101259044, (float)-0.011088137548359975, (float)-0.06905475167783749, (float)0.0458534363138642, (float)0.06175421506708838, (float)-0.20054292791335218, (float)-0.3146471753234007, (float)-0.03047211831555148, (float)0.27956463182570784, (float)0.2684321235955921, (float)-0.0027171139407468213, (float)-0.23583891876704535, (float)-0.13705175011862147, (float)0.19836512957290628, (float)0.322158633057632, (float)0.137421660326813, (float)-0.002924411637155201, (float)0.02484316314160946, (float)0.034180376518113335, (float)-0.03808348654231994, (float)-0.12753072799908194, (float)-0.15982055028528608, (float)-0.04652132202162187, (float)0.122888873206073, (float)0.1175550387424178, (float)-0.04936323017374747, (float)-0.16562542889809348, (float)-0.15675756620895148, (float)-0.06660835781268354, (float)0.007971167886312625, (float)-0.06119654367749974, (float)-0.16284551407832268, (float)-0.06391885383701527, (float)0.05916030608355349, (float)-0.0774237019210581, (float)-0.189105075820011, (float)0.06261304486093663, (float)0.35357724058630885, (float)0.29555095165271306, (float)0.040907561392886566, (float)-0.1688759447185256, (float)-0.23341539158322339, (float)-0.0061912598047026675, (float)0.32902562492974313, (float)0.23831557804833076, (float)-0.19493617597955756, (float)-0.26151303847589624, (float)0.0838052806794064, (float)0.18764406453868782, (float)-0.019444316606747974, (float)-0.04929232278940053, (float)0.08051457208815828, (float)0.01830890404486317, (float)-0.13551168032203467, (float)-0.10904641211998517, (float)0.037353341859635646, (float)0.16821462265924889, (float)0.2498390664386807, (float)0.18775625360884965, (float)-0.018145956584644567, (float)-0.1586419172544657, (float)-0.13969591666046538, (float)-0.07364894386078576, (float)-0.03227034904857826, (float)-0.05213978714313866, (float)-0.15196188589368104, (float)-0.1564179062985879, (float)0.0772746751929409, (float)0.30306091094625665, (float)0.24483900003758738, (float)0.030985683059719434, (float)-0.12859174324983497, (float)-0.22731477381104284, (float)-0.24138284627977993, (float)-0.1762808711545703, (float)-0.19569990589754466, (float)-0.223419882270476, (float)0.03082465939415653, (float)0.3325746810343081, (float)0.16606728542526233, (float)-0.19984547979434963, (float)-0.11353505356687968, (float)0.21730414323721312, (float)0.19362745727881683, (float)-0.0321382374743014, (float)-0.057881230993443, (float)-0.0066902068439758265, (float)0.025500473196188405, (float)0.2173153620911499, (float)0.38388895350313745, (float)0.2234318575302088, (float)0.011242758762722358, (float)0.051251747232121066, (float)0.06886010032656913, (float)-0.12255432421716039, (float)-0.22241036916286983, (float)-0.10210623156116884, (float)-0.010111265029407557, (float)-0.04037870931075843, (float)-0.03606292429684831, (float)0.06578368632952174, (float)0.11869232444393549, (float)-0.048967346776922695, (float)-0.32973385184371373, (float)-0.3706904898418567, (float)-0.13267252751284483, (float)0.006887938737308392, (float)-0.03416950301594576, (float)0.07711052602020946, (float)0.32229887021940573, (float)0.2943491484205803, (float)-0.02494818075483096, (float)-0.2534761318110926, (float)-0.2488890099612059, (float)-0.11872920363346173, (float)0.10061929904001678, (float)0.28785122857214235, (float)0.19909050318142626, (float)-0.05131368178435013, (float)-0.03992393414439487, (float)0.1650545167829543, (float)0.033350895623268505, (float)-0.3595578268176513, (float)-0.34618663724019294, (float)0.05622220381109701, (float)0.18097664413499492, (float)0.04008031320196051, (float)0.13394615214434258, (float)0.2527849615852371, (float)0.009102916988896674, (float)-0.1712522605307066, (float)0.03624051115322226, (float)0.12805637764167302, (float)-0.06254945886242917, (float)-0.015742735777961158, (float)0.22434204596901788, (float)0.14672178511039963, (float)-0.05844739759388295, (float)-0.015051369283152148, (float)-0.03788333277414555, (float)-0.2409557048375928, (float)-0.12004612698813608, (float)0.19632313708176105, (float)0.010104921631182024, (float)-0.40128019866820097, (float)-0.21771251086312046, (float)0.23970136552608368, (float)0.14566805100367614, (float)-0.21565995411911762, (float)-0.129445374676582, (float)0.19677641191830256, (float)0.20733231466192845, (float)-0.020492619992220008, (float)-0.1101189657784945, (float)0.02475065358016564, (float)0.17075150836797254, (float)0.07607794484499669, (float)-0.16282990621485374, (float)-0.14064347776795127, (float)0.16071850353898545, (float)0.2688530463497892, (float)0.008200618317408752, (float)-0.2883436044591978, (float)-0.3041663707171863, (float)-0.01119134430182153, (float)0.27267193308478044, (float)0.14090800358046546, (float)-0.20158536014423684, (float)-0.17667590943550093, (float)0.07253860984408601, (float)0.029988856212633874, (float)-0.09215552197850055, (float)0.05037102699662657, (float)0.16357724833353737, (float)0.09577975462461218, (float)0.0471483450357333, (float)-0.07967866449397, (float)-0.19953889296404004, (float)0.08884544809754244, (float)0.36676353748575585, (float)-0.007711467656069521, (float)-0.3917683079415871, (float)-0.11728037257142691, (float)0.1449689958690042, (float)0.017042200132509375, (float)0.0835060039159507, (float)0.24350652904535425, (float)0.00043458859900833205, (float)-0.20927236212835743, (float)-0.04687263626156813, (float)0.0397606621454102, (float)0.03653268150775181, (float)0.19294478362031736, (float)0.14508058446120603, (float)-0.15124267716495654, (float)-0.1747326238468546, (float)-0.032751574018944504, (float)-0.03694352293396446, (float)0.08077887169864087, (float)0.24150264235108035, (float)0.07558528951623092, (float)-0.059152901413827126, (float)0.035607536346126116, (float)-0.12201558081299366, (float)-0.31398267144966097, (float)-0.04971197624699458, (float)0.06443192557719582, (float)-0.28268406370601123, (float)-0.2782297526973596, (float)0.08887070449863585, (float)0.07097899147149422, (float)-0.0919422071635434, (float)-0.04003983372013137, (float)-0.11611761865274794, (float)-0.07590142921731755, (float)0.34729639110442506, (float)0.3157542019860461, (float)-0.22598156945873688, (float)-0.14696914667613487, (float)0.27801313739179945, (float)0.05760614381579706, (float)-0.11174390097605916, (float)0.330754537581792, (float)0.3511366276660964, (float)-0.10745687264004829, (float)0.028397173309839527, (float)0.34199365269428184, (float)-0.013799703751690791, (float)-0.3279934100200114, (float)-0.0851667031452859, (float)0.07485376152731908, (float)0.04257107861521555, (float)0.12440482312038251, (float)0.055373700053360626, (float)-0.1416023780737714, (float)-0.10410416499069296, (float)-0.10034480726410624, (float)-0.24825803943837463, (float)-0.05411568031760208, (float)0.27626096716186, (float)0.12289614143347646, (float)-0.16651696135995644, (float)-0.13043512030698837, (float)-0.1327180476656107, (float)-0.25886033829513266, (float)-0.10337394135379027, (float)0.12523560666079572, (float)-0.013405758366908934, (float)-0.24413323387829644, (float)-0.14459434856884307, (float)0.12723090598231768, (float)0.18845895393323556, (float)-0.00788092236739863, (float)-0.12223762068570952, (float)0.06155380564500435, (float)0.24940181244149476, (float)0.18665569375517332, (float)0.1269175117207778, (float)0.21616359356844145, (float)0.17349198245623965, (float)-0.08339668845543692, (float)-0.2682704299539316, (float)-0.16616466983150782, (float)0.14773076422207615, (float)0.2900222845161375, (float)0.008750406374119439, (float)-0.24393689533173682, (float)-0.023936306990012146, (float)0.18568148232581683, (float)-0.07588633765181235, (float)-0.34306557687286704, (float)-0.2511186819134095, (float)-0.07933125868826342, (float)0.09382890607697023, (float)0.33489262267810294, (float)0.356949275574416, (float)0.13472234575817205, (float)0.04887396458024237, (float)0.06218240393929993, (float)-0.08639116685378595, (float)-0.1934689386867234, (float)-0.0454333780134066, (float)0.11528837958228845, (float)0.04148647223826048, (float)-0.20081120968319166, (float)-0.3755480754599222, (float)-0.31908564442171483, (float)-0.1597111801483756, (float)-0.06460847430949884, (float)0.0736248561052794, (float)0.20784573520695193, (float)0.06608056313272666, (float)-0.11808418988922624, (float)0.08287522052717539, (float)0.37250193660026876, (float)0.32665731235960943, (float)0.13616736210385952, (float)-0.046549575847630004, (float)-0.2521891682491724, (float)-0.19649530919379687, (float)0.08138470714083797, (float)0.042433190107432545, (float)-0.1342922872897402, (float)0.1148030261169513, (float)0.330312997923139, (float)-0.04242236646136781, (float)-0.40059546033809534, (float)-0.2737104064044492, (float)-0.11398279072970738, (float)-0.0891062543855464, (float)0.016308551626425548, (float)0.05979109004118782, (float)0.08364554593555278, (float)0.3199664518101898, (float)0.3255828037129189, (float)-0.1262571661692154, (float)-0.20421868088450218, (float)0.2870304054979669, (float)0.3521934519829518, (float)-0.09821443174050676, (float)-0.1842701387819873, (float)-0.020005406824814442, (float)-0.1544441729719869, (float)-0.1641540854425689, (float)0.17672100310212108, (float)0.17988328556107225, (float)-0.21554683395584368, (float)-0.27882066560620733, (float)0.04323464391289859, (float)0.25988730937165877, (float)0.2631624849632371, (float)0.10378661610787551, (float)-0.15067666086896508, (float)-0.22101449531711637, (float)-0.11808564301420026, (float)-0.16834869015380174, (float)-0.2355974899925343, (float)-0.02322568375503329, (float)0.17631834000724647, (float)0.10396756560287193, (float)0.06612381189214342, (float)0.16017252521147393, (float)0.04093075841096813, (float)-0.2774519182369369, (float)-0.33289306611708896, (float)0.016269781532786798, (float)0.3114721919440188, (float)0.15890603658114025, (float)-0.09675820289230844, (float)0.020718889588876487, (float)0.13761228629956, (float)-0.15255018787141236, (float)-0.2334421735416842, (float)0.20553938595811544, (float)0.2938180734233116, (float)-0.12466710487153801, (float)-0.07617850509036439, (float)0.3011236698948272, (float)0.041049332780093005, (float)-0.40028691550487794, (float)-0.13225622953633495, (float)0.2584574058044629, (float)0.1046915378046988, (float)-0.07117436916226674, (float)0.04669716047924839, (float)0.061917786704489865, (float)-0.04857660884009549, (float)-0.02400073392994374, (float)0.03245572496613926, (float)-0.03106079604888755, (float)-0.13305742656844746, (float)-0.13979813279209885, (float)-0.007760927403039468, (float)0.10186107558847411, (float)0.08286568253744729, (float)0.14346740905990849, (float)0.23444910123682253, (float)0.014745464902981367, (float)-0.20938659869487866, (float)-0.00247424943113157, (float)0.095180701250958, (float)-0.2368478613051954, (float)-0.2521023530672568, (float)0.10279709081783411, (float)0.026612622854811946, (float)-0.17063745136007066, (float)0.1528942459504446, (float)0.2741015374037875, (float)-0.19868855890213785, (float)-0.2763234883649571, (float)0.16130649635716743, (float)0.15053282396798368, (float)-0.1332390011173366, (float)0.003974105435529396, (float)0.10307946643308706, (float)-0.16880303092309168, (float)-0.144764737194479, (float)0.21822567439408874, (float)0.17193631644051163, (float)-0.22199980916664575, (float)-0.28799481138986444, (float)0.013680105333237836, (float)0.24218148045865767, (float)0.15677696462402094, (float)-0.14166350764195484, (float)-0.2824213989806715, (float)-0.062181684695123966, (float)0.21031740078699393, (float)0.27179579181398655, (float)0.2748885246800111, (float)0.2244561740652175, (float)-0.057533160024501186, (float)-0.2938224948505252, (float)-0.10463558939626351, (float)0.2075251142955218, (float)0.1721653085776317, (float)-0.0205448868525693, (float)0.019475168988205938, (float)0.1767772783029694, (float)0.15509149953276352, (float)-0.02007209935550045, (float)-0.1549726967148614, (float)-0.15784266194652125, (float)-0.05000704743098852, (float)0.05700445177676588, (float)0.037340954859916724, (float)-0.10439096688980265, (float)-0.2625661723333357, (float)-0.3640617660398752, (float)-0.36702452686519943, (float)-0.24272082739666642, (float)-0.04978038465308931, (float)0.08533867873434736, (float)0.11734398099256176, (float)0.11023955312893893, (float)0.07401057265455967, (float)-0.048306154006804304, (float)-0.12271326051328803, (float)0.08615786772347683, (float)0.3762436159408263, (float)0.2933958296206034, (float)0.016189187616800226, (float)0.08367101052715006, (float)0.3011372049199322, (float)0.17522135659855065, (float)-0.029057434729465575, (float)0.0164823983944915, (float)-0.0566453458783937, (float)-0.32015161638013956, (float)-0.24520232097361833, (float)0.09058468633701126, (float)0.11956006237191934, (float)-0.04960130548459843, (float)-0.003279889605630945, (float)0.13984660292407747, (float)0.13157710315611798, (float)-0.028163450897719548, (float)-0.2525737759156471, (float)-0.3159442147976753, (float)-0.09311349074551632, (float)0.14130472370109087, (float)0.23039467437645197, (float)0.2753715755155985, (float)0.0962004374508819, (float)-0.28633220187977576, (float)-0.2432611478611918, (float)0.20671740348992348, (float)0.18868221290718815, (float)-0.2743740821251602, (float)-0.31134136802880424, (float)0.03747830960921289, (float)0.13134175939736928, (float)0.02827870962732639, (float)-0.006921603906666698, (float)-0.10013161816332214, (float)-0.20811272072012565, (float)-0.11068468380637599, (float)0.08990213361628643, (float)0.15751554429519218, (float)0.03150243046855517, (float)-0.14560643271538787, (float)-0.0936937102871669, (float)0.1698653667444754, (float)0.2462651116544872, (float)0.09640362515830551, (float)0.05625301027586176, (float)0.07898335615979406, (float)-0.001937594693532368, (float)0.0029135118175531768, (float)0.059984159298563385, (float)-0.07505862447425711, (float)-0.11603729078504774, (float)0.18370562158227186, (float)0.31091828018143, (float)-0.027379595609422568, (float)-0.29936879186932186, (float)-0.15559379040391175, (float)0.1237929544683933, (float)0.2274437737455495, (float)0.06472990537447079, (float)-0.2078479220211384, (float)-0.2612307405642044, (float)-0.13367702918588534, (float)-0.1770736943845162, (float)-0.2652853932221933, (float)-0.032773755967857386, (float)0.2621305538690423, (float)0.18422646509768456, (float)-0.05545574579210073, (float)-0.06995333610099821, (float)0.06968286363300821, (float)0.1611132877953432, (float)0.19017637780759547, (float)0.15358517879203543, (float)0.04652276645016418, (float)-0.02070180824126556, (float)-4.26057446971224e-05, (float)-0.02515343751012027, (float)-0.1545041375275459, (float)-0.23261760018943764, (float)-0.16023213077682877, (float)-0.04962467325614563, (float)-0.02772951054496882, (float)-0.09848906704771827, (float)-0.13864610407954733, (float)0.035667697788890854, (float)0.33804661078228215, (float)0.3745344737876375, (float)0.12299742420831052, (float)0.0053784436717882024, (float)-0.0021124343105072612, (float)-0.22481867772279038, (float)-0.3344307614582966, (float)0.04141239519571252, (float)0.35452002746861455, (float)0.155793804204797, (float)-0.0538229600946022, (float)0.051206736957398344, (float)0.09261101995732185, (float)-0.060460403657140574, (float)-0.13325267717522057, (float)-0.048909692851587555, (float)0.06071193344570994, (float)0.012715969195174506, (float)-0.2423041833086819, (float)-0.35871712803590444, (float)-0.1401599018438735, (float)0.010637442056819714, (float)-0.04163171953684204, (float)0.0837524346802902, (float)0.27098979109183036, (float)0.1516775510622396, (float)0.014241448978224415, (float)0.10700936927733, (float)0.1438424889968846, (float)0.12148674402433157, (float)0.14238336311345715, (float)-0.09137201856439497, (float)-0.3899889990328171, (float)-0.19431685569308535, (float)0.09596707742338345, (float)-0.06563854324693365, (float)-0.12477913050892939, (float)0.19964862272902048, (float)0.22095670598854647, (float)-0.08463476357474464, (float)-0.0890538583316461, (float)0.0774798276004964, (float)0.0900032288603363, (float)0.14304584881171886, (float)0.13524214691941663, (float)-0.14107329217776804, (float)-0.2634903028138754, (float)-0.09359600065025835, (float)-0.12582538131925625, (float)-0.25865486199774157, (float)-0.024712470046290548, (float)0.22315262787025128, (float)0.04373739380896074, (float)-0.1351574309010434, (float)0.0817546716513173, (float)0.3677921190744888, (float)0.3588349019628963, (float)0.12418890171503266, (float)-0.07916050729506961, (float)-0.12542167152403147, (float)-0.12520103813225192, (float)-0.15652087536768436, (float)-0.10002835156901448, (float)0.007083645871016324, (float)-0.04328580004877168, (float)-0.16931620690111282, (float)-0.14352328093256622, (float)-0.0029890080768615167, (float)0.1283072299739174, (float)0.1731571202267784, (float)0.03710669927084174, (float)-0.11631976093513012, (float)0.00899125364434238, (float)0.22596278308433265, (float)0.16392199876099997, (float)-0.011267692191055553, (float)-0.00019216104994897854, (float)0.056185699479106156, (float)-0.007768088522409909, (float)-0.06251907877031802, (float)-0.0148015105254118, (float)0.04415944363048093, (float)-0.015444822555708563, (float)-0.2124102829726957, (float)-0.33509353030923067, (float)-0.17982970165440487, (float)0.08422993891501686, (float)0.16333679100587553, (float)0.07232421707267092, (float)0.0037007413550813263, (float)0.036103081312839874, (float)0.09697547311709587, (float)0.061772686842531836, (float)-0.05264330103124932, (float)-0.10298843839685198, (float)-0.08336752161831812, (float)-0.02611480663922681, (float)0.15439690584096705, (float)0.31012700099959356, (float)0.1509551529956386, (float)-0.12213699272861989, (float)-0.14627775678979305, (float)-0.06198505602970908, (float)-0.025895771050243755, (float)0.08688704074458015, (float)0.11272795761780262, (float)-0.07623154992725881, (float)-0.06454098767557286, (float)0.1693270133776303, (float)0.027267605658046756, (float)-0.3632687369102443, (float)-0.326914539865599, (float)-0.024402294129319924, (float)0.0696561407432847, (float)0.12290134052361436, (float)0.20296445781960143, (float)0.05023150651550502, (float)-0.10587403613090642, (float)0.026325205010192934, (float)0.14485227387875457, (float)0.08670481976162057, (float)0.07070364910369221, (float)0.051469730845476, (float)-0.026936807009410188, (float)0.02031852983482742, (float)0.03738637709482729, (float)-0.14711962499741654, (float)-0.13925148076526173, (float)0.0985857124152501, (float)-0.003546856298273293, (float)-0.2651155242920439, (float)-0.04906909420756686, (float)0.22605293105940763, (float)-0.04058249465689223, (float)-0.2692345552296428, (float)0.008911099148830436, (float)0.17461748525164283, (float)-0.06870395426885278, (float)-0.20679516754475896, (float)-0.09817650044080069, (float)-0.016639754689760165, (float)0.026611785975852783, (float)0.04914723178023238, (float)0.03506216896475751, (float)0.1730992154973769, (float)0.36246942406923305, (float)0.2316825095630075, (float)-0.025673779559433948, (float)-0.037354051604091595, (float)-0.026819038132243702, (float)-0.07108077765719624, (float)0.14856054837871122, (float)0.3129501364704858, (float)-0.019335206714350104, (float)-0.2884808364604184, (float)-0.11420250565266749, (float)-0.10733586877326806, (float)-0.31021832523525644, (float)-0.101678428235431, (float)0.17936142110955972, (float)-0.04773466659541278, (float)-0.25953908195050873, (float)-0.06899930793268613, (float)0.056831609296415266, (float)0.06611447117393708, (float)0.21120798442429217, (float)0.19874816529100228, (float)0.00012610833853612428, (float)0.025817715605813252, (float)0.09294227341204502, (float)-0.031186341771956012, (float)0.02292004886876851, (float)0.12667807116611274, (float)-0.19150123877107922, (float)-0.4092345942522454, (float)-0.028378783651267517, (float)0.2160228686715832, (float)-0.09077534072474054, (float)-0.23756673598257874, (float)0.036754950557111955, (float)0.18288350793733454, (float)0.009336973735498076, (float)-0.14519903677288173, (float)0.012230761812880426, (float)0.3208703394416325, (float)0.2578961454588108, (float)-0.10094434732814675, (float)-0.05949604693883872, (float)0.17564549766525056, (float)-0.13017358095310672, (float)-0.41656407448648675, (float)0.040155777555197045, (float)0.40127894920133034, (float)0.08028837439680007, (float)-0.08559552182133721, (float)0.1238133404865182, (float)0.051473888748283486, (float)-0.10616612694058891, (float)0.04441381055190626, (float)0.06980483272347617, (float)-0.10366932297330295, (float)-0.017771715436417215, (float)0.1416453738507852, (float)0.036788966455670744, (float)-0.10046779398836149, (float)-0.18636527584247814, (float)-0.3495729182112746, (float)-0.3827274329853821, (float)-0.17560843016443134, (float)0.046123297786761615, (float)0.14468000981526763, (float)0.053718492052538536, (float)-0.11456841974859883, (float)0.044066561094707114, (float)0.4204361446893626, (float)0.40542094290409575, (float)0.1245208120102405, (float)0.1010575293985288, (float)0.12188487102461187, (float)-0.036302265318689644, (float)-0.039564777972060663, (float)0.02514881011311163, (float)-0.19019717957879836, (float)-0.3635285698398181, (float)-0.19570411301751872, (float)-0.008295369745102078, (float)0.029315271415230833, (float)0.011996399660051824, (float)-0.1027539278020773, (float)-0.15657339382080032, (float)0.07623437352719613, (float)0.33147901546553016, (float)0.3211272921889734, (float)0.17444838440299235, (float)0.0341454510350342, (float)-0.03129999629851745, (float)-0.004729646260818518, (float)-0.1223282437600149, (float)-0.3811711847888971, (float)-0.33508092341358625, (float)-0.01356608786835127, (float)0.10358273294671347, (float)0.05140618862035263, (float)0.038797649679581686, (float)-0.07289163648985392, (float)-0.1469280414996969, (float)0.08584930852110834, (float)0.3257423116131161, (float)0.2993247428814996, (float)0.17382917994902855, (float)-0.03416081265676488, (float)-0.2553464761310352, (float)-0.12907648108105949, (float)0.19574883918641323, (float)0.23933667129519492, (float)0.087857621661703, (float)-0.08316786781479037, (float)-0.3114351969963408, (float)-0.24787524265988592, (float)0.15508202321177397, (float)0.1486709938033337, (float)-0.26772850942801835, (float)-0.2346908646577473, (float)0.08939276362800233, (float)-0.00415859890925336, (float)-0.15360771470614573, (float)0.06344831959439982, (float)0.1518628438728989, (float)-0.03939569535657017, (float)-0.05416921851665235, (float)0.03971442497889299, (float)-0.0795528154641088, (float)-0.20304840804466803, (float)-0.06105414038466989, (float)0.17959200398846634, (float)0.24615521116219566, (float)0.16589646040638167, (float)0.18589139498105897, (float)0.27463145908125186, (float)0.1541486149830064, (float)-0.026066950481098774, (float)0.00022823605153066254, (float)-0.09214852459569353, (float)-0.3777474176776069, (float)-0.2687413004661081, (float)0.07862926751583864, (float)-0.03777871888260141, (float)-0.1963865450438254, (float)0.15510059615117988, (float)0.25169764599939537, (float)-0.22302879331109235, (float)-0.2668619823912687, (float)0.21938894388833977, (float)0.2170464129107826, (float)-0.2370405311911496, (float)-0.287038865081088, (float)0.07018849467574251, (float)0.28440812017252315, (float)0.18607137355992764, (float)-0.03151707992776904, (float)-0.08011414742652932, (float)0.05351680718126149, (float)0.06867851641392612, (float)-0.007856153878517184, (float)0.09923933434203107, (float)0.20920773132397594, (float)0.05971534021712916, (float)-0.15567833720931115, (float)-0.27819536058145894, (float)-0.3197898841039625, (float)-0.15731518888308188, (float)0.10986773410363149, (float)0.16917990620766196, (float)0.09505349812265816, (float)0.07113644145165135, (float)0.03033380337713319, (float)0.07036251423788852, (float)0.20167365889026442, (float)0.01717771110387814, (float)-0.3558560831380353, (float)-0.24877424869308531, (float)0.09629372367851939, (float)-0.03471651768236989, (float)-0.2693182530818172, (float)-0.01390249328098462, (float)0.23745868456890962, (float)0.024214556259176817, (float)-0.15834130544449068, (float)0.06850977848993575, (float)0.35785930766737806, (float)0.33655617224330625, (float)0.05901824449038816, (float)-0.12678364803269956, (float)0.011040962701209842, (float)0.2026442222004362, (float)0.07528321971461839, (float)-0.18509804472705815, (float)-0.2186630137031236, (float)-0.14118558333367706, (float)-0.16560879040151208, (float)-0.14296825709753824, (float)0.02569364999131365, (float)0.10787541035890244, (float)0.0016795763014421116, (float)-0.039248266131564104, (float)0.11270791572781254, (float)0.18991096446932546, (float)-0.013917916047356175, (float)-0.2601002882485712, (float)-0.1912766961949327, (float)0.14476429177374045, (float)0.29957413774983155, (float)0.016958658066204, (float)-0.303402340314096, (float)-0.14579224080376738, (float)0.23875356599414244, (float)0.2668585736484383, (float)0.059125760296077544, (float)0.008745779232160052, (float)-0.07186199173201402, (float)-0.302775572768593, (float)-0.23501634455783973, (float)0.14870861675462718, (float)0.19759294091175342, (float)-0.16847925054910595, (float)-0.2820762322649565, (float)0.07356063623476482, (float)0.3777463238116027, (float)0.29624194988325175, (float)0.11027994712948655, (float)0.07382976852047371, (float)-0.03800772122695493, (float)-0.28262502256505795, (float)-0.19975148142362872, (float)0.194230621815666, (float)0.20536747788796467, (float)-0.127080180595515, (float)-0.07119698396948135, (float)0.1878336543021459, (float)-0.03602067574097393, (float)-0.4113112896536228, (float)-0.3418266818289446, (float)-0.11516061746751392, (float)-0.07263413671949401, (float)-0.041856431453764664, (float)0.040213903409036016, (float)0.1110581671738068, (float)0.2006109129840922, (float)0.18148920441274033, (float)0.01732000268992075, (float)-0.05604316443818501, (float)-0.05129060888482373, (float)-0.06583089592353801, (float)0.13120509956444337, (float)0.41159789813734204, (float)0.2649308331435213, (float)-0.05096433169179388, (float)0.06522273979333744, (float)0.2605035928098409, (float)0.01930985441275253, (float)-0.21843878247929452, (float)-0.0387101073818342, (float)0.1431703877936077, (float)-0.008410206301420248, (float)-0.24567193977578564, (float)-0.35404572882619545, (float)-0.3694936775950273, (float)-0.249249417027575, (float)0.0231544247992929, (float)0.1475458874624572, (float)-0.04912083658481496, (float)-0.12501974605905697, (float)0.17667248348829354, (float)0.2438344604765087, (float)-0.16784151679215786, (float)-0.2359328115905716, (float)0.23985885616418193, (float)0.34106439754913664, (float)-0.060182818324467834, (float)-0.18283688672582005, (float)-0.017527759450903967, (float)-0.0034494004405286128, (float)-0.00456377576067347, (float)0.07637073948397528, (float)0.09721029589802377, (float)0.17507131391188346, (float)0.19360878036760665, (float)-0.10173398614776594, (float)-0.24266190270461066, (float)0.05204862759474134, (float)0.09227433807887343, (float)-0.2330000295317196, (float)-0.1736002958204172, (float)0.1440958199324871, (float)0.12297867383848904, (float)0.0705694422511438, (float)0.2137636047654824, (float)0.07297063269836195, (float)-0.2685778818806466, (float)-0.24474089302120972, (float)0.06447442169674014, (float)0.2904640734687636, (float)0.31170939574265877, (float)0.06744163551214977, (float)-0.17622250119129804, (float)-0.022362201764390088, (float)0.19262918749054403, (float)-0.04184414848690223, (float)-0.3752179479846465, (float)-0.31099184423379395, (float)-0.0447145721091601, (float)0.08600008624761855, (float)0.04752623489592448, (float)-0.06997229354056815, (float)-0.14965588315714387, (float)-0.16387769701894686, (float)-0.14590434698343815, (float)-0.015757423060936297, (float)0.16497996635054116, (float)0.1728877209413989, (float)0.12024086659967802, (float)0.17487160752956826, (float)0.10051059394813043, (float)-0.0872029665368553, (float)-0.020785745404703515, (float)0.0765967834642156, (float)-0.17811992282694036, (float)-0.3346152096131199, (float)-0.02036109496647867, (float)0.2364779856404952, (float)0.1097983844572502, (float)-0.0026808237870193726, (float)0.0910798818650064, (float)0.17369623883484483, (float)0.16742644644011087, (float)0.12588064539791297, (float)0.028844255144000287, (float)-0.1351381391955452, (float)-0.2611442780792887, (float)-0.1817034411537415, (float)0.051657256790239574, (float)0.15315161813470027, (float)0.1064964279045259, (float)0.143544274971893, (float)0.17255143574285725, (float)0.0021146086977708927, (float)-0.1764506758950355, (float)-0.1721956100758303, (float)-0.08085137765434028, (float)-0.03858352618431143, (float)-0.16754083816094734, (float)-0.3574885955578629, (float)-0.2015243781647365, (float)0.17916678707997233, (float)0.1796060473306013, (float)-0.04555169229699671, (float)0.04012389102354943, (float)0.17419822710279068, (float)0.10163205918801327, (float)0.16845208102591572, (float)0.2410243422241533, (float)-0.017957117630565043, (float)-0.18557769349537992, (float)-0.0833597443704617, (float)-0.13870395185314383, (float)-0.16359620886877477, (float)0.06988375837439513, (float)0.009050028733919082, (float)-0.249715053441857, (float)-0.011623311867752287, (float)0.2571254414971543, (float)-0.009701328071417324, (float)-0.10210294666522375, (float)0.17766190418784247, (float)0.09524978537654834, (float)-0.08395348655920389, (float)0.20929195100517106, (float)0.37662321972680746, (float)0.08132555947874841, (float)-0.12721481278395316, (float)-0.1934246131872289, (float)-0.23038006524356816, (float)0.06342747772290813, (float)0.3114272324930284, (float)-0.05829425105595983, (float)-0.414050451811895, (float)-0.1791996460262245, (float)0.05241718512411218, (float)-0.03270780340455359, (float)-0.06196350514336419, (float)-0.08538210065360465, (float)-0.2195081955449986, (float)-0.12794935418808942, (float)0.16025994561671283, (float)0.2171322311282673, (float)0.05907264192768716, (float)0.029450478551634986, (float)0.22220455314170584, (float)0.3765992793126972, (float)0.18907207694889816, (float)-0.13321308092726808, (float)-0.1343498757352235, (float)-0.018079708796913667, (float)-0.1377906713745135, (float)-0.10381218524494178, (float)0.21865173428090842, (float)0.20143908409631042, (float)-0.10248445359672302, (float)-0.03730072215691969, (float)0.12796097293982378, (float)-0.09657881125385787, (float)-0.22967659001269108, (float)-0.003922110639812206, (float)0.010147711980830799, (float)-0.22465930894519778, (float)-0.1405323680584588, (float)0.15060588495569985, (float)0.09641213829175196, (float)-0.23199785697891537, (float)-0.34068078153314685, (float)-0.13225301202153994, (float)0.03754407859843467, (float)0.0073761644917416285, (float)0.07950849118069754, (float)0.35006542169170185, (float)0.36922147486080026, (float)0.009617430876619704, (float)-0.1733736260162898, (float)0.0264937183392949, (float)0.08871284725686134, (float)-0.19286636467969662, (float)-0.30508891231372925, (float)0.0075818648547590056, (float)0.25171751676520643, (float)0.12148582184167217, (float)0.06336167956897405, (float)0.25158720718467464, (float)0.11895105761207883, (float)-0.30233920944885556, (float)-0.1901847528156157, (float)0.2994629592695994, (float)0.22758414830605742, (float)-0.1319404649793394, (float)0.04343265594482359, (float)0.28392399523749645, (float)-0.01479000519393975, (float)-0.2202751951185363, (float)0.03604567866199711, (float)0.10096686460477447, (float)-0.13709165916602625, (float)-0.08112782790305857, (float)0.15476782754087084, (float)-0.016771859465657832, (float)-0.38707474010136705, (float)-0.2961450617187056, (float)0.11541680763438014, (float)0.10456285102503599, (float)-0.31926714493675373, (float)-0.40353698265662874, (float)-0.1015686835083928, (float)-0.038769260615499596, (float)-0.11699638228696446, (float)0.09823695596804022, (float)0.22744817626949662, (float)-0.023882623964583048, (float)-0.13672578345507044, (float)0.021236538964670613, (float)0.06981901417688968, (float)0.1682890988810286, (float)0.4186259257021722, (float)0.332044296666077, (float)0.02427948424521175, (float)0.11170655714797571, (float)0.33148766177487765, (float)0.18433298065153514, (float)0.012526445247103434, (float)0.06752610786151532, (float)0.03420183303192532, (float)-0.0700181596319625, (float)-0.034245423692273486, (float)-0.054978247371951956, (float)-0.21062342530273453, (float)-0.2533664933574043, (float)-0.17932353473177742, (float)-0.11589898220615438, (float)-0.005271632265182296, (float)0.06926692799908085, (float)-0.09796695583277208, (float)-0.3557838683076978, (float)-0.3645195168017136, (float)-0.1464829128283877, (float)0.011573677557374169, (float)0.06974560233438692, (float)0.1830259396687497, (float)0.23654306365821148, (float)0.07783949953350695, (float)0.01725317617263248, (float)0.23346634290096227, (float)0.26395998514415236, (float)-0.024212233363657184, (float)-0.11814643911357425, (float)-0.02227228970521894, (float)-0.10598632708276552, (float)-0.07853254900763217, (float)0.211739191377686, (float)0.19617955272750662, (float)-0.09994842545622155, (float)-0.09973576421027815, (float)-0.027999504810660155, (float)-0.1790943729698486, (float)-0.052425581412629124, (float)0.31882775873997926, (float)0.2146993966220423, (float)-0.19639148240817472, (float)-0.2329693402569529, (float)0.029580765520388713, (float)0.24758261081468103, (float)0.2816499492668657, (float)-0.016420048580872947, (float)-0.3442820317701717, (float)-0.2049523693807065, (float)0.04370606110429314, (float)-0.08310566492314957, (float)-0.17065694273201745, (float)0.012193128812293235, (float)-0.009635564341930372, (float)-0.21236146808459347, (float)-0.14837831563748544, (float)0.059343684304977135, (float)0.14677537778722188, (float)0.19569490899799544, (float)0.20292097339507814, (float)0.1628041478282398, (float)0.20635891409631632, (float)0.17055430025115215, (float)-0.08322683217596796, (float)-0.2047114278781049, (float)-0.0781122974595542, (float)-0.06119184983220414, (float)-0.09616728844538969, (float)0.13526114957183724, (float)0.34196219473350176, (float)0.13206342542046043, (float)-0.17580330920164855, (float)-0.1508873454506498, (float)0.018130331171573078, (float)-0.015644930623596714, (float)-0.12968297865168618, (float)-0.06802276176190315, (float)-0.012109831725072955, (float)-0.20449402747581646, (float)-0.3539832255596096, (float)-0.16816937224509948, (float)0.05251020337556199, (float)0.07761686132019298, (float)0.13778849531539203, (float)0.20983668653128157, (float)0.05043682300593713, (float)-0.09799952010080187, (float)0.027451763202935672, (float)0.13806519753944307, (float)0.0920636755110054, (float)0.1258613099092893, (float)0.12228526633240334, (float)-0.13974478399218945, (float)-0.28882103516794055, (float)-0.004947531560439257, (float)0.29318892005437536, (float)0.16720355877541407, (float)-0.1705600547345372, (float)-0.27266437801415894, (float)-0.012623721679895006, (float)0.28677388725922137, (float)0.17770054462589058, (float)-0.2066012570489709, (float)-0.22330839715041367, (float)0.10513669827090172, (float)0.06318948803156124, (float)-0.2399973778554677, (float)-0.02240583168870916, (float)0.4028880713474818, (float)0.20290318591300735, (float)-0.1378650033987648, (float)0.06598244414474422, (float)0.16858537738252172, (float)-0.14434528784029768, (float)-0.07746412422220676, (float)0.22414815682706776, (float)-0.05187683547756338, (float)-0.3572834134207821, (float)-0.10951935763075007, (float)-0.08710271999642843, (float)-0.35390256543543885, (float)-0.05760581293285669, (float)0.2796301269362319, (float)-0.06064798650182722, (float)-0.15786132633913294, (float)0.29864522480218386, (float)0.22079599828978966, (float)-0.2332767141641436, (float)-0.1087761236725334, (float)0.1504954355982664, (float)0.06304401195237384, (float)0.11118900501443209, (float)0.13268523876043684, (float)-0.19286486732448335, (float)-0.20284971078201397, (float)0.12319776211067417, (float)0.016687457618835774, (float)-0.15233160446124328, (float)0.11127747836313015, (float)0.09801813535323105, (float)-0.21510328607646095, (float)0.006898781764634907, (float)0.32671873339798113, (float)0.05468296606668949, (float)-0.08523188995732064, (float)0.27054815677935456, (float)0.3464414234035624, (float)0.051313422676859344, (float)-0.11660503332195803, (float)-0.2467556511269655, (float)-0.3370786537869618, (float)-0.09091894190507362, (float)0.1725875361475507, (float)0.05922971850099203, (float)-0.10168214777474799, (float)-0.0297279134660367, (float)0.01231145329413211, (float)-0.141842590625072, (float)-0.23300301508369942, (float)-0.0035323272593037066, (float)0.2807809500307122, (float)0.15812101590635708, (float)-0.11402109983441523, (float)-0.020150381323628862, (float)0.08144739725492371, (float)-0.180823565248682, (float)-0.24638594890863227, (float)0.06188957963813294, (float)0.14274466918029438, (float)0.036257866269422824, (float)0.07119633845683182, (float)-0.05095671831170906, (float)-0.19514105040251373, (float)0.14909633760285632, (float)0.4308218012816029, (float)0.10700661824159845, (float)-0.10577713119498068, (float)0.08382570549818541, (float)0.0067772463792334465, (float)-0.2664541114694454, (float)-0.2655872570897167, (float)-0.23515712117012663, (float)-0.204749631370202, (float)0.1382945971158832, (float)0.39474388678863737, (float)0.24127119128935862, (float)0.1373415680774428, (float)0.1329186260349643, (float)-0.10827325256961168, (float)-0.22997605465155802, (float)0.016252654287747886, (float)0.06300813241694755, (float)-0.24229950763733468, (float)-0.30457952871640337, (float)0.0037527333619377518, (float)0.18313363589997692, (float)0.040396540269773185, (float)-0.06393386969606633, (float)0.11080729856389514, (float)0.23249889905730756, (float)0.058244992913277976, (float)-0.008502523995655934, (float)0.19856569351254424, (float)0.2147446070729373, (float)0.008071776938671534, (float)-0.09322947141442864, (float)-0.25826441766410035, (float)-0.4140974855040555, (float)-0.09304182854949188, (float)0.2233666292479341, (float)-0.08924647971652562, (float)-0.292455302327064, (float)0.0789515533171651, (float)0.1935036887257243, (float)-0.06971710370683434, (float)-0.021354960413345243, (float)0.12544088211931592, (float)0.052572052913330766, (float)0.11431636052100208, (float)0.1130084861666569, (float)-0.22107553643152894, (float)-0.23566583907329264, (float)0.10899352931183463, (float)0.011281287683232983, (float)-0.23972423846516344, (float)0.021949290984049383, (float)0.26593506248491827, (float)0.110926696924638, (float)0.04050712889670208, (float)0.10405212223076238, (float)0.10870735209938034, (float)0.1972625230930575, (float)0.1510991019213281, (float)-0.16213180719019835, (float)-0.22394575999667257, (float)-0.07550712678285308, (float)-0.181569382933371, (float)-0.16850657046565265, (float)0.10696816066618611, (float)0.008477139209370523, (float)-0.16352171648796088, (float)0.19172459742119394, (float)0.29169270946468506, (float)-0.20426500213506926, (float)-0.21423532698704761, (float)0.28016697873144675, (float)0.27311578832950534, (float)-0.012341572387490621, (float)-0.06741127293417627, (float)-0.2595466281541287, (float)-0.39518811629223877, (float)-0.009192994022254812, (float)0.23276729081290093, (float)-0.04607676579020009, (float)-0.06973007234410092, (float)0.2643479476882658, (float)0.2934977586240959, (float)0.09552285616475444, (float)-0.002949900800842496, (float)-0.12933463902121922, (float)-0.2198469074031991, (float)-0.1621164317474831, (float)-0.16306994677912434, (float)-0.14763433182553556, (float)0.03165326294286767, (float)0.03319162266728324, (float)-0.15357079829932818, (float)-0.0007657133470385407, (float)0.373489485753859, (float)0.37295474094878733, (float)0.10276593841605594, (float)0.02489268194638896, (float)0.06405519328795278, (float)-0.07911069601983396, (float)-0.29355869558800074, (float)-0.200969932940133, (float)0.1774560343953529, (float)0.2929393851198735, (float)-0.021510882609951085, (float)-0.19235832064793812, (float)0.006417188127432989, (float)0.09173963102470514, (float)-0.08057925324799213, (float)-0.14650274948118736, (float)-0.010444917950624803, (float)0.11913830231906783, (float)0.0586626602443298, (float)-0.16968017152961093, (float)-0.18106534248969117, (float)0.15506089457378658, (float)0.24147820718664204, (float)-0.09827427208717271, (float)-0.1729121232124757, (float)0.07635677251951119, (float)0.020719026357291385, (float)-0.1712722128930244, (float)-0.03444472832324873, (float)0.11643465494398547, (float)0.07015688524351567, (float)0.09880717628106005, (float)0.08710566213001722, (float)-0.10641504572126734, (float)-0.16320346212317735, (float)-0.1077691333941285, (float)-0.1996040371400011, (float)-0.18189451573807452, (float)0.03746107856389616, (float)0.071214833320674, (float)0.01200297322716507, (float)0.1982485892636584, (float)0.38836101548513374, (float)0.33352033526468583, (float)0.16904713230339494, (float)-0.04093816815992156, (float)-0.17032096660996415, (float)-0.08287261871149929, (float)-0.05808674264029887, (float)-0.12474893305951638, (float)0.12000118247903269, (float)0.3374391348456506, (float)-0.014936445008547091, (float)-0.29620506730337576, (float)-0.010543086858027828, (float)0.07752035487511773, (float)-0.23803052108718253, (float)-0.23249222251784107, (float)-0.07421156779999584, (float)-0.2579889743225023, (float)-0.2523316129877875, (float)0.15114540818676883, (float)0.20988169968744305, (float)-0.07849640546143724, (float)-0.025739927521890284, (float)0.2286834973605045, (float)0.16073158872180837, (float)-0.11096502658071557, (float)-0.2323524925292682, (float)-0.08935150133754366, (float)0.20187900135584022, (float)0.3271344305193385, (float)0.18302629334140447, (float)0.028534803958547433, (float)-0.03667973681285619, (float)-0.07386833463905544, (float)-0.002630072143440843, (float)0.10546188286103488, (float)0.09616516442761051, (float)0.10006551303426323, (float)0.08540084097834601, (float)-0.1705923106578361, (float)-0.3425079152772568, (float)-0.10853989892431046, (float)0.05735615734446416, (float)-0.05861856947515899, (float)0.05882829662780569, (float)0.32798369316310244, (float)0.15606658582528588, (float)-0.2335643376467562, (float)-0.29072840639382747, (float)-0.14051366818581282, (float)-0.058691078129439106, (float)-0.035414050562777424, (float)-0.048253758480742696, (float)-0.026165193650465005, (float)0.04720904560813078, (float)0.017777421808427563, (float)0.0028231387818864035, (float)0.1805563381649802, (float)0.24017675114960996, (float)0.08638181031809164, (float)0.11193752977865813, (float)0.13902628323205388, (float)-0.19290035615605952, (float)-0.3332488305062054, (float)0.025449952341000254, (float)0.1809574923474988, (float)0.01420964576319656, (float)0.07461286081439543, (float)0.09951391060745442, (float)-0.2088592262738265, (float)-0.24578318969530247, (float)0.07419170650775818, (float)0.09813927604834691, (float)-0.07087394216098554, (float)-0.01401207714235458, (float)0.026189181911500752, (float)-0.03300647705652024, (float)0.054369785504888295, (float)0.08010743987837622, (float)-0.09599212289116169, (float)-0.16081112922576316, (float)-0.10097138727363585, (float)-0.0689432072849497, (float)0.028590530728449137, (float)0.05900810801299101, (float)-0.035549304357439984, (float)0.1178857046247319, (float)0.3054449967738211, (float)0.006691197904335984, (float)-0.2129618104016939, (float)0.10910459681737492, (float)0.15421191766330133, (float)-0.2058633535618337, (float)-0.03791488466927456, (float)0.35607794620787886, (float)0.14119662496594035, (float)-0.08720733711530487, (float)0.12267647752361109, (float)0.0802359126710902, (float)-0.14451372987138358, (float)0.016734888210036034, (float)0.05932896733110813, (float)-0.2643676944677852, (float)-0.2329923034012991, (float)0.04292096892586382, (float)-0.058146766518129334, (float)-0.152499479317922, (float)0.02808733896340456, (float)-0.008948106035253731, (float)-0.13378351352694376, (float)0.014827864392246388, (float)0.027202502266430062, (float)-0.13344329777870978, (float)0.00016251841622318513, (float)0.07842536518115727, (float)-0.18029488847498332, (float)-0.1016038210915201, (float)0.2841072166158323, (float)0.1729338272426242, (float)-0.11100913051079843, (float)0.07172538026500977, (float)0.15027550699249828, (float)-0.15055542168602581, (float)-0.07020770882206391, (float)0.3231424358910709, (float)0.22331705892121737, (float)-0.08625589520335718, (float)0.06687525924979061, (float)0.26525679410999004, (float)0.01977545267283409, (float)-0.1886688588291464, (float)0.014078264846801466, (float)0.18080678411807843, (float)-0.010447804337310788, (float)-0.2151491173429611, (float)-0.1428083501518876, (float)0.01103466802425866, (float)0.04360676646609699, (float)0.0038866554671024944, (float)-0.07780536424783868, (float)-0.16039923250235547, (float)-0.0967890470962349, (float)0.00021162700676142517, (float)-0.1351601396228082, (float)-0.2662347259395414, (float)-0.03044903669448418, (float)0.20806957543786364, (float)0.00783767299196367, (float)-0.20903263207962985, (float)0.030466968440572992, (float)0.32146145461154985, (float)0.1704423794558742, (float)-0.16272090859287103, (float)-0.23531202471818033, (float)-0.07196390026799476, (float)0.12311042915756207, (float)0.26640991673334924, (float)0.2091660487405347, (float)-0.11247811172862633, (float)-0.2853799142992618, (float)0.017673802100591423, (float)0.2823640285990147, (float)0.04449975107735467, (float)-0.11010978798084739, (float)0.24631485052764704, (float)0.3927130352847141, (float)-0.027198510362703054, (float)-0.23177812277080764, (float)0.03551752885082475, (float)0.06950181947759511, (float)-0.2458384570471114, (float)-0.31085331780354186, (float)-0.011777289061110228, (float)0.2383257596685405, (float)0.17815123172397754, (float)-0.07600294352394296, (float)-0.15705532238921682, (float)0.030537711312064418, (float)0.10675042636280857, (float)-0.038041110272616134, (float)-0.0899548111432072, (float)-0.08660555697936317, (float)-0.19189697598618452, (float)-0.12187908390808733, (float)0.14297402570063222, (float)0.11258681409547179, (float)-0.20011771459806893, (float)-0.30518154563498695, (float)-0.12713812574463454, (float)0.10099007183063156, (float)0.19061845154717147, (float)0.02354839678376146, (float)-0.13295749362209772, (float)0.05616508566920989, (float)0.26574029816417555, (float)0.16103751239906042, (float)0.04506518730036721, (float)0.0352699582240648, (float)-0.009205571505404827, (float)0.15623696829975592, (float)0.3860094783077091, (float)0.06470263332208495, (float)-0.370779598864792, (float)-0.12960546506472898, (float)0.16708416800537668, (float)-0.07637981632670894, (float)-0.1106811163977663, (float)0.23704860874787279, (float)0.1694971418777138, (float)-0.1259407216810152, (float)-0.03446412315816314, (float)0.047701462446425064, (float)-0.14698521932504502, (float)-0.20693986480931456, (float)-0.16379157863657592, (float)-0.17389361576200818, (float)-0.035812664135980735, (float)0.0004502206331250255, (float)-0.23866043235261786, (float)-0.11570790971152776, (float)0.32469687778619616, (float)0.1885450583269589, (float)-0.25428781856862953, (float)-0.14322783311634624, (float)0.13988896912340382, (float)0.09597836255792447, (float)0.1014130169762331, (float)0.14980241380881543, (float)-0.017996850067877632, (float)-0.004627468333231382, (float)0.2254706183005001, (float)0.14538125028090837, (float)-0.05921231741126755, (float)-0.06843430976777172, (float)-0.19231395640355312, (float)-0.23980670000518592, (float)0.18388870308535377, (float)0.4057106935731229, (float)0.05735934080475013, (float)-0.04633967726431956, (float)0.135995968232096, (float)-0.09601381438157773, (float)-0.28905726430485196, (float)0.04269376046311497, (float)0.12452151011854823, (float)-0.18655256849953863, (float)-0.06345069787238047, (float)0.22077242083251636, (float)-0.058246655136386195, (float)-0.38141384716107096, (float)-0.2398538231942496, (float)-0.0765002206255107, (float)-0.023650191210884318, (float)0.17393220350934688, (float)0.33230067711412664, (float)0.3067700773033167, (float)0.19780581260632152, (float)-0.0508816096641428, (float)-0.22031530451006662, (float)-0.011703292526579352, (float)0.0879723355588185, (float)-0.25801640415592, (float)-0.36346832240171273, (float)0.0020852166237373924, (float)0.1451068972109705, (float)0.005157525130472238, (float)-0.003799079369715479, (float)-0.07486985479797466, (float)-0.21888447653147688, (float)-0.0077925319102006355, (float)0.24247148964028364, (float)0.04335627928175453, (float)-0.08967071453531641, (float)0.2227827317546339, (float)0.36505816801544444, (float)0.030358439681535006, (float)-0.25488704906914694, (float)-0.12831902767236644, (float)0.2067598352731167, (float)0.31341800651628304, (float)0.029887623796938247, (float)-0.1799651413154245, (float)0.02994812595300662, (float)0.20684042328426389, (float)0.053411412288251844, (float)-0.07177145234091095, (float)-0.11490645821869416, (float)-0.2459018139311, (float)-0.21853879657458064, (float)-0.09254033687572517, (float)-0.20429454558163265, (float)-0.1371877732874367, (float)0.30922366110770977, (float)0.2742467317897325, (float)-0.26082262031953835, (float)-0.1939938636955571, (float)0.2882133282068969, (float)0.1594603223860849, (float)-0.22816831700127044, (float)-0.18896664939591878, (float)-0.05218413718155062, (float)0.0702578668637918, (float)0.34065411798251893, (float)0.2516769343773153, (float)-0.19022013071338026, (float)-0.1547644419188329, (float)0.15828784437056714, (float)0.009855050073706951, (float)-0.14836224465338915, (float)0.08739564504578146, (float)0.06953145163647205, (float)-0.23408311435771698, (float)-0.13848933768515667, (float)0.1627667849203141, (float)0.1372435295769476, (float)-0.03566817916927775, (float)-0.12732889021403107, (float)-0.13286244248556892, (float)0.015545186952498248, (float)0.09922209373190023, (float)-0.012862791601411698, (float)0.11213185403626975, (float)0.40279520152732734, (float)0.21691360576969296, (float)-0.12859581006085344, (float)0.016508606284234933, (float)0.11616193640336828, (float)-0.2513488302040569, (float)-0.3540106417154832, (float)0.004106365876372532, (float)0.13356263337274663, (float)0.027478212999653442, (float)0.06324840105304658, (float)0.03445932841016116, (float)-0.12941625209070412, (float)-0.153039728756562, (float)-0.14739971778695907, (float)-0.1983995568120175, (float)-0.04056182846860802, (float)0.18213748752761458, (float)0.14446855294111224, (float)0.08795076274177423, (float)0.1827693766624548, (float)0.1348043793205415, (float)-0.050322542346973996, (float)-0.1514578479891336, (float)-0.2668456339986972, (float)-0.32802149115917495, (float)-0.0723982005406822, (float)0.20952990566300517, (float)0.12992548258328668, (float)-0.02138054453298622, (float)0.05908409216101335, (float)0.1675059349362937, (float)0.15269352594105215, (float)0.02953192051493225, (float)-0.20937678832853104, (float)-0.29498861144786703, (float)0.006477511048006362, (float)0.2752546730681063, (float)0.13927355515047002, (float)-0.012402697207854323, (float)0.11425231949661356, (float)0.1857696209103783, (float)0.055644093750886255, (float)-0.028165140994274005, (float)-0.036221908624476266, (float)-0.05534550439889847, (float)-0.005587479188258909, (float)0.03891845355561397, (float)-0.06914308909589337, (float)-0.14298565575990324, (float)-0.034801307444606876, (float)0.02221502112146559, (float)-0.051046929027540024, (float)-0.0326406152776411, (float)0.03949417484191642, (float)-0.014957671583865286, (float)-0.03503586887328112, (float)0.10852039077956688, (float)0.14867325723791636, (float)-0.04550948213035656, (float)-0.20434470726401313, (float)-0.16808494969387733, (float)-0.0690460386768306, (float)-0.028904869138390358, (float)-0.07425334348477118, (float)-0.14449989093444784, (float)-0.07578147247475035, (float)0.12340987903230292, (float)0.16537811124256155, (float)-0.03470271030070472, (float)-0.15345998558328167, (float)-0.016666654293094888, (float)0.09983116183643506, (float)-0.009720502272461842, (float)-0.10172385799065092, (float)0.06257539364951374, (float)0.2627476943275899, (float)0.23520857480639418, (float)0.16996420162611747, (float)0.25894396440723816, (float)0.24571034023041138, (float)0.02731055182468307, (float)-0.03756091039151788, (float)0.05372124559999635, (float)-0.11540364586747293, (float)-0.36902555412353405, (float)-0.20972082020427546, (float)0.07919295784425466, (float)0.04055424582522166, (float)-0.000428580832062428, (float)0.14433998143932414, (float)-0.008802707867305085, (float)-0.3881607897378637, (float)-0.35255905323024245, (float)-0.06995036946852133, (float)-0.05454813316805203, (float)0.0038424789983902943, (float)0.2946675662934565, (float)0.21486173371690293, (float)-0.22628019092995127, (float)-0.2725527374145767, (float)-0.004329383177952407, (float)0.022858484655160285, (float)0.07944456452348675, (float)0.36274480334633985, (float)0.2906886130467767, (float)-0.0830525777499588, (float)-0.010000311165120662, (float)0.25733803775904907, (float)-0.015388543763339483, (float)-0.3904037559648819, (float)-0.20736126043556247, (float)0.05853104060058717, (float)-0.07791583005312183, (float)-0.21331695174532947, (float)-0.08279333708935116, (float)0.054103519984386804, (float)0.15368067531029397, (float)0.31989807162163997, (float)0.3688546554469789, (float)0.18537662962668697, (float)0.0002729437222573563, (float)-0.006800122186507822, (float)0.00830648965170394, (float)-0.16711692488517604, (float)-0.3728629114138408, (float)-0.2564016450002542, (float)0.02447580097383198, (float)-0.01853641958276855, (float)-0.21219515537998723, (float)-0.0121032651566641, (float)0.34450659405207285, (float)0.3048083419305215, (float)0.0757212366124741, (float)0.012143156405525423, (float)-0.07959462004781348, (float)-0.2322617864919354, (float)-0.1787314697173321, (float)-0.08494324012554082, (float)-0.17859716748349114, (float)-0.14111112402075832, (float)0.1759340253838084, (float)0.36658681813248806, (float)0.2816323621615933, (float)0.17333623368994827, (float)0.07234937012269081, (float)-0.09388659803177478, (float)-0.16943819509850616, (float)-0.09505366262180404, (float)-0.031044108462764845, (float)-0.019651800684536928, (float)-0.0003194491916228145, (float)-0.0019430851352328197, (float)-0.0073972205365191845, (float)0.07228161381843519, (float)0.1418408044954737, (float)-0.011112485272688448, (float)-0.30091063559663245, (float)-0.34407549077482874, (float)-0.031059658774397775, (float)0.23494369937813367, (float)0.11401303430438418, (float)-0.190339906535411, (float)-0.2895663686460772, (float)-0.11099062590900169, (float)0.1327483676030772, (float)0.196019996081477, (float)0.04733836193468657, (float)-0.01729174653626317, (float)0.19624154919794462, (float)0.3405960343025573, (float)0.0666843243390052, (float)-0.2898319452272686, (float)-0.2340958246880433, (float)0.08116423629001839, (float)0.20985946529340677, (float)0.1408849853770912, (float)0.1446296531072305, (float)0.22681871887670793, (float)0.15322287499179146, (float)-0.09468508416493626, (float)-0.20954034549276263, (float)-0.04799157723846329, (float)0.047206467351181024, (float)-0.19019420612956092, (float)-0.36826976498985675, (float)-0.06331611790131816, (float)0.3142523980116639, (float)0.15272806110674572, (float)-0.23554138841145109, (float)-0.16256452140999753, (float)0.1821325353773416, (float)0.16116127792572005, (float)-0.11757730734746658, (float)-0.15238815663599273, (float)-0.018824251007226508, (float)-0.03393917603726223, (float)-0.10069140196852623, (float)-0.07524901887737005, (float)-0.11067130553486958, (float)-0.2298944731042083, (float)-0.1759856009796889, (float)0.08608220983552393, (float)0.20093905813736532, (float)-0.01174985634696243, (float)-0.1727479006273598, (float)0.04311809595469678, (float)0.2513228527939712, (float)0.05674411130531535, (float)-0.12178403245140955, (float)0.10308284672174262, (float)0.3026914933782259, (float)0.20710668064123994, (float)0.1758007144716978, (float)0.21651790463015833, (float)0.07129988838193664, (float)0.03246771529949343, (float)0.24385643447903418, (float)0.2209652516966826, (float)-0.04306414763059696, (float)-0.059693099858940835, (float)0.02427591452929413, (float)-0.12742990397817805, (float)-0.275754635392928, (float)-0.31873263946432767, (float)-0.40812380722329744, (float)-0.2921672124646245, (float)0.06420210851843794, (float)0.11862192818583353, (float)-0.11580308215667656, (float)-0.0957676711693888, (float)0.0782668826269307, (float)0.04324574639611959, (float)-0.04797048409381243, (float)-0.08687534509518478, (float)-0.17549938823407404, (float)-0.13220635067339492, (float)0.12614802634564462, (float)0.2815230533172863, (float)0.16647362354165227, (float)-0.09318709501725901, (float)-0.2550205646781404, (float)-0.031004705484822696, (float)0.3463940151417164, (float)0.22400856414033768, (float)-0.22086896278542978, (float)-0.22077161895708713, (float)0.09801945969254994, (float)0.17584635657718653, (float)0.13477481856748322, (float)0.11656582919275497, (float)-0.024968653743021027, (float)-0.012233041553669744, (float)0.2925488743393285, (float)0.3664976286893802, (float)0.12675756927995172, (float)0.03913154692735586, (float)0.04080245221623464, (float)-0.07273009076796957, (float)-0.09536103721125698, (float)-0.13900621746368907, (float)-0.40393187922987145, (float)-0.4301705444285855, (float)-0.05501465777039389, (float)0.09391471669396784, (float)-0.0960185976403245, (float)-0.11263135035324053, (float)0.04262752421053266, (float)0.07393987061533974, (float)0.0039043111800853387, (float)-0.1096386180643915, (float)-0.15909489395642717, (float)0.03723894008855181, (float)0.23729457156725386, (float)0.16088389667385328, (float)0.11304641466382759, (float)0.2401778797304582, (float)0.15797445801490193, (float)-0.12066073924446614, (float)-0.19122433140244993, (float)-0.09229622266153349, (float)-0.058419654814986795, (float)-0.048137839339939814, (float)-0.028879137001232198, (float)-0.05369552094161284, (float)-0.0924848928491289, (float)-0.09345998597038657, (float)0.011760534671348195, (float)0.1439838318755915, (float)0.030200513777640242, (float)-0.17182477940043073, (float)-0.023256074621982196, (float)0.1708914408307848, (float)-0.015287600540518084, (float)-0.056181047501281674, (float)0.27251596225586705, (float)0.23889581176434022, (float)-0.08914198383509757, (float)0.022471967389388958, (float)0.1582673284428589, (float)-0.17379263228502154, (float)-0.22595712555357583, (float)0.14833265891427488, (float)0.09762495623767836, (float)-0.11586846230013442, (float)0.20827657601146551, (float)0.42288313129083427, (float)0.07738227785110256, (float)-0.07270614332881521, (float)0.055529136687152564, (float)-0.14686896227406254, (float)-0.3551377011726657, (float)-0.17619439718636748, (float)-0.13442130505669206, (float)-0.32905251744169295, (float)-0.20115527953402448, (float)0.11786837898500102, (float)0.12748385186750757, (float)-0.029412797680862635, (float)-0.031385447797766634, (float)0.08024948804074405, (float)0.13898960156102347, (float)0.052219060265401615, (float)-0.03136937885656947, (float)0.09362175311826773, (float)0.13935929486304277, (float)-0.17363378052501308, (float)-0.33161316576662825, (float)0.03195941786753287, (float)0.3111436542510688, (float)0.11665290175044334, (float)-0.09009345276010393, (float)-0.0848272568021263, (float)-0.11776329119385953, (float)-0.164416320148764, (float)-0.0851507861908721, (float)0.02624860016345956, (float)0.15819436491368982, (float)0.31310705753001267, (float)0.26323163104544567, (float)0.0049179523053457675, (float)-0.08758156122264849, (float)0.06322719710839775, (float)0.0931221065219005, (float)-0.0842763275736478, (float)-0.0751724153966923, (float)0.23345932173231834, (float)0.3316439094844108, (float)-0.010030265991039032, (float)-0.21387344155212007, (float)0.007329694388540666, (float)0.06428720479368602, (float)-0.2297492949696077, (float)-0.2541565074138817, (float)0.04281563672920566, (float)0.09994705040722711, (float)-0.015623578991769378, (float)0.00836489114663596, (float)-0.061055137908100264, (float)-0.22842685187505324, (float)-0.12921885918429313, (float)-0.004030670390562964, (float)-0.2014017113583375, (float)-0.30845389143691, (float)-0.07921733973334126, (float)0.07683797417703717, (float)0.08487131866531415, (float)0.14195913585113015, (float)0.051702330749962645, (float)-0.1424366136070901, (float)-0.027779055951595827, (float)0.17522304861400806, (float)0.03834926704092117, (float)-0.0435040295991344, (float)0.2576970066573888, (float)0.3861369941754452, (float)0.061145076989667826, (float)-0.14420514702521212, (float)0.057725214519479706, (float)0.21740879985295145, (float)0.029617020584398395, (float)-0.19781522712991687, (float)-0.11559486486373309, (float)0.07343196777814753, (float)0.017223090401022094, (float)-0.0598343051711808, (float)0.14586131387749718, (float)0.24154787455017282, (float)-0.04786083287457433, (float)-0.18690353462462347, (float)0.02677371295194646, (float)0.04561521313435857, (float)-0.13925269716369554, (float)-0.05844516842267857, (float)0.0411931869544438, (float)-0.18930082152312575, (float)-0.2794987982836608, (float)0.016881481224173284, (float)0.1432731478050967, (float)-0.07131620042986134, (float)-0.15068317639998272, (float)0.0017569386688597935, (float)0.08200285284555363, (float)0.07871247390572932, (float)0.14019205410530483, (float)0.16788957275910293, (float)0.014701763871429682, (float)-0.18207233718750473, (float)-0.1623000954806658, (float)0.005604517700517289, (float)-0.0036750244141419246, (float)-0.15301762223947324, (float)-0.07571378754978282, (float)0.17883325091158564, (float)0.1919880771493632, (float)-0.04209959519564627, (float)-0.13060042448568637, (float)0.031831211080877206, (float)0.14994002586117333, (float)0.03480543166438985, (float)-0.09649471903119212, (float)-0.011967734050064136, (float)0.046801778447525755, (float)-0.17669942782815196, (float)-0.32388456723989345, (float)-0.09597102560347817, (float)0.10331847115598021, (float)0.05645902609492395, (float)0.16157643900148638, (float)0.42964360269152424, (float)0.41980827128570775, (float)0.17886167795409497, (float)0.018779070497760644, (float)-0.05460797429493844, (float)-0.005767752314998979, (float)0.17474169468463951, (float)0.13803937051460394, (float)-0.1860455423806749, (float)-0.33961961742943986, (float)-0.1936473732526304, (float)-0.04552204730359149, (float)-0.00337791365741014, (float)-0.06653106201927596, (float)-0.2179636471555107, (float)-0.25011310135188164, (float)-0.13779249661263432, (float)-0.07925631892450398, (float)0.013577920376051038, (float)0.15198745904421004, (float)0.0021102661240782186, (float)-0.24705692808773067, (float)-0.10187042569825004, (float)0.10070840642671289, (float)-0.008945915053569764, (float)0.08256228156374062, (float)0.411907976308605, (float)0.2629685259939295, (float)-0.10276628251076567, (float)0.05427351096192899, (float)0.2548667726276235, (float)-0.042920082946535355, (float)-0.23074183649274788, (float)-0.0631211733158609, (float)-0.08140746408704255, (float)-0.13165645207597051, (float)0.18174986761088693, (float)0.34545810306986824, (float)0.07288137767583883, (float)-0.04528873954605845, (float)0.058302778279466845, (float)-0.10409495010501403, (float)-0.2729808713670688, (float)-0.029779838230534584, (float)0.159920196421615, (float)-0.06256126139583935, (float)-0.22924306529192123, (float)-0.10224900306689717, (float)-3.208417471469491e-05, (float)0.044433512439328596, (float)0.1438701222525301, (float)0.04437001853204338, (float)-0.2605675135591152, (float)-0.27357372034467037, (float)0.08610179447155661, (float)0.3383356191360771, (float)0.306689933100535, (float)0.1708937849940233, (float)-0.003319013189869865, (float)-0.12213043189799015, (float)-0.0493878061317116, (float)0.07300713290741578, (float)0.10211977791033003, (float)0.14491574408273375, (float)0.1297379916665441, (float)-0.12113745844660721, (float)-0.35413873441048926, (float)-0.2778801610631314, (float)-0.10618743975351806, (float)-0.03963922081827233, (float)0.08301872018008892, (float)0.2681943685456443, (float)0.25426700050758183, (float)-0.02173875435284296, (float)-0.31448342817514247, (float)-0.35335100252820806, (float)-0.15966440575704036, (float)-0.04212308491202102, (float)-0.08902144996027284, (float)-0.055763879495506305, (float)0.04554689227345332, (float)0.005285256517014064, (float)-0.008722106502398998, (float)0.16502193645592267, (float)0.2270664572786849, (float)0.04653646441496558, (float)-0.08124578658983335, (float)-0.01673406350405822, (float)0.17308682459045063, (float)0.37031800410109794, (float)0.2943225613745173, (float)-0.0023546977001476766, (float)0.012889391416515602, (float)0.27120623601372745, (float)0.1373994844315541, (float)-0.2119147257955861, (float)-0.18910584248781165, (float)-0.07869889620991487, (float)-0.21980588560150222, (float)-0.1679768998541242, (float)0.13884176638101642, (float)0.09793221017532566, (float)-0.24750488942904444, (float)-0.3187888877969761, (float)-0.12691717851704964, (float)0.00012324486664979685, (float)0.08286183438128425, (float)0.17159715497219613, (float)0.14257152339623708, (float)0.027541058805217008, (float)-0.011903934803869606, (float)0.010320507644845841, (float)-0.05465185374917594, (float)-0.17907891650512328, (float)-0.12110583027025434, (float)0.14917982260260687, (float)0.2889494630295966, (float)0.13073616378655212, (float)-0.06430439305383172, (float)-0.12541066501241455, (float)-0.16366441845358193, (float)-0.20377850784545282, (float)-0.16384317466220952, (float)-0.07220476911037607, (float)-0.004480715267453013, (float)0.007383669856151086, (float)-0.006531576050820241, (float)0.050476164910498555, (float)0.17156542416596662, (float)0.21388940791853647, (float)0.15401509539851607, (float)0.08222312196517816, (float)0.027398763805996425, (float)0.021043122391204292, (float)0.05176324052218535, (float)0.01112967563721346, (float)-0.03728479499751565, (float)0.029794248076759677, (float)0.039063201397032926, (float)-0.0645639255706359, (float)0.0029424017810816055, (float)0.14620038001445815, (float)0.018799116949771065, (float)-0.12199000508445727, (float)0.012324978907857434, (float)0.028648057588945713, (float)-0.20038877781410683, (float)-0.19273475386180097, (float)0.053663752187768976, (float)0.12694038122826407, (float)0.0922524261841393, (float)0.13269671748169615, (float)0.10158002640619922, (float)-0.0386754666746445, (float)-0.183049748978489, (float)-0.31576439019115254, (float)-0.3261620332945125, (float)-0.14532922478221216, (float)0.06510927639298342, (float)0.22700665005499987, (float)0.2708042760492974, (float)0.006909716516939798, (float)-0.3175182064858849, (float)-0.25449986914476824, (float)-0.04284466118639977, (float)-0.012170265419281005, (float)0.13072776010475662, (float)0.3689006730844293, (float)0.24264693050902833, (float)-0.013714135100438904, (float)0.05347606649714726, (float)0.12781877055685897, (float)-0.03332123498958356, (float)-0.10875285092069029, (float)-0.0667320794504825, (float)-0.044690312522511245, (float)0.12288184366007555, (float)0.2762953785366351, (float)0.03139083571393142, (float)-0.3163946734010846, (float)-0.27643356762497995, (float)0.012898745160185136, (float)0.23284864171920122, (float)0.24802814105304985, (float)-0.009003469263962454, (float)-0.2839226939287235, (float)-0.2077033860405259, (float)0.05125567423920417, (float)0.10706334856715635, (float)-0.01928420413059676, (float)-0.10435210712219906, (float)-0.01719249348939754, (float)0.20033253378304836, (float)0.2780868932432925, (float)0.11937307740773682, (float)-0.018642941659337216, (float)-0.1019937202512777, (float)-0.2612584780257403, (float)-0.23132081410236827, (float)0.10510610349750096, (float)0.26122069221523087, (float)0.03063403119854358, (float)-0.21159054801798846, (float)-0.29507413796358994, (float)-0.3000796786105431, (float)-0.18466233925044612, (float)0.006764456800718719, (float)0.13704269658701848, (float)0.1943661746684928, (float)0.1796666317842841, (float)0.15555239930128636, (float)0.20426984367075807, (float)0.09563354120376633, (float)-0.23906183808453668, (float)-0.277537436777182, (float)0.08481249472219073, (float)0.2352034321765886, (float)0.11745337416367976, (float)0.15132153212174113, (float)0.16125462773465782, (float)-0.01882497401322536, (float)-0.021054981056447687, (float)0.09661535821964316, (float)-0.030029405586690018, (float)-0.1751224252165584, (float)-0.11178077874874034, (float)-0.03751594700782734, (float)0.06101756460769072, (float)0.15370531585997618, (float)-0.04774925146806916, (float)-0.25734890224408635, (float)-0.07543053750047217, (float)0.016277594372614623, (float)-0.25655688219868467, (float)-0.30692515216061184, (float)-0.0768385111933152, (float)-0.05400425236537792, (float)-0.0802205822429423, (float)0.07332907619493109, (float)0.14249811367424356, (float)0.15731685533015927, (float)0.226653393093762, (float)0.09260752893598216, (float)-0.041545560430447666, (float)0.16939145672777542, (float)0.19302433487665407, (float)-0.21244345892413286, (float)-0.26394407298274897, (float)0.1322161603474829, (float)0.22943234653460942, (float)0.11237538272945996, (float)0.21843091479378537, (float)0.2582502670097402, (float)0.1015304956488355, (float)0.04978034467580301, (float)-0.006609567273644306, (float)-0.1827534802313962, (float)-0.2153561429634877, (float)-0.16872907239844642, (float)-0.2206350789056196, (float)-0.14573734883106396, (float)0.01056442168016648, (float)-0.06259190224656667, (float)-0.1381139552971379, (float)0.015920098976878516, (float)0.07270253618432375, (float)-0.06903439196543244, (float)-0.15600320104897125, (float)-0.1876745462822013, (float)-0.16265713858734254, (float)-0.0009963069136785755, (float)0.0600828769006441, (float)-0.015216086981405166, (float)0.13885227682608908, (float)0.3675694255156428, (float)0.2071327524249084, (float)-0.11391907926969504, (float)-0.17746695198768325, (float)-0.04894370137965478, (float)0.174812636089341, (float)0.3698982799973464, (float)0.24646120357710527, (float)0.0034981363124001272, (float)0.0737401209750421, (float)0.2150667669250633, (float)0.1017655811272699, (float)-0.03917269574804911, (float)-0.14978973692668823, (float)-0.3296464804915575, (float)-0.2781548444291223, (float)-0.016405841777352492, (float)-0.03597315015474173, (float)-0.17432345406331967, (float)-0.01807816326868413, (float)0.0655726222962461, (float)-0.11552686149763229, (float)-0.04218315660008143, (float)0.19993729481083983, (float)0.03994942703364187, (float)-0.20624742889774592, (float)-0.004159390510214516, (float)0.2444076395491167, (float)0.1127246944638599, (float)-0.0607784062443039, (float)-0.004615568741265488, (float)0.03006903190086476, (float)-0.14403180295364765, (float)-0.3034130391635307, (float)-0.14686341709054307, (float)0.1796361562583816, (float)0.23263496491288507, (float)0.08001275228648898, (float)0.15651175627490516, (float)0.2729931820544649, (float)0.015884734817932688, (float)-0.21895610624054915, (float)-0.01939185737693344, (float)0.0892011423464121, (float)-0.2329408039257292, (float)-0.3680899603761354, (float)-0.022474257161429645, (float)0.1913785389778584, (float)-0.02178581385265506, (float)-0.17502798748456125, (float)0.0345399463672121, (float)0.3016174841994784, (float)0.28711521505443083, (float)0.011648930719361182, (float)-0.26094882323389557, (float)-0.26302351497434523, (float)0.002681411732885517, (float)0.19710096130006483, (float)0.11111572491011397, (float)-0.002271261529242247, (float)0.05562091081161034, (float)0.06760739341122722, (float)-0.008564372176373966, (float)0.09183635629887005, (float)0.2011976849902101, (float)-0.025767097699300034, (float)-0.2589055555748491, (float)-0.15309938960339672, (float)-0.10301998594833596, (float)-0.25910974152462946, (float)-0.16634470880409208, (float)0.07968994190573703, (float)0.05613721762482513, (float)0.08555823840213654, (float)0.39828911074681767, (float)0.4201869251337725, (float)0.08104157170079304, (float)0.007941144213614689, (float)0.085062812893594, (float)-0.17153069769828788, (float)-0.3948518390136364, (float)-0.2069953347010217, (float)-0.03134830520328276, (float)-0.11862953178823234, (float)-0.19577199966774614, (float)-0.1665478276828089, (float)-0.05557294829068143, (float)0.1426082916954237, (float)0.17487963650135657, (float)-0.018788888974273357, (float)-0.03171665202751397, (float)0.12614722321765864, (float)0.027959314868067107, (float)-0.13091917782734971, (float)0.045878826186486074, (float)0.23230452294340373, (float)0.1522184890462725, (float)0.11689313760998715, (float)0.11458470007504488, (float)-0.1078583536073732, (float)-0.1928690018535667, (float)0.07008264309737418, (float)0.11894856758222137, (float)-0.09578370380532927, (float)0.08263488430489951, (float)0.3959500587252997, (float)0.06015376405252373, (float)-0.4176431559416584, (float)-0.1606673791727958, (float)0.25691419921159825, (float)0.06304522389009472, (float)-0.18443678442534275, (float)-0.007441842421945021, (float)0.01603977058289064, (float)-0.28979390504094427, (float)-0.3366705793773354, (float)-0.11900109617530598, (float)-0.045213927734467564, (float)0.05292291970778052, (float)0.2852686647947898, (float)0.2055993199107285, (float)-0.152266811328032, (float)-0.17370976413485545, (float)0.1134995559212117, (float)0.15932298780741325, (float)-0.0036039373278695776, (float)-0.0027620989850999046, (float)0.08458202064791501, (float)0.048920926201094124, (float)0.004159319723058566, (float)0.06443047461264664, (float)0.13968777728417367, (float)0.16192276600376698, (float)0.10127976394101178, (float)-0.08136608459603566, (float)-0.2427481301287019, (float)-0.1715114124007814, (float)-0.011915207521816304, (float)-0.0663077527988956, (float)-0.1970967726027623, (float)-0.0909697366217604, (float)0.06764672823824412, (float)-0.015192213140953615, (float)-0.08547503904131133, (float)0.09078711153140115, (float)0.17627057250189893, (float)0.018095493659697825, (float)0.007260973763168889, (float)0.18304570810870546, (float)0.1270937647221626, (float)-0.07625615263361185, (float)0.0038213672699088683, (float)0.1836012794297488, (float)0.02421165109358271, (float)-0.24149902447296287, (float)-0.16738629639036795, (float)0.03365864049432094, (float)-0.0374662814608135, (float)-0.173478412076035, (float)-0.04380579964912126, (float)0.12178404455428589, (float)0.08376948924593985, (float)0.09995592109275839, (float)0.2180568585500651, (float)0.048597377790989355, (float)-0.2749977128181593, (float)-0.17228849400607804, (float)0.20665058557647115, (float)0.2609336872572035, (float)0.04819906465737258, (float)-0.10771741286916738, (float)-0.2571620107787632, (float)-0.30346172896161216, (float)-0.02325725821342988, (float)0.2746764466106204, (float)0.23663599673140467, (float)0.05386921552236337, (float)-0.1151401561209487, (float)-0.30627853431817886, (float)-0.31828859648366625, (float)-0.11182849318193622, (float)0.010080382476578376, (float)0.09265100187699596, (float)0.29496859360753624, (float)0.2817079228124642, (float)-0.016909137626531196, (float)-0.08064185225570657, (float)0.11487593039746188, (float)0.14653844533046612, (float)0.11159166763068379, (float)0.14041046658152706, (float)-0.07060310601184663, (float)-0.35413979755052477, (float)-0.20598497730504747, (float)0.09746036788668004, (float)0.06133886182821023, (float)-0.05692127775586484, (float)0.0284632150658303, (float)0.09531324054493141, (float)0.0411918086267044, (float)-0.039524335587654676, (float)-0.12477644875719271, (float)-0.06540683617756879, (float)0.12951262287944798, (float)0.06005882086136347, (float)-0.2222700910602574, (float)-0.1654738703617623, (float)0.11368198494683242, (float)0.11742038623179031, (float)0.07208408224011978, (float)0.2065804611500657, (float)0.08564922454717387, (float)-0.21434023344653283, (float)-0.05926892081650057, (float)0.24060095947039797, (float)-0.02009878697651851, (float)-0.37357233672704443, (float)-0.16096410070784667, (float)0.12996084511032122, (float)0.0534938085094182, (float)0.050833252479824856, (float)0.21321414993171595, (float)0.03858727118433067, (float)-0.31056398325488666, (float)-0.20510273645379576, (float)0.18289033435746427, (float)0.1836172005705716, (float)-0.1774654286455319, (float)-0.2905160538000343, (float)0.034498006165737144, (float)0.3329908370647023, (float)0.20192066277908297, (float)-0.12533519072558252, (float)-0.13269615114614464, (float)0.194315342964661, (float)0.3280535941048365, (float)0.015141176553424235, (float)-0.31516210459005894, (float)-0.23741460004428933, (float)0.03474958847279494, (float)0.1323679488850768, (float)0.10589418328299215, (float)0.050908655086166425, (float)-0.08968548571517941, (float)-0.08627178625457302, (float)0.19002081476632351, (float)0.20304931812856056, (float)-0.2046431179071473, (float)-0.26375608837881526, (float)0.10005726216595251, (float)0.02942771057839175, (float)-0.29898587944858385, (float)-0.060566650631622455, (float)0.25127293001802214, (float)-0.04577609685089866, (float)-0.26275561833968164, (float)-0.010546204261330227, (float)0.05856568915321235, (float)0.016993401946836354, (float)0.2971247223606839, (float)0.29039914912156756, (float)-0.22390458939013155, (float)-0.3176899050808446, (float)0.08541485841930938, (float)0.15098318125264523, (float)-0.058696209830973296, (float)-0.09719012645034027, (float)-0.08074653354573377, (float)0.060781436049210005, (float)0.35294176853948767, (float)0.22177431458462454, (float)-0.2257202976947665, (float)-0.16678102546342038, (float)0.1441358374288189, (float)-0.015264835925784388, (float)-0.20595655400784144, (float)0.03725070598216933, (float)0.20767419760498848, (float)0.10737983325092346, (float)0.08499869006287468, (float)0.07150967705871364, (float)-0.07366258901637668, (float)-0.15938664869344402, (float)-0.16156762211253853, (float)-0.12861001700228852, (float)-0.02223312383121168, (float)-0.047515889358483686, (float)-0.22599286444683325, (float)-0.1733272048132747, (float)0.030513169171467125, (float)0.024361892495048092, (float)0.05286251840278483, (float)0.25246441807039, (float)0.19021351908320852, (float)-0.028636533717267508, (float)0.05090026191036193, (float)0.11663699111755885, (float)-0.09838086439505021, (float)-0.08234618950075295, (float)0.2417087694899069, (float)0.27882112951284055, (float)-0.012921032279175177, (float)-0.18859561989074297, (float)-0.13951209729827466, (float)-0.027572711389716748, (float)-0.035722677314312286, (float)-0.1729678254951576, (float)-0.13763949837815698, (float)0.07339098589968754, (float)0.018029417943778568, (float)-0.18832935731761793, (float)-0.009344833203062399, (float)0.3344607331522365, (float)0.2968373208714935, (float)-0.0006608371212481327, (float)-0.2099604536531838, (float)-0.18022728708093194, (float)0.13219532667259948, (float)0.31742562743662733, (float)-0.032134198438987016, (float)-0.369766348736327, (float)-0.15169369529038468, (float)0.08170103279050768, (float)-0.052547966582666084, (float)-0.08153645134877649, (float)0.09405101148985152, (float)0.12462654891540234, (float)0.09654640436854575, (float)0.09608257372750614, (float)-0.04736565463558663, (float)-0.12720859685466648, (float)0.013859235370499276, (float)0.02616874155295702, (float)-0.06674747153972253, (float)0.07251340349573664, (float)0.11490461015612545, (float)-0.19391851824113895, (float)-0.24871723398462384, (float)0.10657369294352832, (float)0.16924054868484736, (float)-0.07421333984144098, (float)-5.757933142228211e-05, (float)0.20727033416351004, (float)0.059391572961051645, (float)-0.10118971106431994, (float)0.05396206057768911, (float)0.10050835379587715, (float)-0.091714658668153, (float)-0.038415276524028076, (float)0.18783370891791998, (float)0.03401857918066509, (float)-0.25929742485870966, (float)-0.0791406338072933, (float)0.20969462329153354, (float)-0.037990017608965, (float)-0.3875279323586832, (float)-0.18767931673530716, (float)0.17572859387582387, (float)0.13260250105282878, (float)-0.08715841369823908, (float)-0.1060092018313519, (float)0.01900311676972722, (float)0.11754914910460164, (float)0.08609786238513085, (float)-0.053484840913759366, (float)-0.07575862902344141, (float)0.0558267975157603, (float)0.0803636250028255, (float)0.03351862290043972, (float)0.1604406954167361, (float)0.2737549798075173, (float)0.13729207835595547, (float)0.007221462876466846, (float)0.022340726599587604, (float)-0.07699045132494993, (float)-0.23874131061954457, (float)-0.16070949718424624, (float)-0.0019588798619616103, (float)-0.05774974343915143, (float)-0.1542305719576124, (float)-0.07363290035091301, (float)0.04472085078133813, (float)0.06940947066462838, (float)0.018935167630159754, (float)-0.10889460233936032, (float)-0.17735149848940363, (float)0.004655348746506, (float)0.1995670963645098, (float)0.0522449145309014, (float)-0.15558746128360756, (float)0.018544449160899843, (float)0.2782426667048664, (float)0.17198565865250073, (float)-0.02658160037145611, (float)0.04873612948788571, (float)0.1501827833012139, (float)0.016706158477301766, (float)-0.17919693708222764, (float)-0.25578596472130916, (float)-0.16994661270528466, (float)0.07921189085613028, (float)0.25966326427031006, (float)0.11162658293567408, (float)-0.1862721370234572, (float)-0.2854245366019588, (float)-0.14220076178768065, (float)0.07705227395291832, (float)0.16252840731001425, (float)0.004157088577588576, (float)-0.15945662909754016, (float)-0.04760455094194283, (float)0.18161694874011164, (float)0.285964337891847, (float)0.2945394741613877, (float)0.1708053900110795, (float)-0.12241864753655059, (float)-0.2860089031095643, (float)-0.15281557945250923, (float)0.004286334883998746, (float)0.044502501133349505, (float)0.066895494007783, (float)-0.0048856586034986115, (float)-0.2013858339172559, (float)-0.2831588671324641, (float)-0.15457538612511473, (float)0.0278317055186373, (float)0.15338417605407753, (float)0.1919135807471257, (float)0.18049400411194555, (float)0.2010470197594618, (float)0.2002715792136575, (float)0.1161510943682083, (float)0.021545353386404245, (float)-0.13148165097712464, (float)-0.33584372068028656, (float)-0.2622739803958085, (float)0.024825191843746968, (float)-0.033473774064060664, (float)-0.2660580705957991, (float)-0.05173934323631493, (float)0.22751122244658223, (float)0.010986850430268856, (float)-0.13876233798385382, (float)0.13352015035208648, (float)0.18482184388148534, (float)-0.049195669668431724, (float)0.004204586000673425, (float)0.11050716817960109, (float)-0.08957827428940167, (float)-0.09722098087852374, (float)0.23374474348930935, (float)0.29445683945611045, (float)0.04073588194816323, (float)-0.11589646737411874, (float)-0.23905991160673543, (float)-0.3329990830527369, (float)-0.07568905595611548, (float)0.28304052165229804, (float)0.17469214880883277, (float)-0.1959945883363777, (float)-0.23054839650951503, (float)0.07494148186232422, (float)0.32009657463559876, (float)0.32024608822324985, (float)0.16439236442476707, (float)0.028681901214997817, (float)0.005839068729570943, (float)0.01003032263623538, (float)-0.07070472835339635, (float)-0.18930785406646772, (float)-0.2325052545352152, (float)-0.20417205696051777, (float)-0.17724468231464863, (float)-0.12930616691577107, (float)-0.012798101165273976, (float)0.0696480709696919, (float)0.005796142001543192, (float)-0.11193689621693308, (float)-0.12219437882533016, (float)0.034474457593443385, (float)0.2862678417712397, (float)0.3561673579314832, (float)0.053814902710317705, (float)-0.2468853007587754, (float)-0.11197877108105118, (float)0.15846505007405634, (float)0.14378527084344025, (float)0.08807509683449621, (float)0.1950334446614184, (float)0.13677065922041967, (float)-0.15422796560424717, (float)-0.3210932035194444, (float)-0.2802748988541501, (float)-0.16609755209842278, (float)-0.01420833939756998, (float)0.05521728712729629, (float)0.025864363446011233, (float)0.16125306562037617, (float)0.39612396628462876, (float)0.3414504672178426, (float)0.10981232350023262, (float)0.031824268373576485, (float)-0.08482283938425553, (float)-0.3322310486587734, (float)-0.2856792243121915, (float)0.010442645908361624, (float)-0.02433478275851139, (float)-0.2847823030216868, (float)-0.17500789387085855, (float)0.15193022670477596, (float)0.15511143501220093, (float)-0.02620825226340129, (float)-0.0041616096188080084, (float)0.10739770962844446, (float)0.1284360025999072, (float)0.14593319260394627, (float)0.10991585274528164, (float)-0.038175271138931814, (float)-0.028726261780534067, (float)0.16269529364356236, (float)0.09769418942777443, (float)-0.2116395777294301, (float)-0.27145394035004144, (float)-0.1412077923580423, (float)-0.19941897660702432, (float)-0.2617886448827158, (float)-0.10929072170859863, (float)0.01679270914786035, (float)0.10753135368717251, (float)0.3219599571356937, (float)0.3612271175504648, (float)0.11526734027326077, (float)-0.0019929753441125155, (float)-0.0309173435289738, (float)-0.27064498224061984, (float)-0.3275588899945412, (float)0.035291705913064714, (float)0.22569717367804612, (float)0.09296853055387616, (float)0.11891627490299876, (float)0.18320415839861026, (float)-0.012413898671390625, (float)-0.09562839511181233, (float)0.08503085542580104, (float)0.15206953817106966, (float)0.11687763599594202, (float)0.12034241367320307, (float)-0.06992316963239985, (float)-0.3396812353031793, (float)-0.2710675252766122, (float)0.007304067506355755, (float)0.19268900041428702, (float)0.2553163227298672, (float)0.04066414659369072, (float)-0.3356451200586138, (float)-0.24618759068117907, (float)0.1952522747678537, (float)0.13792497234923712, (float)-0.28043435813650613, (float)-0.2335936541850303, (float)0.0822172714535548, (float)0.0034075871254881317, (float)-0.21282850506539, (float)-0.028916839240260138, (float)0.3238674241990208, (float)0.30804025776189436, (float)-0.040218152866327225, (float)-0.1947874612401926, (float)-0.009902259753400427, (float)0.03687592482722407, (float)-0.21835496105289617, (float)-0.31551853978083233, (float)-0.10759056254850091, (float)0.1161940761894155, (float)0.270355457408746, (float)0.24386056945363271, (float)-0.06527110523730213, (float)-0.14517237259270926, (float)0.2680814470361084, (float)0.43695877849905657, (float)0.1137106480517849, (float)0.010335881412114554, (float)0.13438631228574083, (float)-0.0056265052497939325, (float)-0.09731751742797212, (float)0.020340410993095037, (float)-0.1401103444850339, (float)-0.3402738535184561, (float)-0.1325092601537941, (float)-0.06478971959606937, (float)-0.27661944043934833, (float)-0.03515393380954273, (float)0.3961934971589873, (float)0.26894661818398224, (float)0.044339427677555665, (float)0.11040064323978628, (float)-0.05975487394328587, (float)-0.2802298254504279, (float)-0.002502216454565361, (float)0.18568482048775817, (float)-0.12822999251467856, (float)-0.259800249597894, (float)-0.0907048041825228, (float)-0.1523681855487273, (float)-0.2241759886445116, (float)0.02748198972975687, (float)0.25645548235429755, (float)0.2720747401286852, (float)0.15528229849567504, (float)-0.11479778326921901, (float)-0.22738281674627944, (float)0.015867686070768588, (float)0.05326456941575089, (float)-0.2566035557906996, (float)-0.2245526872450905, (float)0.09749366397195637, (float)0.0360237765118847, (float)-0.161101599296218, (float)0.06034805779681234, (float)0.3786985754318369, (float)0.3731317272843078, (float)0.183744447560605, (float)8.069614193035599e-05, (float)-0.06350606802696171, (float)0.0777423138605407, (float)0.22393642411522852, (float)0.16854088566732428, (float)0.03640984625496631, (float)-0.014814190443111419, (float)0.009150012615098192, (float)-0.0014137864459425572, (float)-0.16066178600123868, (float)-0.26478993121178007, (float)-0.06389685068384436, (float)0.04631619266122693, (float)-0.24587840899792504, (float)-0.30124802739883616, (float)0.13933861633997618, (float)0.20049767070771451, (float)-0.2689763620566839, (float)-0.2824168640200461, (float)0.17832714813997833, (float)0.1579448761344669, (float)-0.2816674793402485, (float)-0.34704211435610616, (float)-0.07864277901807312, (float)0.0161757044059059, (float)-0.031191348018459505, (float)0.05321249318696362, (float)0.2189748978696314, (float)0.255464405014456, (float)0.18708371926452408, (float)0.2071880539852585, (float)0.24147051915810056, (float)0.06424774312662956, (float)-0.140728395713851, (float)-0.0996827007598743, (float)-0.0362778857736916, (float)-0.07758231310789679, (float)0.0930214690482072, (float)0.3135730352173134, (float)0.04340310381605359, (float)-0.37468189213216, (float)-0.21145474804728398, (float)0.19548454458640988, (float)0.11062456560655518, (float)-0.23586155603075148, (float)-0.2672453316942891, (float)-0.05938179390320542, (float)0.12384262144004116, (float)0.291115419943407, (float)0.34660618179188574, (float)0.15851736835500688, (float)-0.020495065722343844, (float)0.02103704217573935, (float)0.0011781725000763721, (float)-0.20989891082287918, (float)-0.2578190290918385, (float)-0.13000960184808802, (float)-0.1797865518648784, (float)-0.18947964321111296, (float)0.12662722857082212, (float)0.197070389421509, (float)-0.21841318589451525, (float)-0.2605361863519305, (float)0.21720079296242317, (float)0.22315233206561524, (float)-0.22705215323910002, (float)-0.18814182352149253, (float)0.1667403688916435, (float)0.14807491744838297, (float)0.04421840483165532, (float)0.13003617018745312, (float)0.030387139027809745, (float)-0.15310351610193293, (float)-0.051442728953161404, (float)0.061252862535790084, (float)0.02865552860144704, (float)0.15139174113614223, (float)0.25309284483940336, (float)0.05734701030365588, (float)-0.04134549517652854, (float)0.10536462772130435, (float)0.06022717571502484, (float)-0.1019684618980718, (float)-0.014483560982850275, (float)0.03651316709266521, (float)-0.20152522434567427, (float)-0.3306598866270685, (float)-0.1442027738073703, (float)0.08146002480527448, (float)0.15368126739409255, (float)0.02297724332285585, (float)-0.16543270309548946, (float)-0.021841713131124544, (float)0.3222990551751446, (float)0.2054323512591778, (float)-0.23264771181737634, (float)-0.21608129256977696, (float)0.08598506895429857, (float)-0.017499629231656665, (float)-0.2669274536846657, (float)-0.14034674239179007, (float)0.049995662591693864, (float)-0.0019361923526802535, (float)-0.010469872277346092, (float)0.11413284489104127, (float)0.18027309108909448, (float)0.22312400687710407, (float)0.2446364055508926, (float)0.16157326267284566, (float)0.14940638397916645, (float)0.17899517140006888, (float)-0.0950054802375768, (float)-0.40789430739096794, (float)-0.2279273067131343, (float)0.042267051234424265, (float)-0.1292419797942893, (float)-0.2867149196843538, (float)-0.10267808350666084, (float)-0.018815519340219404, (float)-0.05461476457620925, (float)0.13202566138448008, (float)0.23920011809454939, (float)0.035063476138276164, (float)-0.013358729044778604, (float)0.2163829649745133, (float)0.29192398007879794, (float)0.11941397394084483, (float)-0.1315874107810505, (float)-0.32619006404653317, (float)-0.23027615261230788, (float)0.018410581527465122, (float)-0.053833792720370297, (float)-0.2405793084975927, (float)-0.052296076281613264, (float)0.18023174608459827, (float)0.08042967455102065, (float)-0.03917493057528897, (float)-0.06737610238375566, (float)-0.14075059720989327, (float)-0.020823472236190885, (float)0.23148131957352974, (float)0.16874791231059824, (float)-0.0009715022834013875, (float)0.08170165230688504, (float)0.1043905215489091, (float)0.016933834550461727, (float)0.14692882221410034, (float)0.19196713733937307, (float)-0.0443646209965277, (float)-0.009161311081658116, (float)0.25187308240713546, (float)0.12564699807941987, (float)-0.1138941801315095, (float)-0.04085099579222959, (float)-0.09903158316619907, (float)-0.39551827038607756, (float)-0.3671698032565086, (float)-0.033869828692360125, (float)0.17362120438212664, (float)0.17808562027631786, (float)-0.03644028642040056, (float)-0.34448288258092813, (float)-0.3422107823617401, (float)-0.10195232789207695, (float)-0.0090457034716094, (float)0.06248558056122872, (float)0.21702822649768466, (float)0.18803083973710216, (float)0.0923973710718455, (float)0.13082844377445663, (float)0.03269800717161374, (float)-0.13408929387185156, (float)-0.0045075965173756, (float)0.11411312311038434, (float)-0.04594830461117837, (float)-0.04830364813775651, (float)0.1144869553945805, (float)0.002379175878759027, (float)-0.1314589958399664, (float)0.034071352694203076, (float)0.14399370612698426, (float)0.10314265872798807, (float)0.1910681829677591, (float)0.24302225994119828, (float)0.0928797294552553, (float)-0.0037223108592471157, (float)-0.022379491235310193, (float)-0.1635223135006411, (float)-0.33869261368977244, (float)-0.3434573770497618, (float)-0.1112411511997347, (float)0.1477704170801475, (float)0.036699610530301775, (float)-0.22705926216284048, (float)0.0061512359045713, (float)0.4139535090558771, (float)0.27976440994557406, (float)0.02636138342136511, (float)0.08561359669354632, (float)-0.08003877816744553, (float)-0.3858704923484779, (float)-0.18296858393613263, (float)0.09205897641505555, (float)-0.01539886054620783, (float)0.036339805356292554, (float)0.13987669583058607, (float)-0.21252666907247417, (float)-0.29532302177127034, (float)0.21687984624572992, (float)0.21398160454539622, (float)-0.3048285302832028, (float)-0.1976021800248669, (float)0.1770877481579701, (float)-0.02023671222752198, (float)-0.13437739083502923, (float)0.22756645765298503, (float)0.25044078966676636, (float)-0.15011648180969098, (float)-0.2264097963856296, (float)0.08343219706696994, (float)0.3535168684805521, (float)0.35370839852538744, (float)0.07563577375851732, (float)-0.10923849201911484, (float)0.07401837448381472, (float)0.2219536937090742, (float)0.0807388744364803, (float)-0.03307766284826395, (float)-0.11203130266186907, (float)-0.30166670087927905, (float)-0.272478673097733, (float)0.01891064070392186, (float)0.08553403976236354, (float)-0.08922767828290822, (float)-0.13863949346709284, (float)-0.06263607104178855, (float)0.014769662144749339, (float)0.0687809325574784, (float)-0.0013304547674789491, (float)-0.14123714833119294, (float)-0.16297667889631617, (float)-0.0755966810528918, (float)0.07683174173232311, (float)0.22358732962307087, (float)0.14794665476073612, (float)-0.021932938434410954, (float)0.03617360704696576, (float)0.06846056574347885, (float)-0.13294578708526894, (float)-0.11650557688013664, (float)0.11730297166764676, (float)0.013681879211641488, (float)-0.21093260509499603, (float)-0.05968020335190216, (float)0.16315879621556853, (float)0.17773598456113612, (float)0.1601501747367311, (float)0.06773424147622466, (float)-0.025190011051749873, (float)0.12518164548518937, (float)0.12255509968806554, (float)-0.24221826834173163, (float)-0.2609895747360395, (float)0.08469648378819139, (float)-0.016296487333275593, (float)-0.2972161920670392, (float)-0.09655564760332826, (float)0.09213938873283355, (float)-0.02491625933114541, (float)0.12190012203242608, (float)0.3938745403710267, (float)0.2770398106708536, (float)0.0811301351966604, (float)-0.024369089368573803, (float)-0.29438145863973775, (float)-0.3508273008252132, (float)0.022099726654455514, (float)0.16419101921129756, (float)0.0017935336377379383, (float)0.08183577706141489, (float)0.11394156351012952, (float)-0.21907667068236228, (float)-0.26138027368388805, (float)0.13884282854609756, (float)0.16905021927855587, (float)-0.25358999279072303, (float)-0.3630604441412556, (float)-0.01942828106580532, (float)0.1855402104966503, (float)-0.017138864781580686, (float)-0.20283694039452027, (float)0.033096800124940685, (float)0.3396918036915791, (float)0.20431056368136788, (float)-0.0786135562054261, (float)-0.04743104284158155, (float)0.05325889961407077, (float)-0.003568656567425729, (float)0.013246151917748611, (float)0.059459127056639, (float)-0.051447443422665246, (float)-0.03987685815632297, (float)0.230725014083957, (float)0.34234934862692507, (float)0.1358669087649767, (float)-0.030408682633628014, (float)-0.013666872910013712, (float)-0.08250182121380081, (float)-0.3224615265827859, (float)-0.36514655766926657, (float)-0.011654998983069417, (float)0.27198660846920897, (float)0.12084972631006077, (float)-0.08305525281175351, (float)-0.054130577382811, (float)-0.0179047813709238, (float)0.046867335369713034, (float)0.1774141593257994, (float)-0.022150870664260254, (float)-0.3720788117307623, (float)-0.21543635189068075, (float)0.08236056929735658, (float)-0.07428024921031032, (float)-0.14315610511825413, (float)0.11124556212053863, (float)0.03342768252362132, (float)-0.13244179309830817, (float)0.18471406236412735, (float)0.27173472099255563, (float)-0.19156320990716405, (float)-0.21895025167914745, (float)0.1821556876985601, (float)0.0890515967453056, (float)-0.12003899405084081, (float)0.1998450680068182, (float)0.3929036507254258, (float)0.074588018170769, (float)-0.1630896885108212, (float)-0.1921635695144539, (float)-0.2565088097642451, (float)-0.15530907974587896, (float)0.14993484413478647, (float)0.325411499883261, (float)0.268471876026734, (float)0.06353025022626338, (float)-0.11523247148138419, (float)-0.03640666760658014, (float)0.09730233605355398, (float)-0.03987335362303564, (float)-0.18007145469686858, (float)-0.08609950122581993, (float)0.002122465647854129, (float)0.0922035760903452, (float)0.2581585702955569, (float)0.161374327563951, (float)-0.13180362683844152, (float)-0.1865267208161095, (float)-0.22090191150690305, (float)-0.40768410253103, (float)-0.2363605613452582, (float)0.17560798940362593, (float)0.15160669436090898, (float)-0.017115309792133823, (float)0.16016295988911905, (float)0.20463284450318123, (float)-0.10546589629481663, (float)-0.2659466982970714, (float)-0.23509553833771024, (float)-0.18263407943755675, (float)0.09017359299319892, (float)0.34003380165024627, (float)0.14236675677440072, (float)-0.09221239607843161, (float)-0.014018405252743612, (float)-0.04379699839313919, (float)-0.18160205597885629, (float)0.048404239646633325, (float)0.36471223728231444, (float)0.2368356389668215, (float)-0.02455271819149406, (float)0.04722069307408551, (float)0.22195128622758561, (float)0.0802429266931434, (float)-0.24834232196132242, (float)-0.22056476615641307, (float)0.21857348567369603, (float)0.35243567276516824, (float)-0.061345794538140375, (float)-0.2400525893592068, (float)0.06499520472824209, (float)0.0781627479420438, (float)-0.26805496330739603, (float)-0.19644666471044206, (float)0.17916704319173316, (float)0.1393945758467945, (float)-0.11602818204919443, (float)-0.06286033503806047, (float)0.03906913717031186, (float)-0.10444055265798212, (float)-0.20983232239728064, (float)-0.16181470583344745, (float)-0.15640170375104642, (float)-0.09690979297761788, (float)0.11970822414523902, (float)0.17546141033687981, (float)-0.03651667502359488, (float)-0.1211805871819103, (float)0.030920800501773805, (float)0.10803213232314834, (float)0.09434823092034726, (float)0.16562006101484858, (float)0.19147227897811778, (float)0.06878494088510759, (float)-0.0824442568050075, (float)-0.2556644963630694, (float)-0.33123442418286975, (float)-0.03477382840199961, (float)0.30814948562766, (float)0.1544867554538255, (float)-0.13206264111858726, (float)-0.05577081874064, (float)-0.01479243993238396, (float)-0.17590773777373858, (float)0.003311858715696509, (float)0.3849345903492036, (float)0.3217846912233237, (float)0.01502762612923181, (float)-0.06743719439170538, (float)-0.04834003617155022, (float)0.014551753401234786, (float)0.1674766576566133, (float)0.11927746740930015, (float)-0.06810465707239352, (float)0.030283585387308704, (float)0.2026912406886902, (float)0.07860426376724175, (float)-0.07496353005402168, (float)-0.12267908335578812, (float)-0.2502525704100263, (float)-0.2553400004061527, (float)-0.07158275038809898, (float)-0.10158528009924639, (float)-0.26668160285066084, (float)-0.21030081367502887, (float)-0.13203254038723078, (float)-0.10657875020250678, (float)0.11979965173144995, (float)0.2318584449601302, (float)-0.011949504607397876, (float)-0.03624382236473758, (float)0.2524350788237425, (float)0.21180566938448023, (float)-0.05626425146673928, (float)-0.06098019581018483, (float)-0.025914053803667233, (float)-0.06096107168158001, (float)0.15624792213628583, (float)0.3302241210210654, (float)0.028933451628964033, (float)-0.2917163670258814, (float)-0.16055478170333934, (float)0.1081555676370766, (float)0.1339636146413108, (float)-0.005319688455964873, (float)-0.015332778277948413, (float)0.1629993816378002, (float)0.13540162975653164, (float)-0.18869921145242213, (float)-0.17161473156463686, (float)0.2348040590674813, (float)0.21740831554788062, (float)-0.12280924494177266, (float)-0.019567585211107297, (float)0.1415127552218538, (float)-0.17621192106174, (float)-0.2767999312382469, (float)0.09965714206756633, (float)0.1456302039357834, (float)-0.11421671327556306, (float)-0.040060443513516, (float)0.05544496036731962, (float)-0.16932500482101337, (float)-0.22678832770173518, (float)-0.038670685635340686, (float)-0.0006637445300532823, (float)0.06644448960060993, (float)0.2978133240578729, (float)0.22633589564622283, (float)-0.16429437978388745, (float)-0.2888519350072171, (float)-0.05055056204743146, (float)0.1432002921672354, (float)0.13918179040140852, (float)0.09561527375836032, (float)0.10482664853093467, (float)0.03495791383150356, (float)-0.20068087209710864, (float)-0.33699316198395035, (float)-0.1775001321133779, (float)-0.014956588109053582, (float)-0.043249805874208534, (float)-0.031368704696642206, (float)0.05806003915979227, (float)0.06868937916676622, (float)0.13996058572238554, (float)0.32724435044884326, (float)0.3408101400130453, (float)0.1198806849932953, (float)-0.11740532119791536, (float)-0.26551663084829935, (float)-0.22541146691260447, (float)-0.015079345790078004, (float)0.015032846266503318, (float)-0.1873021039256532, (float)-0.15399697592226502, (float)0.18203901486148452, (float)0.3536862093566999, (float)0.24893962728036145, (float)0.13625019923292292, (float)0.05787229796829857, (float)-0.10582423623761303, (float)-0.27222657542776, (float)-0.19557459660331142, (float)0.12875221081564858, (float)0.2661008615071863, (float)-0.010733310814153069, (float)-0.23306978766188927, (float)-0.10001010378091581, (float)0.019938384994542185, (float)0.015004253837018564, (float)0.10365145571860118, (float)0.024881443766235536, (float)-0.31380367357192723, (float)-0.29946426559836015, (float)0.08793615578066162, (float)0.1252465223680998, (float)-0.1269342203076324, (float)-0.10633711668496017, (float)0.02581324150450118, (float)0.004632241433303609, (float)0.024580332676729037, (float)0.06247617546326134, (float)0.033054920684608545, (float)0.14631110347889534, (float)0.24865699656860482, (float)0.05035656207255784, (float)-0.08252816008592706, (float)0.07338015668670679, (float)0.0529894437081425, (float)-0.20307578268242302, (float)-0.2452168991443239, (float)-0.07995213620066562, (float)0.09312595122367757, (float)0.28994879030814, (float)0.30667506288179025, (float)0.007626045905374171, (float)-0.244638373553587, (float)-0.21865089653209685, (float)-0.021123849112192054, (float)0.25876511969662447, (float)0.31754797352324954, (float)-0.03625505308129272, (float)-0.25404505782428033, (float)-0.06503310258140277, (float)-0.07631799604194502, (float)-0.28435808462563844, (float)-0.02595240484499805, (float)0.341196752144868, (float)0.13778512564143963, (float)-0.12373213133746669, (float)0.025933066866962267, (float)0.06473113407436476, (float)-0.1415591155489516, (float)-0.15523582818344514, (float)-0.09872037010804584, (float)-0.18785717441796207, (float)-0.11470389186243042, (float)0.15918774714470546, (float)0.30453952830467107, (float)0.29931345769516937, (float)0.1900494770654069, (float)-0.06595752706347997, (float)-0.18102894502067374, (float)0.02499393869010267, (float)0.14223440462143078, (float)-0.05748949832251196, (float)-0.2189292363335192, (float)-0.16817847888743437, (float)-0.12069806517843626, (float)-0.11449476040860906, (float)-0.011910664055209597, (float)0.09854021622767473, (float)0.023559295034687584, (float)-0.1320100776325423, (float)-0.07633736586159015, (float)0.13337493313592838, (float)0.14265979696774028, (float)-0.01268667898009686, (float)0.027346526046756917, (float)0.1724801004942593, (float)0.06668499683441892, (float)-0.14542013176099672, (float)-0.11932238517780039, (float)0.057425135434849096, (float)0.1551824531055979, (float)0.14580392283932325, (float)0.050362532460695233, (float)-0.03492228294298861, (float)0.021109858052953876, (float)0.05475787127214505, (float)-0.1231277877969252, (float)-0.20140785100513967, (float)0.102570380846276, (float)0.33045782262057927, (float)0.014451085464710908, (float)-0.3677855782195728, (float)-0.1774861476069661, (float)0.21367200713489173, (float)0.13926367700423659, (float)-0.1414143906217737, (float)-0.09655759416395064, (float)0.04444973725551519, (float)-0.025843071129306082, (float)-0.030529724164308544, (float)0.13275286992477556, (float)0.14334637710790915, (float)-0.02254273490929538, (float)-0.14370931629566208, (float)-0.16372104667269644, (float)-0.036061893393649194, (float)0.1274281026574531, (float)0.01909905970077711, (float)-0.15456372695282322, (float)0.001031970551746603, (float)0.07698590153839521, (float)-0.2282083384735685, (float)-0.23819289933969226, (float)0.17311882190428401, (float)0.1775584010026834, (float)-0.15505871598890733, (float)-0.12593363222318152, (float)-0.03415956759911165, (float)-0.18769100496565916, (float)-0.03353605424588259, (float)0.2945834243822539, (float)0.11994877248486706, (float)-0.06775292660319733, (float)0.29788672755709605, (float)0.47485397877821467, (float)0.12145844180718617, (float)0.00026744718423889706, (float)0.13448821703705718, (float)-0.08241400347777296, (float)-0.33200972179217336, (float)-0.13832231338521775, (float)0.0929240268507057, (float)0.08009744472940161, (float)0.0920203531261353, (float)0.1079814094074262, (float)-0.03342130816906771, (float)-0.11188414828883947, (float)0.00558717881528082, (float)0.11883552401034106, (float)0.10669221487793297, (float)-0.023189013769620483, (float)-0.20499764352364877, (float)-0.2286776013246733, (float)-0.07276751008255623, (float)-0.06087089547487239, (float)-0.24672020351293578, (float)-0.278272896564534, (float)-0.11739064427651724, (float)-0.06203582350583237, (float)-0.06411634373375931, (float)0.09405174468793728, (float)0.1979624930595825, (float)0.010290211759535638, (float)-0.1532125764405053, (float)0.014110475366009, (float)0.20875624756419722, (float)0.07924844744298248, (float)-0.1445575321141808, (float)-0.0675691353131161, (float)0.2269685765220017, (float)0.34398065132666383, (float)0.1896616984202917, (float)0.03147888202847571, (float)-0.01791259505148416, (float)-0.063269720985346, (float)-0.007498744171166349, (float)0.21020630808014115, (float)0.23290938373037456, (float)-0.01600608951207113, (float)-0.02669517618411724, (float)0.2009850673972528, (float)0.11513695886331946, (float)-0.1431103304055127, (float)-0.17036689316449904, (float)-0.27453156174736315, (float)-0.4510897091596853, (float)-0.13920174716740913, (float)0.2201481081178388, (float)-0.07183211313912159, (float)-0.24218742039792668, (float)0.22572636676566765, (float)0.26341175190369137, (float)-0.2914158322600482, (float)-0.2173229620384784, (float)0.3000033932542106, (float)0.1655507332222018, (float)-0.16299630876648427, (float)0.04812834636133657, (float)0.1952640001060723, (float)-0.05688344332244413, (float)-0.17763701994474282, (float)-0.11076468082716741, (float)-0.055290134716910834, (float)0.08932816981169898, (float)0.09260470240596576, (float)-0.18334180977670328, (float)-0.17213389838015775, (float)0.2186545860187309, (float)0.3131992544363025, (float)0.07550474189869226, (float)-0.016093623751936407, (float)-0.06321783370169103, (float)-0.2542695349664395, (float)-0.286149739563847, (float)-0.001269160707256489, (float)0.3149010251298715, (float)0.32633890238096275, (float)0.024855953582633386, (float)-0.1464519855317705, (float)0.04635675333688215, (float)0.12993122584530262, (float)-0.0954886530439406, (float)-0.12709976824696786, (float)0.04756053729648552, (float)-0.005909991086464455, (float)-0.07119164498341465, (float)0.04588697031159108, (float)-0.06475084124693391, (float)-0.2366698749549273, (float)0.03812576711886367, (float)0.2664752856292233, (float)0.007644296457727606, (float)-0.06645570329083485, (float)0.2456931904956755, (float)0.2276058605194532, (float)-0.08922186579633941, (float)-0.12641953993046987, (float)-0.05201765021616967, (float)-0.147285384624799, (float)-0.1296237587648877, (float)0.11322356118370755, (float)0.3149981406509516, (float)0.2771120981858146, (float)-0.00484279999491033, (float)-0.20865588851198982, (float)-0.05863723420497593, (float)0.02507205739900143, (float)-0.2659598614608362, (float)-0.3476913127966663, (float)-0.03300804723783256, (float)-0.02584271469207142, (float)-0.31820717077187743, (float)-0.22467245877700293, (float)0.06666092040345946, (float)0.06632153106523482, (float)0.06905463806370064, (float)0.2041555186346021, (float)0.07094397458454067, (float)-0.14875293400292688, (float)0.016331045939465633, (float)0.27285706186910785, (float)0.18762210730588066, (float)0.00437984638945477, (float)0.052496575449231205, (float)0.1989452737591405, (float)0.16118451588628754, (float)-0.07579106006749792, (float)-0.20653171099337372, (float)-0.06322068771063713, (float)0.060979188924401885, (float)-0.005931133292802539, (float)0.023449560000475014, (float)0.1957687568793895, (float)0.20799236098007354, (float)0.10771332504537373, (float)0.06911330352986558, (float)-0.06341279748493199, (float)-0.20413310401308496, (float)-0.02281858177941357, (float)0.1873052482056094, (float)-0.02645131429189731, (float)-0.26630652732730775, (float)-0.06935445818339628, (float)0.13057575972357435, (float)-0.10372512075698428, (float)-0.40548809328000907, (float)-0.3643209303964807, (float)-0.1519929931859272, (float)-0.062331184224767355, (float)-0.04994560804660151, (float)0.07295803297991231, (float)0.21029098231320145, (float)0.08658984555246728, (float)-0.13330120725921235, (float)0.02555953941218636, (float)0.39479247469753814, (float)0.3423320413696345, (float)-0.026333187571100307, (float)-0.11783330947829244, (float)-0.02751588143498684, (float)-0.10901320406566299, (float)-0.08404943455355912, (float)0.19330731480579177, (float)0.21365947832110543, (float)-0.07230545971221412, (float)-0.0617195310534906, (float)0.18191948588492513, (float)0.030397815765463902, (float)-0.3564110448939255, (float)-0.3270538867049849, (float)0.03982098854758485, (float)0.2277603301845981, (float)0.13879705481744212, (float)-0.03976503097120895, (float)-0.12863867965327283, (float)-0.021304205833449885, (float)0.06507694959371445, (float)-0.10452496217161722, (float)-0.19037422050355413, (float)0.08957573604415112, (float)0.27696854847044483, (float)0.13862575371833563, (float)0.1524903812235971, (float)0.3058617550426929, (float)0.09009142747345833, (float)-0.18433425231638464, (float)0.0227035010690772, (float)0.21991379282766327, (float)-0.05630277544804204, (float)-0.26988188363766963, (float)-0.1446936890057955, (float)-0.1390318277199521, (float)-0.2699672216813805, (float)-0.17847205805673202, (float)0.0012132703563626235, (float)0.058079196020536274, (float)0.10876245056852968, (float)0.11331794514893394, (float)-0.03691660813666181, (float)-0.1674996795031299, (float)-0.1805230105961542, (float)-0.15506929934653702, (float)-0.06927327998098554, (float)0.012364473360882049, (float)-0.02207339763653392, (float)-0.010054366754130826, (float)0.0930737564699263, (float)0.07784321057551068, (float)0.10887612900557139, (float)0.36539510094849154, (float)0.3790704030312044, (float)-0.008198675226306167, (float)-0.16844460740768324, (float)-0.023671385729305536, (float)-0.0865661187281221, (float)-0.13784992182219424, (float)0.17533027780315985, (float)0.3063674631971093, (float)-0.026727060432763232, (float)-0.20867848195608524, (float)-0.056522922180209816, (float)0.017850803056164283, (float)0.04927853014293905, (float)0.18057244326703592, (float)0.13436126787596805, (float)-0.06331391493039051, (float)-0.05005943825238961, (float)0.01926398785313477, (float)-0.16382228421144054, (float)-0.2801747815086451, (float)-0.039433218719793384, (float)0.13731418339891913, (float)-0.06777448672918025, (float)-0.23303713933987155, (float)-0.05015927402688357, (float)0.08467747310029625, (float)-0.07697158889922745, (float)-0.149215217985173, (float)0.04365060729859208, (float)0.1687624066062039, (float)0.139951151619245, (float)0.1308413677914054, (float)0.053466446410182895, (float)-0.12125458404674497, (float)-0.16126442433578575, (float)-0.0775345726500378, (float)-0.012581024278772968, (float)0.08995843025049957, (float)0.11620840876635495, (float)-0.04545049405600072, (float)-0.049078083660969316, (float)0.13672013459399449, (float)0.018646933271335327, (float)-0.19664914280770499, (float)0.03162577496856827, (float)0.23838038095468284, (float)-0.004092329015456929, (float)-0.08652895419255544, (float)0.12486188416047499, (float)0.039345468574338086, (float)-0.11373918130941407, (float)0.06369326287514758, (float)0.07420931706408435, (float)-0.1369535189604758, (float)-0.004267723316275727, (float)0.12156791758531138, (float)-0.1838492814506245, (float)-0.2155716378954594, (float)0.23009184056064108, (float)0.32110739440345215, (float)0.04156147595600203, (float)-1.1848456823264042e-05, (float)0.012419577053496778, (float)-0.1620342786170868, (float)-0.21404033141637874, (float)-0.1426496273661538, (float)-0.09469052437527012, (float)0.05642847316342846, (float)0.0767026819696605, (float)-0.2168783779636847, (float)-0.22147162235897003, (float)0.20321478757779515, (float)0.23579433205786704, (float)-0.162110622876161, (float)-0.14702645105348622, (float)0.2564294260503676, (float)0.3653842021325621, (float)0.14181776473483196, (float)-0.05939312371596646, (float)-0.08928798104258112, (float)0.05124291977682395, (float)0.16984699737677592, (float)0.09788094009314417, (float)-0.013846494100750211, (float)-0.1159863736485223, (float)-0.29254211406502567, (float)-0.24503033191633578, (float)0.11706258074901187, (float)0.17053368848609732, (float)-0.20755004499919127, (float)-0.2685103490281984, (float)0.07459779524005651, (float)0.13791952294290002, (float)-0.08748821676763968, (float)-0.1367675666371541, (float)-0.07486288706693696, (float)-0.03732238971691617, (float)0.12510807405781588, (float)0.2249861382764925, (float)0.01539149800959647, (float)-0.14074171962680043, (float)0.0436843662075331, (float)0.20720500704881398, (float)0.11893953902262726, (float)0.0004576131000561227, (float)-0.07430323843521287, (float)-0.13497766292812965, (float)-0.02714709547719953, (float)0.17139149503647938, (float)0.14447196733544448, (float)-0.04330701367535709, (float)-0.11170246478436271, (float)-0.08514503727951643, (float)-0.03683865098451068, (float)0.08072510674920906, (float)0.1517428904790658, (float)0.12447099902416248, (float)0.16949577746045505, (float)0.16908868659094317, (float)-0.08784580442649825, (float)-0.2413923707916081, (float)-0.006676278117337256, (float)0.14108601716699015, (float)-0.08558780439322285, (float)-0.2564600254996175, (float)-0.16859196488936684, (float)-0.07806053582528133, (float)-0.0723640873075856, (float)-0.1335690137964097, (float)-0.21548353131505088, (float)-0.04658472646769647, (float)0.29259617591752946, (float)0.2274915995322956, (float)-0.16514669257126297, (float)-0.15484134188167997, (float)0.23421006654923027, (float)0.3293244998966558, (float)0.07117276851061478, (float)-0.11794947149074436, (float)-0.1406588902614271, (float)-0.12907888542469523, (float)-0.11841800729758455, (float)-0.06714017127224309, (float)0.04984486492429064, (float)0.14109117053255432, (float)0.12021472067198215, (float)0.07240965968063809, (float)0.018511403191453262, (float)-0.07875745183659165, (float)-0.01932431493684643, (float)0.19023164697280176, (float)0.12456131936784832, (float)-0.11153688510516495, (float)0.026608337410685707, (float)0.24220888993988743, (float)-0.013424079399991582, (float)-0.23873015866462285, (float)0.003396382026009882, (float)0.08871802129441733, (float)-0.20997956108066929, (float)-0.22862330601571915, (float)0.08940652257344636, (float)0.15974943195625804, (float)-0.009744800409572511, (float)-0.008127570913658212, (float)0.16411097097211833, (float)0.20172492957241994, (float)-0.015148014980278323, (float)-0.19534416172662947, (float)-0.05713520673245238, (float)0.057164309640536926, (float)-0.20590357087262742, (float)-0.38217052765568277, (float)-0.11108335626125335, (float)0.12809792382916457, (float)0.0945011588197783, (float)0.09199510223228168, (float)0.054268546550304914, (float)-0.1337410392287226, (float)-0.14875123858619893, (float)-0.01176788601546446, (float)0.005040841311870809, (float)0.13486312803607595, (float)0.3790881628502906, (float)0.23432469180513332, (float)-0.06942123060289253, (float)0.03163692554974491, (float)0.114492006069201, (float)-0.1937672272696982, (float)-0.26928482493497274, (float)0.03507216356475528, (float)0.027469190600112277, (float)-0.25280799688537914, (float)-0.17570283803605666, (float)0.14255878392084417, (float)0.1868775440179933, (float)-0.024087501423293477, (float)-0.12666287194880724, (float)0.050200346083542534, (float)0.2779076403116043, (float)0.20960556570988967, (float)-0.03930332556054035, (float)-0.09975379127419641, (float)-0.03154879846900591, (float)-0.014926580115019393, (float)0.09866267724737243, (float)0.2614498162564017, (float)0.14443573726477174, (float)-0.16434024778187567, (float)-0.2792360511057166, (float)-0.1377720171089427, (float)0.057663221286968706, (float)0.0996658451155212, (float)-0.06588537197244591, (float)-0.1901279873328603, (float)-0.10663717018987563, (float)-0.03509544204566627, (float)-0.0374754489737077, (float)0.057680320742549494, (float)0.06699847641158414, (float)-0.12759805366471844, (float)-0.09975051029527528, (float)0.18427810646047418, (float)0.14700251705267436, (float)-0.16499523904860874, (float)-0.1898001459115136, (float)-0.002593496856696448, (float)0.08524521022083416, (float)0.1987914945128291, (float)0.27211154107767194, (float)0.03930362039291949, (float)-0.2001513176704456, (float)-0.08481376303977427, (float)0.08922699913385185, (float)0.05125134365977066, (float)0.0008366629552767814, (float)0.018762962494348764, (float)-0.004114900770102737, (float)-0.010959323405411534, (float)0.008462876575516176, (float)-0.05793219841289449, (float)-0.10967035945329097, (float)0.0007038864376615649, (float)0.12214403251057279, (float)0.08222237910148113, (float)-0.005053755029820836, (float)0.016298907581511476, (float)0.07693766689114549, (float)0.03451234287140068, (float)-0.05462850987077505, (float)-0.033273464570945994, (float)0.018437193850428163, (float)-0.08348739738134667, (float)-0.18584632018532285, (float)-0.04736381898036858, (float)0.12476743092830607, (float)0.0382890714485522, (float)-0.1272568254914043, (float)-0.11616752065592297, (float)-0.03828150334234531, (float)-0.022157791872629787, (float)0.006254908791974327, (float)0.05849043414595794, (float)0.06968908913499462, (float)0.06380902151199314, (float)0.060941693831326714, (float)0.03172872078565185, (float)0.00039661749194513907, (float)-0.009023652189338633, (float)-0.020418175155524743, (float)-0.007351899731811944, (float)0.05688025658576138, (float)0.08519426450319609, (float)0.01680931694185899, (float)-0.04505606508311328, (float)-0.00633551366603687, (float)0.046518886878408744, (float)0.00035745355087587425, (float)-0.07633793584307352, (float)-0.05068292108103162, (float)0.03330997635809374, (float)0.03853550733071938, (float)-0.023482702284404838, (float)-0.05557700472321619, (float)-0.05201935025711931, (float)-0.032707663903031814, (float)0.011474238691419189, (float)0.03179317294705113, (float)-0.0020280542477285556, (float)-0.00904756084148349, (float)0.034702143224144145, (float)0.04086023132879876, (float)0.007276184942472115, (float)-8.235160962624308e-05, (float)-0.00856465151920328, (float)-0.038028801685332854, (float)-0.026317266126062683, (float)0.010175567481292943, (float)0.000992028799770922, (float)-0.0118520121813525, (float)0.019912822524653213, (float)0.03406089263964201, (float)0.0084691018709162, (float)-0.0005414264068602551, (float)0.0008917626585561318, (float)-0.013286450448489626, (float)-0.005591798038396845, (float)0.02014565134391095, (float)0.010755654615578876, (float)-0.009695858979149508, (float)0.0012395095228391404, }; signal-estimator-0.0.9/src/base/processing/Impulse.hpp000066400000000000000000000002171452044147100230100ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include extern const std::array impulse; signal-estimator-0.0.9/src/base/processing/ImpulseGenerator.cpp000066400000000000000000000025461452044147100246610ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "processing/ImpulseGenerator.hpp" #include "core/Sample.hpp" #include #include namespace signal_estimator { void ImpulseGenerator::generate(Frame& frame) { const auto num_ch = config_.channel_count; size_t i_frame = 0; do { for (; i_frame < frame.size() && counter_ < impulse_size_ && counter_ < impulse_interval_; ++counter_, i_frame += num_ch) { assert(i_frame % num_ch == 0); assert(i_frame <= frame.size() - num_ch); for (size_t j = 0; j < num_ch; ++j) { frame[i_frame + j] = saturated_cast(MaxSample * config_.gain * impulse_data_[counter_]); } } if (i_frame < frame.size() && counter_ < impulse_interval_) { const size_t n_fill = std::min( (frame.size() - i_frame), (impulse_interval_ - counter_) * num_ch); assert(n_fill % num_ch == 0); assert(i_frame + n_fill <= frame.size()); std::fill_n(frame.data() + i_frame, n_fill, 0); counter_ += n_fill / num_ch; i_frame += n_fill; } else if (counter_ >= impulse_interval_) { counter_ = 0; } } while (i_frame < frame.size()); } } // namespace signal_estimator signal-estimator-0.0.9/src/base/processing/ImpulseGenerator.hpp000066400000000000000000000015711452044147100246630ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/Config.hpp" #include "processing/IGenerator.hpp" #include namespace signal_estimator { class ImpulseGenerator : public IGenerator { public: template ImpulseGenerator(const Config& config, const T& impulse) : config_(config) , impulse_data_(impulse.data()) , impulse_size_(impulse.size()) , impulse_interval_(size_t(config.impulse_interval * config.sample_rate)) { } ImpulseGenerator(const ImpulseGenerator&) = delete; ImpulseGenerator& operator=(const ImpulseGenerator&) = delete; void generate(Frame& frame) override; private: const Config config_; const float* impulse_data_; size_t impulse_size_; const size_t impulse_interval_; size_t counter_ { 0 }; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/processing/LossEstimator.cpp000066400000000000000000000034231452044147100241770ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "processing/LossEstimator.hpp" #include "reports/IReporter.hpp" #include #include namespace signal_estimator { LossEstimator::LossEstimator(const Config& config, IReporter& reporter) : config_(config) , signal_runmax_(config.signal_detection_window) , gradient_runmax_(config.glitch_detection_window) , gradient_schmitt_(config.glitch_detection_threshold) , sma_(config.report_sma_window) , reporter_(reporter) { } LossEstimator::~LossEstimator() { } void LossEstimator::add_output(FramePtr frame) { // noop (void)frame; } void LossEstimator::add_input(FramePtr frame) { if (!frame) { return; } process_frame_(*frame); report_losses_(); } void LossEstimator::process_frame_(const Frame& frame) { for (size_t n = 0; n < frame.size(); n++) { auto s = (float)frame[n]; if (signal_runmax_(std::abs(s)) >= MaxSample * config_.signal_detection_threshold) { signal_++; leading_zeros_ = false; } else { if (!leading_zeros_) { no_signal_++; } } s = gradient_(s); s = std::abs(s); s = gradient_runmax_(s); if (gradient_schmitt_(s)) { losses_++; } } } void LossEstimator::report_losses_() { const auto elapsed = limiter_.allow(); if (elapsed > 0) { LossReport rep; rep.loss_rate = (double)losses_ / elapsed; rep.loss_rate_avg = sma_(rep.loss_rate); rep.loss_ratio = double(no_signal_) / (signal_ + no_signal_) * 100.0; reporter_.report(rep); losses_ = 0; signal_ = no_signal_ = 0; } } } // namespace signal_estimator signal-estimator-0.0.9/src/base/processing/LossEstimator.hpp000066400000000000000000000025731452044147100242110ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/Config.hpp" #include "core/RateLimiter.hpp" #include "processing/IEstimator.hpp" #include "processing/MovAvg.hpp" #include "processing/MovGradient.hpp" #include "processing/MovMax.hpp" #include "processing/SchmittTrigger.hpp" #include "reports/IReporter.hpp" #include namespace signal_estimator { // estimate signal loss ratio // assumes that the output signal is a smooth sine wave produced by ContinuousGenerator // detects spikes in the output signal class LossEstimator : public IEstimator { public: LossEstimator(const Config& config, IReporter& reporter); LossEstimator(const LossEstimator&) = delete; LossEstimator& operator=(const LossEstimator&) = delete; ~LossEstimator() override; void add_output(FramePtr frame) override; void add_input(FramePtr frame) override; private: void process_frame_(const Frame& frame); void report_losses_(); const Config config_; MovMax signal_runmax_; MovGradient gradient_; MovMax gradient_runmax_; SchmittTrigger gradient_schmitt_; bool leading_zeros_ { true }; uint64_t signal_ {}; uint64_t no_signal_ {}; uint64_t losses_ {}; RateLimiter limiter_ { 2 }; MovAvg sma_; IReporter& reporter_; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/processing/MovAvg.hpp000066400000000000000000000020241452044147100225670ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include #include namespace signal_estimator { // moving average (SMA) template class MovAvg { public: explicit MovAvg(const size_t window_sz) : window_sz_(window_sz) , buff_(window_sz) , init_counter_(0) , cur_i_(0) , accum_(0) { } T operator()(const T x) { add(x); return get(); } void add(const T x) { accum_ -= buff_[cur_i_]; accum_ += x; buff_[cur_i_] = x; if (++cur_i_ >= window_sz_) { cur_i_ = 0; } if (init_counter_ < window_sz_) { init_counter_++; } } T get() const { return accum_ / T(init_counter_); } bool is_full() const { return init_counter_ == window_sz_; } private: const size_t window_sz_; std::vector buff_; size_t init_counter_; size_t cur_i_; T accum_; }; } // signal_estimator signal-estimator-0.0.9/src/base/processing/MovDev.hpp000066400000000000000000000031651452044147100225770ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "processing/MovAvg.hpp" #include #include namespace signal_estimator { // moving deviation // calculates average and maximum absolute deviations from average value // accross moving window template class MovDev { public: explicit MovDev(const size_t window_sz) : window_sz_(window_sz) , mean_(window_sz) , buff_(window_sz) , start_(0) , end_(0) { } void add(const T x) { mean_.add(x); buff_[end_ % window_sz_] = x; end_++; if (end_ - start_ > window_sz_) { start_++; } } // average deviation from arithmetic mean T avg() const { if (end_ == start_) { return 0; } const T mean = mean_.get(); T ret = 0; for (size_t i = start_; i != end_; i++) { ret += std::abs(buff_[i % window_sz_] - mean); } ret /= (end_ - start_); return ret; } // maximum deviation from arithmetic mean T max() const { if (end_ == start_) { return 0; } const T mean = mean_.get(); T ret = 0; for (size_t i = start_; i != end_; i++) { ret = std::max(ret, std::abs(buff_[i % window_sz_] - mean)); } return ret; } bool is_full() const { return end_ - start_ == window_sz_; } private: const size_t window_sz_; MovAvg mean_; std::vector buff_; size_t start_; size_t end_; }; } // signal_estimator signal-estimator-0.0.9/src/base/processing/MovGradient.hpp000066400000000000000000000013401452044147100236070ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include #include namespace signal_estimator { // calculate gradient using central difference template class MovGradient { public: MovGradient() = default; T operator()(const T x) { add(x); return get(); } void add(const T val) { if (size_ < 2) { prev_[size_++] = val; } else { grad_ = (val - prev_[0]) / 2; prev_[0] = prev_[1]; prev_[1] = val; } } T get() const { return grad_; } private: size_t size_ {}; T prev_[2] {}; T grad_ { 0 }; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/processing/MovMax.hpp000066400000000000000000000046521452044147100226100ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include #include #include namespace signal_estimator { // running maximum with amortized O(1) push // see https://stackoverflow.com/a/4802260/3169754 template class MovMax { public: explicit MovMax(size_t size) : push_stack_(size) , pop_stack_(size) , preload_(size) { if (!EnablePreload) { preload_ = 0; for (size_t i = 0; i < size; ++i) { push_stack_.push(T(0)); } } } T operator()(const T x) { add(x); return get(); } void add(const T val) { if (preload_ == 0) { pop_(); } else { preload_--; } push_stack_.push(val); } T get() const { return get_max_(); } private: struct StackItem { T val {}; T max {}; }; class Stack { public: explicit Stack(size_t size) : items_(size) , size_(0) { } void push(T val) { StackItem item; item.val = val; item.max = size_ == 0 ? val : std::max(get_max(), val); assert(size_ < items_.size()); items_[size_++] = item; } T pop() { assert(size_ > 0); return items_[--size_].val; } bool is_empty() const { return size_ == 0; } T get_max() const { assert(size_ > 0); return items_[size_ - 1].max; } private: std::vector items_; size_t size_ {}; }; void pop_() { if (pop_stack_.is_empty()) { for (;;) { const auto val = push_stack_.pop(); if (push_stack_.is_empty()) { break; } pop_stack_.push(val); } } else { pop_stack_.pop(); } } T get_max_() const { if (push_stack_.is_empty()) { return pop_stack_.get_max(); } if (pop_stack_.is_empty()) { return push_stack_.get_max(); } return std::max(push_stack_.get_max(), pop_stack_.get_max()); } Stack push_stack_; Stack pop_stack_; size_t preload_ { 0 }; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/processing/MovPercentile.hpp000066400000000000000000000050431452044147100241500ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include #include namespace signal_estimator { // moving percentile // calculates lowest value that is larger than P% of values in moving window // based on https://stackoverflow.com/questions/3738349 template class MovPercentile { public: // percentile should be in range [0; 1] MovPercentile(const size_t window_sz, const double percentile) : window_sz_(window_sz) , percentile_(percentile) , buff_(window_sz) , start_(0) , end_(0) { } T operator()(const T x) { add(x); return get(); } void add(const T x) { buff_[end_ % window_sz_] = x; end_++; if (end_ - start_ > window_sz_) { start_++; } clear_(); // N * log(N) for (size_t i = start_; i != end_; i++) { push_(buff_[i % window_sz_]); } } T get() const { return lower_.front(); } bool is_full() const { return end_ - start_ == window_sz_; } private: void push_(T x) { if (lower_.empty() || x <= lower_.front()) { lower_.push_back(x); std::push_heap(lower_.begin(), lower_.end(), std::less()); } else { upper_.push_back(x); std::push_heap(upper_.begin(), upper_.end(), std::greater()); } const size_t size_lower = size_t((lower_.size() + upper_.size()) * percentile_ + 1); if (lower_.size() > size_lower) { // lower to upper if (!lower_.empty()) { std::pop_heap(lower_.begin(), lower_.end(), std::less()); upper_.push_back(lower_.back()); std::push_heap(upper_.begin(), upper_.end(), std::greater()); lower_.pop_back(); } } else if (lower_.size() < size_lower) { // upper to lower if (!upper_.empty()) { std::pop_heap(upper_.begin(), upper_.end(), std::greater()); lower_.push_back(upper_.back()); std::push_heap(lower_.begin(), lower_.end(), std::less()); upper_.pop_back(); } } } void clear_() { lower_.clear(); upper_.clear(); } const size_t window_sz_; const double percentile_; std::vector buff_; size_t start_; size_t end_; std::vector lower_; std::vector upper_; }; } // signal_estimator signal-estimator-0.0.9/src/base/processing/SchmittTrigger.hpp000066400000000000000000000020041452044147100243250ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/Sample.hpp" namespace signal_estimator { // software schmitt trigger (a comparator with hysteresis) template class SchmittTrigger { public: SchmittTrigger(T threshold) : lower_threshold_(T(MaxSample) * threshold / 2) , upper_threshold_(T(MaxSample) * threshold) { } bool operator()(const T val) { const bool old_state = get(); add(val); const bool new_state = get(); return !old_state && new_state; } void add(const T val) { if (state_) { if (val < lower_threshold_) { state_ = false; } } else { if (val > upper_threshold_) { state_ = true; } } } bool get() const { return state_; } private: const T lower_threshold_; const T upper_threshold_; bool state_ { false }; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/processing/StepsGenerator.cpp000066400000000000000000000033551452044147100243400ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "processing/StepsGenerator.hpp" #include #include namespace signal_estimator { StepsGenerator::StepsGenerator(const Config& config) : config_(config) , step_period_(size_t(config.sample_rate * config.step_interval)) , step_length_(size_t(config.sample_rate * config.step_length)) , warmup_countdown_(config.output_info.period_count) { } void StepsGenerator::generate(Frame& frame) { std::fill_n(frame.data(), frame.size(), 0); if (warmup_countdown_ != 0) { warmup_countdown_--; return; } size_t frame_size = frame.size(); size_t frame_pos = 0; while (frame_size != 0) { if (step_countdown_ != 0) { const size_t n_samples = frame_size / config_.channel_count; if (step_countdown_ >= n_samples) { step_countdown_ -= n_samples; return; } if (step_countdown_ < n_samples) { frame_pos += step_countdown_ * config_.channel_count; frame_size -= step_countdown_ * config_.channel_count; step_countdown_ = 0; } } while (frame_size != 0) { if (++step_pos_ == step_length_) { step_pos_ = 0; step_countdown_ = step_period_; break; } for (size_t cn = 0; cn < config_.channel_count; cn++) { frame[frame_pos] = saturated_cast(MaxSample * config_.gain * std::sin(2 * (float)M_PI / config_.sample_rate * 880 * step_pos_)); frame_pos++; frame_size--; } } } } } // namespace signal_estimator signal-estimator-0.0.9/src/base/processing/StepsGenerator.hpp000066400000000000000000000012571452044147100243440ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/Config.hpp" #include "processing/IGenerator.hpp" namespace signal_estimator { // generate periodic steps (beeps) class StepsGenerator : public IGenerator { public: StepsGenerator(const Config& config); StepsGenerator(const StepsGenerator&) = delete; StepsGenerator& operator=(const StepsGenerator&) = delete; void generate(Frame& frame) override; private: const Config config_; const size_t step_period_; const size_t step_length_; size_t warmup_countdown_ {}; size_t step_countdown_ {}; size_t step_pos_ {}; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/processing/StepsLatencyEstimator.cpp000066400000000000000000000057441452044147100257050ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "processing/StepsLatencyEstimator.hpp" #include "core/Time.hpp" #include "reports/IReporter.hpp" namespace signal_estimator { StepsLatencyEstimator::StepTrigger::StepTrigger(const Config& config) : config_(config) , runmax_(config.step_detection_window) , schmitt_(config.step_detection_threshold) { } void StepsLatencyEstimator::StepTrigger::add_frame(const Frame& frame) { for (size_t n = 0; n < frame.size(); n++) { auto s = (float)frame[n]; s = std::abs(s); s = runmax_(s); if (schmitt_(s)) { last_trigger_ts_.sw_hw = (double)frame.sw_sample_time(n) / Millisecond; last_trigger_ts_.hw = (double)frame.hw_sample_time(n) / Millisecond; } } } StepsLatencyEstimator::StepsLatencyEstimator(const Config& config, IReporter& reporter) : config_(config) , thread_(&StepsLatencyEstimator::run_, this) , output_trigger_(config_) , input_trigger_(config_) , sma_(config.report_sma_window) , reporter_(reporter) { } StepsLatencyEstimator::~StepsLatencyEstimator() { queue_in_.push(nullptr); if (thread_.joinable()) { thread_.join(); } } void StepsLatencyEstimator::add_output(FramePtr frame) { queue_out_.push(std::move(frame)); } void StepsLatencyEstimator::add_input(FramePtr frame) { queue_in_.push(std::move(frame)); } void StepsLatencyEstimator::run_() { while (true) { while (auto out_frame = queue_out_.try_pop()) { output_trigger_.add_frame(*out_frame); LatencyReport rep; if (check_output_(rep)) { reporter_.report(rep); } } do { auto in_frame = queue_in_.wait_pop(); if (!in_frame) { return; } input_trigger_.add_frame(*in_frame); LatencyReport rep; if (check_input_(rep)) { reporter_.report(rep); } } while (!queue_in_.empty()); } } bool StepsLatencyEstimator::check_output_(LatencyReport& report) { if (!output_ts_.is_equal(output_trigger_.last_trigger_ts())) { output_ts_ = output_trigger_.last_trigger_ts(); return check_step_(report); } return false; } bool StepsLatencyEstimator::check_input_(LatencyReport& report) { if (!input_ts_.is_equal(input_trigger_.last_trigger_ts())) { input_ts_ = input_trigger_.last_trigger_ts(); return check_step_(report); } return false; } bool StepsLatencyEstimator::check_step_(LatencyReport& report) { if (output_ts_.is_zero() || input_ts_.is_zero()) { return false; } if (std::abs(input_ts_.hw - output_ts_.hw) > (double)config_.step_interval * 1000) { return false; } report.sw_hw = (input_ts_.sw_hw - output_ts_.sw_hw); report.hw = (input_ts_.hw - output_ts_.hw); report.hw_avg = sma_(report.hw); return true; } } // namespace signal_estimator signal-estimator-0.0.9/src/base/processing/StepsLatencyEstimator.hpp000066400000000000000000000041331452044147100257010ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/Config.hpp" #include "core/FrameQueue.hpp" #include "processing/IEstimator.hpp" #include "processing/MovAvg.hpp" #include "processing/MovMax.hpp" #include "processing/SchmittTrigger.hpp" #include "reports/IReporter.hpp" #include #include namespace signal_estimator { // estimate signal latency // assumes that the output signal was produced by StepsGenerator // detects strikes in output and input signals and calculates the latency between them class StepsLatencyEstimator : public IEstimator { public: StepsLatencyEstimator(const Config& config, IReporter& reporter); ~StepsLatencyEstimator() override; StepsLatencyEstimator(const StepsLatencyEstimator&) = delete; StepsLatencyEstimator& operator=(const StepsLatencyEstimator&) = delete; void add_output(FramePtr frame) override; void add_input(FramePtr frame) override; private: struct Timestamp { double sw_hw {}; double hw {}; bool is_zero() const { return sw_hw == 0 && hw == 0; } bool is_equal(const Timestamp& other) const { return sw_hw == other.sw_hw && hw == other.hw; } }; class StepTrigger { public: StepTrigger(const Config& config); Timestamp last_trigger_ts() const { return last_trigger_ts_; } void add_frame(const Frame& frame); private: const Config& config_; MovMax runmax_; SchmittTrigger schmitt_; Timestamp last_trigger_ts_ {}; }; void run_(); bool check_output_(LatencyReport&); bool check_input_(LatencyReport&); bool check_step_(LatencyReport&); void print_report_(const LatencyReport&); const Config config_; FrameQueue queue_in_; FrameQueue queue_out_; std::thread thread_; StepTrigger output_trigger_; StepTrigger input_trigger_; Timestamp output_ts_ {}; Timestamp input_ts_ {}; MovAvg sma_; IReporter& reporter_; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/reports/000077500000000000000000000000001452044147100202035ustar00rootroot00000000000000signal-estimator-0.0.9/src/base/reports/IReporter.hpp000066400000000000000000000015741452044147100226360ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include #include namespace signal_estimator { struct LatencyReport { double sw_hw { 0 }; double hw { 0 }; double hw_avg { 0 }; }; struct LossReport { double loss_rate { 0 }; double loss_rate_avg { 0 }; double loss_ratio { 0 }; }; struct IOJitterReport { double swdev_avg { 0 }; double swdev_per { 0 }; double hwdev_avg { 0 }; double hwdev_per { 0 }; }; struct IODelayReport { double sw_avg { 0 }; double hw_avg { 0 }; }; class IReporter { public: virtual ~IReporter() = default; virtual void report(const LatencyReport& rep) = 0; virtual void report(const LossReport& rep) = 0; virtual void report(const IOJitterReport& rep) = 0; virtual void report(const IODelayReport& rep) = 0; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/reports/JsonPrinter.cpp000066400000000000000000000012341452044147100231640ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "reports/JsonPrinter.hpp" #include #include namespace signal_estimator { JsonPrinter::JsonPrinter() { first_output_ = true; } JsonPrinter::~JsonPrinter() { if (!first_output_) { printf("\n]\n"); } } void JsonPrinter::write_line(const char* fmt, ...) { std::lock_guard lock(mutex_); if (first_output_) { first_output_ = false; printf("[\n"); } else { printf(",\n"); } va_list args; va_start(args, fmt); vprintf(fmt, args); va_end(args); fflush(stdout); } } // namespace signal_estimator signal-estimator-0.0.9/src/base/reports/JsonPrinter.hpp000066400000000000000000000007311452044147100231720ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include namespace signal_estimator { class JsonPrinter { public: JsonPrinter(); ~JsonPrinter(); JsonPrinter(const JsonPrinter&) = delete; JsonPrinter& operator=(const JsonPrinter&) = delete; __attribute__((format(printf, 2, 3))) void write_line(const char* fmt, ...); private: std::mutex mutex_; bool first_output_; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/reports/JsonReporter.cpp000066400000000000000000000033331452044147100233450ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "reports/JsonReporter.hpp" #include "core/Time.hpp" #include namespace signal_estimator { JsonReporter::JsonReporter(const Config&, const DevInfo& dev_info, JsonPrinter& printer) : printer_(printer) , dev_name_(dev_info.short_name) { } void JsonReporter::report(const LatencyReport& rep) { printer_.write_line("{\"type\": \"latency\", \"device\": \"%s\", \"timestamp\": %llu," " \"sw_hw\": %f, \"hw\": %f, \"hw_avg\": %f}", dev_name_.c_str(), (unsigned long long)wallclock_timestamp_ns(), rep.sw_hw, rep.hw, rep.hw_avg); } void JsonReporter::report(const LossReport& rep) { printer_.write_line("{\"type\": \"losses\", \"device\": \"%s\", \"timestamp\": %llu," " \"rate\": %f, \"rate_avg\": %f, \"ratio\": %f}", dev_name_.c_str(), (unsigned long long)wallclock_timestamp_ns(), rep.loss_rate, rep.loss_rate_avg, rep.loss_ratio); } void JsonReporter::report(const IOJitterReport& rep) { printer_.write_line( "{\"type\": \"io_jitter\", \"device\": \"%s\", \"timestamp\": %llu," " \"swdev_avg\": %f, \"swdev_per\": %f," " \"hwdev_avg\": %f, \"hwdev_per\": %f}", dev_name_.c_str(), (unsigned long long)wallclock_timestamp_ns(), rep.swdev_avg, rep.swdev_per, rep.hwdev_avg, rep.hwdev_per); } void JsonReporter::report(const IODelayReport& rep) { printer_.write_line( "{\"type\": \"io_delay\", \"device\": \"%s\", \"timestamp\": %llu," " \"sw_avg\": %f, \"hw_avg\": %f}", dev_name_.c_str(), (unsigned long long)wallclock_timestamp_ns(), rep.sw_avg, rep.hw_avg); } } // namespace signal_estimator signal-estimator-0.0.9/src/base/reports/JsonReporter.hpp000066400000000000000000000014141452044147100233500ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/Config.hpp" #include "reports/IReporter.hpp" #include "reports/JsonPrinter.hpp" #include namespace signal_estimator { class JsonReporter : public IReporter { public: JsonReporter(const Config& config, const DevInfo& dev_info, JsonPrinter& printer); JsonReporter(const JsonReporter&) = delete; JsonReporter& operator=(const JsonReporter&) = delete; void report(const LatencyReport& rep) override; void report(const LossReport& rep) override; void report(const IOJitterReport& rep) override; void report(const IODelayReport& rep) override; private: JsonPrinter& printer_; const std::string dev_name_; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/reports/TextReporter.cpp000066400000000000000000000037041452044147100233620ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "reports/TextReporter.hpp" #include namespace signal_estimator { TextReporter::TextReporter(const Config& config, const DevInfo& dev_info) : config_(config) , sign_(config.diff_inputs) { if (config.show_device_names && !dev_info.short_name.empty()) { suffix_ = "[" + dev_info.short_name + "]"; } } void TextReporter::report(const LatencyReport& rep) { if (sign_) { printf("latency%s:" " sw+hw %+7.3fms hw %+7.3fms hw_avg%d %+7.3fms\n", suffix_.c_str(), rep.sw_hw, rep.hw, (int)config_.report_sma_window, rep.hw_avg); } else { printf("latency%s:" " sw+hw %7.3fms hw %7.3fms hw_avg%d %7.3fms\n", suffix_.c_str(), rep.sw_hw, rep.hw, (int)config_.report_sma_window, rep.hw_avg); } } void TextReporter::report(const LossReport& rep) { if (sign_) { printf("losses%s:" " rate %+5.1f/sec rate_avg%d %+5.1f/sec ratio %+6.2f%%\n", suffix_.c_str(), rep.loss_rate, (int)config_.report_sma_window, rep.loss_rate_avg, rep.loss_ratio); } else { printf("losses%s:" " rate %5.1f/sec rate_avg%d %5.1f/sec ratio %6.2f%%\n", suffix_.c_str(), rep.loss_rate, (int)config_.report_sma_window, rep.loss_rate_avg, rep.loss_ratio); } } void TextReporter::report(const IOJitterReport& rep) { printf("io_jitter%s:" " sw_avg %7.3fms sw_p%d %7.3fms hw_avg %7.3fms hw_p%d %7.3fms\n", suffix_.c_str(), rep.swdev_avg, (int)config_.io_jitter_percentile, rep.swdev_per, rep.hwdev_avg, (int)config_.io_jitter_percentile, rep.hwdev_per); } void TextReporter::report(const IODelayReport& rep) { printf("io_delay%s:" " sw_avg %7.3fms hw_avg %7.3fms\n", suffix_.c_str(), rep.sw_avg, rep.hw_avg); } } // namespace signal_estimator signal-estimator-0.0.9/src/base/reports/TextReporter.hpp000066400000000000000000000013271452044147100233660ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/Config.hpp" #include "reports/IReporter.hpp" #include namespace signal_estimator { class TextReporter : public IReporter { public: TextReporter(const Config& config, const DevInfo& dev_info); TextReporter(const TextReporter&) = delete; TextReporter& operator=(const TextReporter&) = delete; void report(const LatencyReport& rep) override; void report(const LossReport& rep) override; void report(const IOJitterReport& rep) override; void report(const IODelayReport& rep) override; private: Config config_; bool sign_ {}; std::string suffix_; }; } // namespace signal_estimator signal-estimator-0.0.9/src/base/run/000077500000000000000000000000001452044147100173115ustar00rootroot00000000000000signal-estimator-0.0.9/src/base/run/Runner.cpp000066400000000000000000000200671452044147100212730ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "run/Runner.hpp" #include "core/Log.hpp" #include "core/Realtime.hpp" #include "dumps/AsyncDumper.hpp" #include "dumps/CsvDumper.hpp" #include "io/AlsaReader.hpp" #include "io/AlsaWriter.hpp" #include "processing/ContinuousGenerator.hpp" #include "processing/CorrelationLatencyEstimator.hpp" #include "processing/IODelayEstimator.hpp" #include "processing/IOJitterEstimator.hpp" #include "processing/Impulse.hpp" #include "processing/ImpulseGenerator.hpp" #include "processing/LossEstimator.hpp" #include "processing/StepsGenerator.hpp" #include "processing/StepsLatencyEstimator.hpp" #include "reports/JsonReporter.hpp" #include "reports/TextReporter.hpp" #include namespace signal_estimator { Runner::Runner(const Config& config) : config_(config) { } Runner::~Runner() { stop(); wait(); } bool Runner::failed() const { return fail_; } bool Runner::start() { if (!config_.output_dev.empty()) { auto alsa_writer = std::make_unique(); if (!alsa_writer->open(config_, config_.output_dev)) { fail_ = true; return false; } config_.output_info = alsa_writer->info(); output_writer_ = std::move(alsa_writer); } for (const auto& input_dev : config_.input_devs) { auto alsa_reader = std::make_unique(); if (!alsa_reader->open(config_, input_dev)) { fail_ = true; return false; } config_.input_info.emplace_back(alsa_reader->info()); input_readers_.emplace_back(std::move(alsa_reader)); } config_.frame_size = config_.output_info.period_size; for (const auto& input_info : config_.input_info) { config_.frame_size = std::max(config_.frame_size, (size_t)input_info.period_size); } config_.show_device_names = config_.diff_inputs ? input_readers_.size() > 2 : input_readers_.size() > 1; if (!config_.dump_file.empty()) { auto csv_dumper = std::make_shared(config_); if (!csv_dumper->open(config_.dump_file)) { fail_ = true; return false; } dumper_ = std::move(csv_dumper); } if (dumper_) { dumper_ = std::make_shared(std::move(dumper_)); } se_log_info("starting measurement"); frame_pool_ = std::make_unique(config_); size_t num_estimators = 0; if (input_readers_.size() != 0) { if (config_.diff_inputs) { // measurement for each input device except first num_estimators = input_readers_.size() - 1; } else { // measurement for each input device num_estimators = input_readers_.size(); } } else if (output_writer_) { // measurements for one output device num_estimators = 1; } if (config_.report_format == Format::Json) { json_printer_ = std::make_unique(); } for (size_t n = 0; n < num_estimators; n++) { DevInfo dev_info; if (input_readers_.size() != 0) { if (config_.diff_inputs) { // measurement for each input device except first dev_info = config_.input_info[n + 1]; } else { // measurement for each input device dev_info = config_.input_info[n]; } } else { dev_info = config_.output_info; } switch (config_.report_format) { case Format::Text: reporters_.emplace_back(std::make_unique(config_, dev_info)); break; case Format::Json: reporters_.emplace_back( std::make_unique(config_, dev_info, *json_printer_)); break; } switch (config_.mode) { case Mode::LatencyCorr: estimators_.emplace_back( std::make_unique(config_, *reporters_[n])); break; case Mode::LatencyStep: estimators_.emplace_back( std::make_unique(config_, *reporters_[n])); break; case Mode::Losses: estimators_.emplace_back( std::make_unique(config_, *reporters_[n])); break; case Mode::IOJitter: estimators_.emplace_back( std::make_unique(config_, dev_info, *reporters_[n])); break; case Mode::IODelay: estimators_.emplace_back( std::make_unique(config_, dev_info, *reporters_[n])); break; } } if (output_writer_) { switch (config_.mode) { case Mode::LatencyCorr: generator_ = std::make_unique(config_, impulse); break; case Mode::LatencyStep: generator_ = std::make_unique(config_); break; case Mode::Losses: generator_ = std::make_unique(config_); break; case Mode::IOJitter: generator_ = std::make_unique(config_); break; case Mode::IODelay: generator_ = std::make_unique(config_); break; } } if (output_writer_) { output_thread_ = std::thread(&Runner::output_loop_, this); } for (size_t n = 0; n < input_readers_.size(); n++) { input_threads_.emplace_back(std::thread(&Runner::input_loop_, this, n)); } return true; } void Runner::stop() { stop_ = true; } void Runner::wait() { if (output_thread_.joinable()) { output_thread_.join(); } for (auto& input_thread : input_threads_) { if (input_thread.joinable()) { input_thread.join(); } } } void Runner::output_loop_() { if (!config_.no_realtime) { make_realtime(); } uint64_t current_samples = 0, total_samples = config_.total_samples(), warmup_samples = config_.warmup_samples(); while (current_samples < total_samples || total_samples == 0) { if (stop_ || fail_) { break; } auto frame = frame_pool_->allocate(Dir::Output, 0); if (generator_) { generator_->generate(*frame); } if (!output_writer_->write(*frame)) { se_log_error("got error from output device, exiting"); fail_ = true; break; } current_samples += frame->size(); if (current_samples < warmup_samples) { continue; } if (!config_.diff_inputs) { for (auto& estimator : estimators_) { estimator->add_output(frame); } } if (dumper_) { dumper_->write(frame); } } } void Runner::input_loop_(size_t dev_index) { if (!config_.no_realtime) { make_realtime(); } uint64_t current_samples = 0, total_samples = config_.total_samples(), warmup_samples = config_.warmup_samples(); while (current_samples < total_samples || total_samples == 0) { if (stop_ || fail_) { break; } auto frame = frame_pool_->allocate(Dir::Input, dev_index); if (!input_readers_[dev_index]->read(*frame)) { se_log_error("got error from input device, exiting"); fail_ = true; break; } current_samples += frame->size(); if (current_samples < warmup_samples) { continue; } if (!config_.diff_inputs) { estimators_[dev_index]->add_input(frame); } else { if (dev_index == 0) { for (auto& estimator : estimators_) { estimator->add_output(frame); } } else { estimators_[dev_index - 1]->add_input(frame); } } if (dumper_) { dumper_->write(frame); } } } } // namespace signal_estimator signal-estimator-0.0.9/src/base/run/Runner.hpp000066400000000000000000000025761452044147100213050ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "core/Config.hpp" #include "core/FramePool.hpp" #include "dumps/IDumper.hpp" #include "io/IDeviceReader.hpp" #include "io/IDeviceWriter.hpp" #include "processing/IEstimator.hpp" #include "processing/IGenerator.hpp" #include "reports/IReporter.hpp" #include "reports/JsonReporter.hpp" #include #include #include #include namespace signal_estimator { class Runner { public: Runner(const Config& config); ~Runner(); Runner(const Runner&) = delete; Runner& operator=(const Runner&) = delete; bool failed() const; bool start(); void stop(); void wait(); private: void output_loop_(); void input_loop_(size_t dev_index); Config config_; std::unique_ptr output_writer_; std::vector> input_readers_; std::unique_ptr frame_pool_; std::unique_ptr json_printer_; std::vector> reporters_; std::unique_ptr generator_; std::vector> estimators_; std::shared_ptr dumper_; std::thread output_thread_; std::vector input_threads_; std::atomic_bool stop_ { false }; std::atomic_bool fail_ { false }; }; } // namespace signal_estimator signal-estimator-0.0.9/src/cli/000077500000000000000000000000001452044147100163425ustar00rootroot00000000000000signal-estimator-0.0.9/src/cli/Format.cpp000066400000000000000000000012271452044147100203000ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "Format.hpp" namespace signal_estimator { Formatter::Formatter() { label("REQUIRED", "[required]"); } std::string Formatter::make_expanded(const CLI::App* sub) const { std::stringstream out; out << "\n" << sub->get_group() << ":\n"; for (const CLI::Option* opt : sub->get_options()) { if (opt == sub->get_help_ptr() || opt == sub->get_help_all_ptr()) { continue; } if (opt->get_group().empty()) { continue; } out << make_option(opt, false); } return out.str(); } } // namespace signal_estimator signal-estimator-0.0.9/src/cli/Format.hpp000066400000000000000000000005131452044147100203020ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include namespace signal_estimator { // custom --help formatter class Formatter : public CLI::Formatter { public: Formatter(); std::string make_expanded(const CLI::App* sub) const override; }; } // namespace signal_estimator signal-estimator-0.0.9/src/cli/Main.cpp000066400000000000000000000254461452044147100177450ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "Format.hpp" #include "Print.hpp" #include "core/Log.hpp" #include "run/Runner.hpp" #include #include #include #include using namespace signal_estimator; int main(int argc, char** argv) { Config config; std::string mode = "latency_corr"; std::string report_format = "text"; std::string input_format = PcmFormat().to_string(), output_format = PcmFormat().to_string(); int verbosity = 0; bool list_supported = false; CLI::App app { "Measure characteristics of a looped back signal", "signal-estimator" }; app.formatter(std::make_shared()); app.add_flag( "-L,--list-supported", list_supported, "Print supported features and exit"); app.add_flag("-v,--verbose", verbosity, "Increase verbosity level (can be used multiple times)"); auto control_opts = app.add_option_group("Control options"); control_opts ->add_option("-m,--mode", mode, "Operation mode: latency_corr|latency_step|losses|io_jitter|io_delay") ->default_str(mode); control_opts->add_option("-o,--output", config.output_dev, "Output device name"); control_opts->add_option("-i,--input", config.input_devs, "Input device name(s)") ->expected(0, -1); control_opts ->add_flag( "--diff", config.diff_inputs, "Measure difference between input devices") ->group(""); control_opts ->add_option("-d,--duration", config.measurement_duration, "Limit measurement duration, seconds (zero for no limit)") ->default_val(config.measurement_duration); control_opts ->add_option("-w,--warmup", config.warmup_duration, "Warmup duration, seconds (zero for no warmup)") ->default_val(config.warmup_duration); auto io_opts = app.add_option_group("I/O options"); io_opts->add_option("-r,--rate", config.sample_rate, "Sample rate, Hz") ->default_val(config.sample_rate); io_opts->add_option("-c,--chans", config.channel_count, "Number of channels") ->default_val(config.channel_count); io_opts->add_option("-g,--gain", config.gain, "Output signal gain, from 0 to 1") ->default_val(config.gain); io_opts ->add_option("--in-latency", config.requested_input_latency_us, "Input ring buffer size, microseconds") ->default_val(config.requested_input_latency_us); io_opts ->add_option("--in-periods", config.requested_input_period_count, "Number of periods in input ring buffer") ->default_val(config.requested_input_period_count); io_opts ->add_option("--in-format", input_format, "Input device sample format (see --list-supported)") ->default_val(input_format); io_opts ->add_option("--out-latency", config.requested_output_latency_us, "Output ring buffer size, microseconds") ->default_val(config.requested_output_latency_us); io_opts ->add_option("--out-periods", config.requested_output_period_count, "Number of periods in output ring buffer") ->default_val(config.requested_output_period_count); io_opts ->add_option("--out-format", output_format, "Output device sample format (see --list-supported)") ->default_val(output_format); io_opts->add_flag("--no-rt", config.no_realtime, "Don't try using SCHED_RR policy"); auto report_opts = app.add_option_group("Report options"); report_opts ->add_option("-f,--report-format", report_format, "Report format: text|json") ->default_str(report_format); report_opts ->add_option("--report-sma", config.report_sma_window, "Simple Moving Average window for latency reports") ->default_val(config.report_sma_window); auto dump_opts = app.add_option_group("Dump options"); dump_opts->add_option( "-D,--dump-file", config.dump_file, "File to dump samples (\"-\" for stdout)"); dump_opts ->add_option("--dump-compression", config.dump_compression, "Compress dumped samples by given ratio using SMA") ->default_val(config.dump_compression); auto corr_opts = app.add_option_group("Correlation-based latency estimation options"); corr_opts ->add_option( "--impulse-interval", config.impulse_interval, "Impulse interval, seconds") ->default_val(config.impulse_interval); corr_opts ->add_option("--impulse-peak-noise-ratio", config.impulse_avg_2_peak_ration_threshold, "The peak-to-noise minimum ratio threshold") ->default_val(config.impulse_avg_2_peak_ration_threshold); corr_opts ->add_option("--impulse-peak-window", config.impulse_peak_detection_width, "Peak detection window length, samples") ->default_val(config.impulse_peak_detection_width); auto step_opts = app.add_option_group("Step-based latency estimation options"); step_opts ->add_option("--step-interval", config.step_interval, "Step interval, seconds") ->default_val(config.step_interval); step_opts->add_option("--step-length", config.step_length, "Step length, seconds") ->default_val(config.step_length); step_opts ->add_option("--step-detection-window", config.step_detection_window, "Step detection running maximum window, samples") ->default_val(config.step_detection_window); step_opts ->add_option("--step-detection-threshold", config.step_detection_threshold, "Step detection threshold, from 0 to 1") ->default_val(config.step_detection_threshold); auto loss_opts = app.add_option_group("Loss ratio estimation options"); loss_opts ->add_option("--signal-detection-window", config.signal_detection_window, "Signal detection running maximum window, samples") ->default_val(config.signal_detection_window); loss_opts ->add_option("--signal-detection-threshold", config.signal_detection_threshold, "Signal detection threshold, from 0 to 1") ->default_val(config.signal_detection_threshold); loss_opts ->add_option("--glitch-detection-window", config.glitch_detection_window, "Glitch detection running maximum window, samples") ->default_val(config.glitch_detection_window); loss_opts ->add_option("--glitch-detection-threshold", config.glitch_detection_threshold, "Glitch detection threshold, from 0 to 1") ->default_val(config.glitch_detection_threshold); auto iojitter_opts = app.add_option_group("I/O jitter estimation options"); iojitter_opts ->add_option("--io-jitter-window", config.io_jitter_window, "I/O jitter detection window, number of periods") ->default_val(config.io_jitter_window); iojitter_opts ->add_option("--io-jitter-percentile", config.io_jitter_percentile, "I/O jitter percentile, from 1 to 100") ->default_val(config.io_jitter_percentile); auto iodelay_opts = app.add_option_group("I/O delay estimation options"); iodelay_opts ->add_option("--io-delay-window", config.io_delay_window, "I/O delay detection window, number of periods") ->default_val(config.io_delay_window); try { app.parse(argc, argv); } catch (const CLI::ParseError& e) { return app.exit(e); } if (list_supported) { print_supported_formats(std::cerr); return EXIT_SUCCESS; } // parse mode const std::map mode_map { { "latency_corr", Mode::LatencyCorr }, { "latency_step", Mode::LatencyStep }, { "losses", Mode::Losses }, { "io_jitter", Mode::IOJitter }, { "io_delay", Mode::IODelay }, }; if (!mode_map.count(mode)) { std::cerr << "--mode: Invalid value\n" << "Run with --help for more information.\n"; return EXIT_FAILURE; } config.mode = mode_map.at(mode); // parse report format const std::map format_map { { "text", Format::Text }, { "json", Format::Json }, }; if (!format_map.count(report_format)) { std::cerr << "--report-format: Invalid value\n" << "Run with --help for more information.\n"; return EXIT_FAILURE; } config.report_format = format_map.at(report_format); // parse io formats if (auto fmt = PcmFormat::from_string(input_format)) { config.requested_input_format = *fmt; } else { std::cerr << "--in-format: Invalid value\n" << "Run with --list-supported for more information.\n"; return EXIT_FAILURE; } if (auto fmt = PcmFormat::from_string(output_format)) { config.requested_output_format = *fmt; } else { std::cerr << "--out-format: Invalid value\n" << "Run with --list-supported for more information.\n"; return EXIT_FAILURE; } // validate devices const bool have_output = !config.output_dev.empty(); const bool have_input = !config.input_devs.empty(); if (config.mode == Mode::IOJitter || config.mode == Mode::IODelay) { if ((have_output && have_input) || (!have_output && !have_input)) { std::cerr << "--mode " << mode << " requires either one --output device OR\n" << "one or more --input devices\n" << "Run with --help for more information.\n"; return EXIT_FAILURE; } } else { if (!have_output || !have_input) { std::cerr << "--mode " << mode << " requires one --output device AND\n" << "one or more --input devices\n" << "Run with --help for more information.\n"; return EXIT_FAILURE; } } if (config.diff_inputs) { if (config.mode == Mode::IOJitter || config.mode == Mode::IODelay) { std::cerr << "--mode " << mode << " does not support --diff option\n" << "Run with --help for more information.\n"; return EXIT_FAILURE; } if (config.input_devs.size() < 2) { std::cerr << "--diff requires at least two --input devices\n" << "Run with --help for more information.\n"; return EXIT_FAILURE; } } // setup and run init_log(verbosity); const int code = [&]() { Runner runner(config); if (!runner.start()) { return EXIT_FAILURE; } runner.wait(); if (runner.failed()) { return EXIT_FAILURE; } return EXIT_SUCCESS; }(); if (code != 0) { se_log_debug("exiting with code {}", code); } return code; } signal-estimator-0.0.9/src/cli/Print.cpp000066400000000000000000000020131452044147100201360ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "Print.hpp" #include "io/PcmFormat.hpp" #include namespace signal_estimator { void print_supported_formats(std::ostream& out) { const auto formats = PcmFormat::supported_formats(); out << "Device formats:\n"; for (size_t bits = 0; bits <= 64; bits++) { for (size_t bytes = 0; bytes <= 8; bytes++) { for (bool is_int : { true, false }) { size_t n = 0; for (const auto& fmt : formats) { if (fmt.bits() == bits && fmt.bytes() == bytes && fmt.is_int() == is_int) { if (n == 0) { out << " "; } out << " " << fmt.to_string(); n++; } } if (n != 0) { out << "\n"; } } } } } } // namespace signal_estimator signal-estimator-0.0.9/src/cli/Print.hpp000066400000000000000000000003231452044147100201450ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include namespace signal_estimator { void print_supported_formats(std::ostream& out); } // namespace signal_estimator signal-estimator-0.0.9/src/gui/000077500000000000000000000000001452044147100163575ustar00rootroot00000000000000signal-estimator-0.0.9/src/gui/ListValidator.cpp000066400000000000000000000012211452044147100216400ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "ListValidator.hpp" namespace signal_estimator { ListValidator::ListValidator(const QStringList& allowed_values, QObject* parent) : QValidator(parent) , allowed_values_(allowed_values) { } QValidator::State ListValidator::validate(QString& input, int&) const { if (allowed_values_.contains(input, Qt::CaseInsensitive)) { return Acceptable; } for (const auto& value : allowed_values_) { if (value.startsWith(input, Qt::CaseInsensitive)) { return Intermediate; } } return Invalid; } } // namespace signal_estimator signal-estimator-0.0.9/src/gui/ListValidator.hpp000066400000000000000000000006761452044147100216620ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include #include namespace signal_estimator { class ListValidator : public QValidator { Q_OBJECT public: explicit ListValidator(const QStringList& allowed_values, QObject* parent = nullptr); State validate(QString& input, int&) const override; private: QStringList allowed_values_; }; } // namespace signal_estimator signal-estimator-0.0.9/src/gui/Main.cpp000066400000000000000000000012401452044147100177440ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "core/Log.hpp" #include "io/AlsaDeviceManager.hpp" #include "MainWindow.hpp" #include "NotFoundDialog.hpp" #include "SignalEstimator.hpp" #include #include #include #include using namespace signal_estimator; int main(int argc, char* argv[]) { init_log(2); QApplication a(argc, argv); if (SignalEstimator::find().isEmpty()) { NotFoundDialog w; w.exec(); return 1; } AlsaDeviceManager device_manager; MainWindow w { device_manager }; return a.exec(); } signal-estimator-0.0.9/src/gui/MainWindow.cpp000066400000000000000000000342611452044147100211450ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "MainWindow.hpp" #include "ListValidator.hpp" #include "RightClickPickerMachine.hpp" #include "ui_MainWindow.h" #include "io/PcmFormat.hpp" #include #include #include #include #include #include namespace signal_estimator { MainWindow::MainWindow(IDeviceManager& device_manager, QWidget* parent) : QMainWindow(parent) , ui(new Ui::MainWindow) , device_manager_(device_manager) , signal_estimator_(new SignalEstimator(this)) { ui->setupUi(this); connect(signal_estimator_, &SignalEstimator::error, this, &MainWindow::show_error); connect(signal_estimator_, &SignalEstimator::can_read, this, &MainWindow::read_graph_data); ui->SignalPlot->setCanvasBackground(QApplication::palette().base().color()); ui->ResultPlot1->setCanvasBackground(QApplication::palette().base().color()); ui->ResultPlot2->setCanvasBackground(QApplication::palette().base().color()); outputCurve_->setPen(QColor(0x1F77B4)); outputCurve_->attach(ui->SignalPlot); inputCurve_->setPen(QColor(0xFF7F0E)); inputCurve_->attach(ui->SignalPlot); { data1Curve_->setPen(QColor(0xBA2D0B), 2); QwtSymbol* symbol1 = new QwtSymbol(QwtSymbol::Ellipse); symbol1->setColor(data1Curve_->pen().color()); symbol1->setPen(data1Curve_->pen().color()); symbol1->setSize(5); data1Curve_->setSymbol(symbol1); data1Curve_->setLegendAttribute(QwtPlotCurve::LegendShowSymbol); data1Curve_->attach(ui->ResultPlot1); } { data2Curve_->setPen(QColor(0x14A3A1), 2); QColor color2 = data2Curve_->pen().color(); color2.setAlphaF(0.1); QwtSymbol* symbol2 = new QwtSymbol(QwtSymbol::Ellipse); symbol2->setColor(data2Curve_->pen().color()); symbol2->setPen(data2Curve_->pen().color()); symbol2->setSize(5); data2Curve_->setBrush(QBrush(color2)); data2Curve_->setSymbol(symbol2); data2Curve_->setLegendAttribute(QwtPlotCurve::LegendShowSymbol); data2Curve_->attach(ui->ResultPlot1); } { data3Curve_->setPen(QColor(0xB2A3B5), 2); QColor color3 = data3Curve_->pen().color(); color3.setAlphaF(0.1); QwtSymbol* symbol3 = new QwtSymbol(QwtSymbol::Ellipse); symbol3->setColor(data3Curve_->pen().color()); symbol3->setPen(data3Curve_->pen().color()); symbol3->setSize(5); data3Curve_->setBrush(QBrush(color3)); data3Curve_->setSymbol(symbol3); data3Curve_->setLegendAttribute(QwtPlotCurve::LegendShowSymbol); data3Curve_->attach(ui->ResultPlot2); } ui->SignalPlot->insertLegend(new QwtLegend(), QwtPlot::BottomLegend); ui->ResultPlot1->insertLegend(new QwtLegend(), QwtPlot::BottomLegend); ui->ResultPlot2->insertLegend(new QwtLegend(), QwtPlot::BottomLegend); grid1_->setMajorPen(Qt::black, 0.0, Qt::DotLine); grid1_->attach(ui->SignalPlot); grid2_->setMajorPen(Qt::black, 0.0, Qt::DotLine); grid2_->attach(ui->ResultPlot1); grid3_->setMajorPen(Qt::black, 0.0, Qt::DotLine); grid3_->attach(ui->ResultPlot2); QwtPlotPicker* zoomInPicker = new QwtPlotPicker(ui->SignalPlot->canvas()); zoomInPicker->setStateMachine(new QwtPickerDragRectMachine()); zoomInPicker->setRubberBand(QwtPicker::RectRubberBand); zoomInPicker->setRubberBandPen(QPen(QColor(Qt::red))); connect(zoomInPicker, qOverload(&QwtPlotPicker::selected), [this](const QRectF& rect) { ui->SignalPlot->setAxisScale( QwtPlot::xBottom, rect.topLeft().x(), rect.bottomRight().x()); ui->SignalPlot->setAxisScale( QwtPlot::yLeft, rect.topLeft().y(), rect.bottomLeft().y()); ui->SignalPlot->replot(); }); QwtPlotPicker* zoomOutPicker = new QwtPlotPicker(ui->SignalPlot->canvas()); zoomOutPicker->setStateMachine(new RightClickPickerMachine()); connect(zoomOutPicker, qOverload(&QwtPlotPicker::selected), [this](const QPointF&) { ui->SignalPlot->setAxisAutoScale(QwtPlot::xBottom); ui->SignalPlot->setAxisAutoScale(QwtPlot::yLeft); ui->SignalPlot->replot(); }); QwtPlotPicker* trackPicker1 = new QwtPlotPicker(ui->SignalPlot->canvas()); trackPicker1->setStateMachine(new QwtPickerTrackerMachine()); trackPicker1->setTrackerPen(QApplication::palette().text().color()); trackPicker1->setTrackerMode(QwtPlotPicker::DisplayMode::AlwaysOn); QwtPlotPicker* trackPicker2 = new QwtPlotPicker(ui->ResultPlot1->canvas()); trackPicker2->setStateMachine(new QwtPickerTrackerMachine()); trackPicker2->setTrackerPen(QApplication::palette().text().color()); trackPicker2->setTrackerMode(QwtPlotPicker::DisplayMode::AlwaysOn); QwtPlotPicker* trackPicker3 = new QwtPlotPicker(ui->ResultPlot2->canvas()); trackPicker3->setStateMachine(new QwtPickerTrackerMachine()); trackPicker3->setTrackerPen(QApplication::palette().text().color()); trackPicker3->setTrackerMode(QwtPlotPicker::DisplayMode::AlwaysOn); for (const auto& dev : device_manager_.get_input_devices()) { ui->InputDevice->addItem(QString::fromStdString(dev)); } for (const auto& dev : device_manager_.get_output_devices()) { ui->OutputDevice->addItem(QString::fromStdString(dev)); } QStringList formats; for (const auto& fmt : PcmFormat::supported_formats()) { formats.append(QString::fromStdString(fmt.to_string())); } ui->InputFormat->addItems(formats); ui->OutputFormat->addItems(formats); ui->InputFormat->setValidator(new ListValidator(formats, this)); ui->OutputFormat->setValidator(new ListValidator(formats, this)); ui->InputFormat->setCurrentText(QString::fromStdString(PcmFormat().to_string())); ui->OutputFormat->setCurrentText(QString::fromStdString(PcmFormat().to_string())); display_latency_text_(); show(); } MainWindow::~MainWindow() { if (signal_estimator_) { signal_estimator_->stop(); } if (timer_) { timer_->stop(); } delete ui; } void MainWindow::on_StartButton_released() { QStringList args = set_up_program_(); set_update_plots_(true); // must be true to update graphs // clear old data when the start button is pressed in_data_.clear_buf(); out_data_.clear_buf(); data1_.clear_buf(); data2_.clear_buf(); data3_.clear_buf(); // reset graphs ui->SignalPlot->updateAxes(); ui->SignalPlot->replot(); ui->ResultPlot1->updateAxes(); ui->ResultPlot1->replot(); ui->ResultPlot2->updateAxes(); ui->ResultPlot2->replot(); if (!timer_) { timer_ = new QTimer(this); timer_->setInterval(20); timer_->connect(timer_, &QTimer::timeout, this, &MainWindow::update_graphs); } if (signal_estimator_->start(args)) { ui->ErrorLabel->setText(""); } else { ui->ErrorLabel->setText(QString("Failed to open signal-estimator")); } set_update_plots_(true); clear_results_text_(); timer_->start(); } void MainWindow::on_StopButton_clicked() { signal_estimator_->stop(); set_update_plots_(false); } void MainWindow::update_graphs() { if (auto latencyValues = signal_estimator_->latencyUpdate()) { update_latency_(*latencyValues); } if (auto lossesValues = signal_estimator_->lossesUpdate()) { update_losses_(*lossesValues); } if (!update_plots_) { return; } // update all graphs QVector in_current = in_data_.get_current_points(); QVector out_current = out_data_.get_current_points(); QVector data1_current = data1_.get_current_points(); QVector data2_current = data2_.get_current_points(); QVector data3_current = data3_.get_current_points(); if (in_current.isEmpty() || out_current.isEmpty()) { return; } auto xMax = std::max(in_current.back().x(), out_current.back().x()); auto xMin = xMax - out_data_.size_milliseconds(); inputCurve_->setSamples(in_current); outputCurve_->setSamples(out_current); data1Curve_->setSamples(data1_current); data2Curve_->setSamples(data2_current); data3Curve_->setSamples(data3_current); ui->SignalPlot->setAxisScale(QwtPlot::xBottom, xMin, xMax); ui->SignalPlot->replot(); ui->ResultPlot1->setAxisScale(QwtPlot::xBottom, xMin, xMax); ui->ResultPlot1->replot(); ui->ResultPlot2->setAxisScale(QwtPlot::xBottom, xMin, xMax); ui->ResultPlot2->replot(); } void MainWindow::read_graph_data() { while (auto entry = signal_estimator_->read()) { auto pt = *entry; if (pt.type == PointType::Input) { in_data_.append_point({ pt.time, pt.data1 }); } else if (pt.type == PointType::Output) { out_data_.append_point({ pt.time, pt.data1 }); } else if (pt.type == PointType::Latency || pt.type == PointType::Losses) { data1_.append_point({ pt.time, pt.data1 }); data2_.append_point({ pt.time, pt.data2 }); data3_.append_point({ pt.time, pt.data3 }); } } } void MainWindow::show_error(QString error) { ui->ErrorLabel->setText(error); } QStringList MainWindow::set_up_program_() { QStringList list; QString t; // Control list.append("--mode"); list.append(ui->Mode->currentText()); t = ui->OutputDevice->currentText(); list.append("--output"); list.append( QString::fromStdString(device_manager_.format_device_name(t.toStdString()))); t = ui->InputDevice->currentText(); list.append("--input"); list.append( QString::fromStdString(device_manager_.format_device_name(t.toStdString()))); t = ui->Duration->cleanText(); list.append("--duration"); list.append(t); t = ui->Warmup->cleanText(); list.append("--warmup"); list.append(t); // I/O t = ui->SampleRate->cleanText(); list.append("--rate"); list.append(t); t = ui->ChannelCount->cleanText(); list.append("--chans"); list.append(t); t = ui->SignalGain->cleanText(); list.append("--gain"); list.append(t); t = ui->OutputBuffer->cleanText(); list.append("--out-latency"); list.append(t); t = ui->OutputPeriods->cleanText(); list.append("--out-periods"); list.append(t); t = ui->OutputFormat->currentText(); list.append("--out-format"); list.append(t); t = ui->InputBuffer->cleanText(); list.append("--in-latency"); list.append(t); t = ui->InputPeriods->cleanText(); list.append("--in-periods"); list.append(t); t = ui->InputFormat->currentText(); list.append("--in-format"); list.append(t); if (!ui->Realtime->isChecked()) { list.append("--no-rt"); } // Reports t = ui->SMA->cleanText(); list.append("--report-sma"); list.append(t); // Dumps list.append("--dump-file"); list.append("-"); t = ui->SigComp->cleanText(); list.append("--dump-compression"); list.append(t); // LatencyCorr t = ui->ImpulseInterval->cleanText(); list.append("--impulse-interval"); list.append(t); t = ui->PeakDWL->cleanText(); list.append("--impulse-peak-window"); list.append(t); t = ui->PeakToNoiseMRT->cleanText(); list.append("--impulse-peak-noise-ratio"); list.append(t); // LatencyStep t = ui->StepInterval->cleanText(); list.append("--step-interval"); list.append(t); t = ui->StepLength->cleanText(); list.append("--step-length"); list.append(t); t = ui->StepDW->cleanText(); list.append("--step-detection-window"); list.append(t); t = ui->StepDT->cleanText(); list.append("--step-detection-threshold"); list.append(t); // Losses t = ui->SigDW->cleanText(); list.append("--signal-detection-window"); list.append(t); t = ui->SigDT->cleanText(); list.append("--signal-detection-threshold"); list.append(t); t = ui->GliDW->cleanText(); list.append("--glitch-detection-window"); list.append(t); t = ui->GliDT->cleanText(); list.append("--glitch-detection-threshold"); list.append(t); // IOJitter t = ui->IOJitWindow->cleanText(); list.append("--io-jitter-window"); list.append(t); t = ui->IOJitPercentile->cleanText(); list.append("--io-jitter-percentile"); list.append(t); // IODelay t = ui->IODelayWindow->cleanText(); list.append("--io-delay-window"); list.append(t); return list; } void MainWindow::set_update_plots_(bool f) { update_plots_ = f; } void MainWindow::update_latency_(LatencyResult latency) { display_latency_text_(); ui->Result1->setText(QString::number(latency.swHw, 'f', 3) + QString("ms")); ui->Result2->setText(QString::number(latency.hw, 'f', 3) + QString("ms")); ui->Result3->setText(QString::number(latency.hwAvgN, 'f', 3) + QString("ms")); } void MainWindow::update_losses_(LossesResult latency) { display_losses_text_(); ui->Result1->setText(QString::number(latency.rate, 'f', 3) + QString("/sec")); ui->Result2->setText(QString::number(latency.avgRate, 'f', 3) + QString("/sec")); ui->Result3->setText(QString::number(latency.ratio, 'f', 3) + QString("%")); } void MainWindow::display_latency_text_() { ui->ResultLabel1->setText("Hardware + Software Latency:"); ui->ResultLabel2->setText("Hardware Latency:"); ui->ResultLabel3->setText("Average Hardware Latency:"); data1Curve_->setTitle("Average Hardware Latency"); data2Curve_->setTitle("Hardware Latency"); data3Curve_->setTitle("Hardware + Software Latency"); } void MainWindow::display_losses_text_() { ui->ResultLabel1->setText("Loss Rate:"); ui->ResultLabel2->setText("Average Loss Rate:"); ui->ResultLabel3->setText("Loss Ratio:"); data1Curve_->setTitle("Loss Rate"); data2Curve_->setTitle("Average Loss Rate"); data3Curve_->setTitle("Loss Ratio"); } void MainWindow::clear_results_text_() { ui->ResultLabel1->setText(""); ui->ResultLabel2->setText(""); ui->ResultLabel3->setText(""); ui->Result1->setText(""); ui->Result2->setText(""); ui->Result3->setText(""); } } // namespace signal_estimator signal-estimator-0.0.9/src/gui/MainWindow.hpp000066400000000000000000000041521452044147100211460ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "io/IDeviceManager.hpp" #include "NotFoundDialog.hpp" #include "PointsBuffer.hpp" #include "SignalEstimator.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Ui { class MainWindow; } namespace signal_estimator { class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(IDeviceManager& device_manager, QWidget* parent = nullptr); ~MainWindow() override; private slots: void on_StartButton_released(); void on_StopButton_clicked(); void update_graphs(); void read_graph_data(); void show_error(QString error); private: QStringList set_up_program_(); void set_update_plots_(bool f); void update_latency_(LatencyResult latency); void update_losses_(LossesResult losses); void display_latency_text_(); void display_losses_text_(); void clear_results_text_(); Ui::MainWindow* ui; bool update_plots_ = false; PointsBuffer out_data_; PointsBuffer in_data_; PointsBuffer data1_; PointsBuffer data2_; PointsBuffer data3_; QScopedPointer grid1_ { new QwtPlotGrid() }; QScopedPointer grid2_ { new QwtPlotGrid() }; QScopedPointer grid3_ { new QwtPlotGrid() }; QScopedPointer inputCurve_ { new QwtPlotCurve( "Input signal (captured)") }; QScopedPointer outputCurve_ { new QwtPlotCurve( "Output signal (emitted)") }; QScopedPointer data1Curve_ { new QwtPlotCurve("") }; QScopedPointer data2Curve_ { new QwtPlotCurve("") }; QScopedPointer data3Curve_ { new QwtPlotCurve("") }; QTimer* timer_ = nullptr; IDeviceManager& device_manager_; SignalEstimator* signal_estimator_ = nullptr; }; } // namespace signal_estimator signal-estimator-0.0.9/src/gui/MainWindow.ui000066400000000000000000001451621452044147100210030ustar00rootroot00000000000000 MainWindow 0 0 801 912 600 800 Signal Estimator 0 Signals 0 0 QFrame::NoFrame true 0 0 767 775 4 4 4 4 QComboBox::AdjustToContents true default Input Device: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter latency_corr latency_step losses Mode: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Output Device: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter QComboBox::AdjustToContents default Start Stop true QFrame::StyledPanel QFrame::Raised 2 Qt::LeftToRight Qt::AlignCenter Qt::LeftToRight Qt::AlignCenter Qt::LeftToRight Qt::AlignCenter 16777215 10 0 0 0 160 16777215 16777215 false 0 0 0 160 16777215 16777215 0 0 0 160 16777215 16777215 General Options Control options 280 15 Measurement Duration: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Limit measurement duration, seconds (zero for no limit) seconds 0 2147483647 1 20 280 15 Warmup Duration: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Warmup duration, seconds (zero for no warmup) seconds 0 2147483647 1 1 I/O options 280 15 Sample Rate: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Number of samples per second Hz 1 2147483647 48000 280 15 Channel Count: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Number of audio channels 1 2147483647 2 280 15 Signal Gain: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Output signal gain, from 0 to 1 6 0.000000000000000 1.000000000000000 0.100000000000000 0.800000000000000 280 15 Output Ring Buffer Size: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Output ring buffer size, microseconds μs 0 2147483647 1 8000 280 15 Output Ring Buffer Periods: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Number of periods in output ring buffer 0 2147483647 1 2 280 15 Input Ring Buffer Size: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Input ring buffer size, microseconds μs 0 2147483647 1 8000 280 15 Input Ring Buffer Periods: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Number of periods in input ring buffer 0 2147483647 1 2 280 14 Real-Time Scheduling: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Try to enable SCHED_RR scheduling policy for sensitive I/O threads Try enabling SCHED_RR true 280 15 Output Sample Format: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter true 280 15 Input Sample Format: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter true Report options 280 15 -1 Simple Moving Average Window: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Simple Moving Average window for latency reports values 2147483647 5 280 15 Signal Compression: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Compress input and output signals on plot by given ratio using SMA samples 2147483647 10 Qt::Vertical 20 40 Estimation Options Correlation-based latency estimation 280 15 Impulse Interval: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Impulse interval, seconds seconds 2147483647 1 280 15 Peak Detection Window Length: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Peak detection window length, samples samples 2147483647 128 280 15 Peak-to-Noise Min. Ratio Threshold: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter The peak-to-noise minimum ratio threshold 2147483647 4 Step-based latency estimation 280 15 Step Interval: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Step interval, seconds seconds 2147483647 1 280 15 Step Length: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Step length, seconds seconds 6 1.000000000000000 0.010000000000000 0.100000000000000 280 15 Step Detection Window: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Step detection running maximum window, samples samples 0 2147483647 96 280 15 Step Detection Threshold: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Step detection threshold, from 0 to 1 6 1.000000000000000 0.010000000000000 0.400000000000000 Loss ratio estimation 280 15 Signal Detection Window: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Signal detection running maximum window, samples samples 2147483647 48 280 15 Signal Detection Threshold: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Signal detection threshold, from 0 to 1 6 1.000000000000000 0.010000000000000 0.150000000000000 280 15 Glitch Detection Window: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Glitch detection running maximum window, samples samples 2147483647 32 280 15 Glitch Detection Threshold: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Glitch detection threshold, from 0 to 1 6 1.000000000000000 0.010000000000000 0.050000000000000 I/O Jitter Estimation 280 15 I/O Jitter Window: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter I/O jitter SMA window, number of periods periods 1 2147483647 250 280 15 I/O Jitter Percentile: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter I/O jitter percentile, from 1 to 100 % 100 95 I/O Delay Estimation 280 15 I/O Delay Window: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter I/O delay SMA window, number of periods periods 1 2147483647 250 Qt::Vertical 20 40 0 0 801 26 TopToolBarArea false QwtPlot QFrame
qwt_plot.h
1
signal-estimator-0.0.9/src/gui/NotFoundDialog.cpp000066400000000000000000000006651452044147100217460ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "NotFoundDialog.hpp" #include "ui_NotFoundDialog.h" namespace signal_estimator { NotFoundDialog::NotFoundDialog(QWidget* parent) : QDialog(parent) , ui(new Ui::NotFoundDialog) { ui->setupUi(this); } NotFoundDialog::~NotFoundDialog() { delete ui; } void NotFoundDialog::on_pushButton_clicked() { close(); } } // namespace signal_estimator signal-estimator-0.0.9/src/gui/NotFoundDialog.hpp000066400000000000000000000006731452044147100217520ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include namespace Ui { class NotFoundDialog; } namespace signal_estimator { class NotFoundDialog : public QDialog { Q_OBJECT public: explicit NotFoundDialog(QWidget* parent = nullptr); ~NotFoundDialog() override; private slots: void on_pushButton_clicked(); private: Ui::NotFoundDialog* ui; }; } // namespace signal_estimator signal-estimator-0.0.9/src/gui/NotFoundDialog.ui000066400000000000000000000022251452044147100215730ustar00rootroot00000000000000 NotFoundDialog 0 0 400 165 Dialog 80 110 241 41 Close 10 10 381 91 The "signal-estimator" executable was not found in current directory, binary directory, or PATH. Qt::AlignCenter true signal-estimator-0.0.9/src/gui/PointType.hpp000066400000000000000000000003301452044147100210170ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once namespace signal_estimator { enum class PointType { Input, Output, Latency, Losses, }; } // namespace signal_estimator signal-estimator-0.0.9/src/gui/PointsBuffer.cpp000066400000000000000000000014571452044147100215000ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "PointsBuffer.hpp" #include namespace signal_estimator { void PointsBuffer::append_point(QPointF pt) { ringbuf_.push_back(pt); // should not actually happen for (size_t n = ringbuf_.size() - 1; n > 0 && ringbuf_[n].x() < ringbuf_[n - 1].x(); n--) { std::swap(ringbuf_[n], ringbuf_[n - 1]); } while (ringbuf_.back().x() - ringbuf_.front().x() > ring_size_milliseconds_) { ringbuf_.pop_front(); } } QVector PointsBuffer::get_current_points() { QVector ret((int)ringbuf_.size()); std::copy_n(ringbuf_.begin(), ringbuf_.size(), ret.begin()); return ret; } void PointsBuffer::clear_buf() { ringbuf_.clear(); } } // namespace signal_estimator signal-estimator-0.0.9/src/gui/PointsBuffer.hpp000066400000000000000000000007701452044147100215020ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include #include #include namespace signal_estimator { class PointsBuffer { public: void append_point(QPointF); QVector get_current_points(); void clear_buf(); int size_milliseconds() const { return ring_size_milliseconds_; } private: const int ring_size_milliseconds_ = 15000; std::deque ringbuf_; }; } // namespace signal_estimator signal-estimator-0.0.9/src/gui/RightClickPickerMachine.cpp000066400000000000000000000023301452044147100235270ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "RightClickPickerMachine.hpp" #include #include namespace signal_estimator { RightClickPickerMachine::RightClickPickerMachine() : QwtPickerMachine(PointSelection) { } QList RightClickPickerMachine::transition( const QwtEventPattern& eventPattern, const QEvent* event) { QList cmdList; switch (event->type()) { case QEvent::MouseButtonPress: { if (eventPattern.mouseMatch( QwtEventPattern::MouseSelect2, static_cast(event))) { cmdList += Begin; cmdList += Append; cmdList += End; } break; } case QEvent::KeyPress: { const QKeyEvent* keyEvent = static_cast(event); if (eventPattern.keyMatch(QwtEventPattern::KeySelect1, keyEvent)) { if (!keyEvent->isAutoRepeat()) { cmdList += Begin; cmdList += Append; cmdList += End; } } break; } default: break; } return cmdList; } } // namespace signal_estimator signal-estimator-0.0.9/src/gui/RightClickPickerMachine.hpp000066400000000000000000000005771452044147100235470ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include namespace signal_estimator { class RightClickPickerMachine : public QwtPickerMachine { public: RightClickPickerMachine(); QList transition( const QwtEventPattern& eventPattern, const QEvent* event) override; }; } // namespace signal_estimator signal-estimator-0.0.9/src/gui/SignalEstimator.cpp000066400000000000000000000127611452044147100221770ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #include "SignalEstimator.hpp" #include "core/Sample.hpp" #include "core/Time.hpp" #include #include #include #include #include #include namespace signal_estimator { namespace { std::optional parseLatency(const QString& buffer) { LatencyResult values; QRegularExpression reg("([\\d\\.]+)ms"); QStringList list; QRegularExpressionMatchIterator i = reg.globalMatch(buffer); while (i.hasNext()) { QRegularExpressionMatch match = i.next(); list << match.captured(1); } if (list.size() != 3) { return {}; } values.swHw = list[0].toDouble(); values.hw = list[1].toDouble(); values.hwAvgN = list[2].toDouble(); return values; } std::optional parseLosses(const QString& buffer) { LossesResult values; QRegularExpression reg("([\\d\\.]+)/sec|([\\d\\.]+)%"); QStringList list; QRegularExpressionMatchIterator i = reg.globalMatch(buffer); while (i.hasNext()) { QRegularExpressionMatch match = i.next(); list << match.captured(1); } if (list.size() != 3) { return {}; } values.rate = list[0].toDouble(); values.avgRate = list[1].toDouble(); values.ratio = list[2].toDouble(); return values; } std::optional parseSignal(const QString& buffer) { QRegularExpression reg(",|\\n"); QStringList tokens = buffer.split(reg, Qt::SkipEmptyParts); if (tokens.count() < 3) { return {}; } SignalPoint pt; pt.isOutput = tokens[0] == "o"; try { pt.time = tokens[1].toDouble(); } catch (const std::invalid_argument&) { return {}; } try { pt.amplitude = tokens[2].toDouble(); } catch (const std::invalid_argument&) { return {}; } return pt; } } // namespace SignalEstimator::SignalEstimator(QObject* parent) : QObject(parent) { } SignalEstimator::~SignalEstimator() { stop(); } QString SignalEstimator::find() { if (auto path = QDir::currentPath() + "/signal-estimator"; QFileInfo(path).isExecutable()) { return path; } if (auto path = QCoreApplication::applicationDirPath() + "/signal-estimator"; QFileInfo(path).isExecutable()) { return path; } if (auto path = QStandardPaths::findExecutable("signal-estimator"); QFileInfo(path).isExecutable()) { return path; } return {}; } bool SignalEstimator::start(QStringList args) { stop(); proc_ = QSharedPointer(new QProcess); proc_->setProcessChannelMode(QProcess::MergedChannels); proc_->setProgram(find()); proc_->setArguments(args); proc_->setReadChannel(QProcess::StandardOutput); connect(proc_.data(), &QProcess::readyReadStandardOutput, this, &SignalEstimator::can_read); connect(proc_.data(), qOverload(&QProcess::errorOccurred), this, [this]() { if (proc_) { error(proc_->errorString()); } }); if (!proc_->open(QProcess::ReadOnly)) { proc_ = {}; return false; } startTime_ = wallclock_timestamp_ns(); return true; } void SignalEstimator::stop() { if (proc_ && proc_->isOpen()) { proc_->close(); } proc_ = {}; } std::optional SignalEstimator::read() { if (!proc_) { return {}; } if (!proc_->canReadLine()) { return {}; } QByteArray buffer = proc_->readLine(); return parseIO_(QString(buffer)); } void SignalEstimator::clearResults_() { latency_ = {}; losses_ = {}; } std::optional SignalEstimator::parseIO_(const QString& buffer) { if (buffer[0] == "#") { return {}; } DataPoint pt {}; if (buffer.size() > 1 && buffer[0] == "l" && buffer[1] == "a") { if (auto latencyValues = parseLatency(buffer)) { clearResults_(); latency_ = *latencyValues; pt.type = PointType::Latency; pt.time = (wallclock_timestamp_ns() - startTime_) / Millisecond; pt.data1 = latency_->hwAvgN; pt.data2 = latency_->hw; pt.data3 = latency_->swHw; return pt; } } if (buffer.size() > 1 && buffer[0] == "l" && buffer[1] == "o") { if (auto lossesValues = parseLosses(buffer)) { clearResults_(); losses_ = *lossesValues; pt.type = PointType::Losses; pt.time = (wallclock_timestamp_ns() - startTime_) / Millisecond; pt.data1 = losses_->rate; pt.data2 = losses_->avgRate; pt.data3 = losses_->ratio; return pt; } } if (buffer.size() > 1 && (buffer[0] == "i" || buffer[0] == "o")) { if (auto sigPoint = parseSignal(buffer)) { pt.type = sigPoint->isOutput ? PointType::Output : PointType::Input; pt.time = (sigPoint->time - startTime_) / Millisecond; pt.data1 = sigPoint->amplitude / MaxSample * 100; return pt; } } return {}; } std::optional SignalEstimator::latencyUpdate() { std::optional latencyTmp = latency_; latency_ = {}; return latencyTmp; } std::optional SignalEstimator::lossesUpdate() { std::optional lossesTmp = losses_; losses_ = {}; return lossesTmp; } } // namespace signal_estimator signal-estimator-0.0.9/src/gui/SignalEstimator.hpp000066400000000000000000000031331452044147100221750ustar00rootroot00000000000000// Copyright (c) Signal Estimator authors // Licensed under MIT #pragma once #include "PointType.hpp" #include "core/Time.hpp" #include #include #include #include #include #include namespace signal_estimator { struct LatencyResult { double swHw { 0 }; double hw { 0 }; double hwAvgN { 0 }; }; struct LossesResult { double rate { 0 }; double avgRate { 0 }; double ratio { 0 }; }; struct SignalPoint { bool isOutput { false }; double time { 0 }; double amplitude { 0 }; }; struct DataPoint { PointType type {}; double time {}; // Depending on PointType: double data1 {}; // Avg HW Latency | Loss Rate | Signal level double data2 {}; // HW Latency | Avg Loss Rate | Not used (garbage) double data3 {}; // HW + SW Latency | Loss Ratio | Not used (garbage) }; class SignalEstimator : public QObject { Q_OBJECT public: static QString find(); SignalEstimator(QObject* parent = nullptr); ~SignalEstimator() override; bool start(QStringList args); void stop(); std::optional read(); std::optional latencyUpdate(); std::optional lossesUpdate(); signals: void can_read(); void error(QString); private: std::optional parseIO_(const QString& buffer); void clearResults_(); QSharedPointer proc_; std::optional latency_ = {}; std::optional losses_ = {}; nanoseconds_t startTime_ {}; }; } // namespace signal_estimator