pax_global_header00006660000000000000000000000064131735760540014525gustar00rootroot0000000000000052 comment=3469c963ca82ea5eab00189fd2a7eb239cce0d39 fenrir-1.5.1/000077500000000000000000000000001317357605400130165ustar00rootroot00000000000000fenrir-1.5.1/.gitignore000066400000000000000000000001201317357605400147770ustar00rootroot00000000000000__pycache__/ *\.pyc fenrir.egg-info/ fenrir_screenreader.egg-info/ dist/ build/ fenrir-1.5.1/Changelog.txt000066400000000000000000000212761317357605400154560ustar00rootroot00000000000000# Version 1.5 - Doku: Write a user wiki https://wiki.linux-a11y.org/doku.php?id=fenrir_user_manual&s[]=fenrir - initial working setup.py - available via pip (python packet manager) sudo pip3 install fenrir-screenreader https://pypi.python.org/pypi/fenrir-screenreader/1.5.post5 - leave review on typing - add dependency check (check-dependencys.py) - Add nice dummy drivers as template or for debugging - reimplement detection code for X11 - initial translate structure (manuelcortez Thanks!) - add a configurable place where you can place own commands or overwrite existing commands without need to change default code - implement autodetection of plugged and unplugged input devices - implement speechdriver generic - try to autodetect encoding (Easy for contribution) (Prototype "charmapTTY" in play zone) Braille Support (WIP): - initial BrlTTY driver - detect device size via driver - output to braille device - make flushMode configurable - make flushTimeout configurable - flush message after X seconds and show current line (review over text) - tweak current commands and output - command flush_braille - command for scroll left - command for scroll right - create offset for scrolling - respect scrolling make cursor following configurable (brailleCursorTrackingMode) - cell - page follow cursor while typing brailleFocusMode: - review = priority to review - move to an event based system - add initial multithreading/ multiprocessing support - support cli parameters - add cli parameter for debugging "-d" - add cli parameter to overwrite options "-o" - add cli parameter to specify an settings.conf "-s" - list of bound commands in Tutorial Mode. speak name, binding and description. # Version: 1.00 - move from VCS to VCSA and parese the Attributes http://linux.die.net/man/4/vcsa http://man.cx/vcsa(4)/de http://manpages.org/display-vcsa/7 https://en.wikipedia.org/wiki/Virtual_console every second byte is a attribute others are text. fast way: c[::2],c[1::2] http://manpages.ubuntu.com/manpages/precise/de/man4/vcs.4.html https://docs.python.org/3/library/fcntl.html http://rodrigorivas.serveblog.net/en/imagenes-desde-vt-con-vcsa/ good doku: http://angband.oook.cz/d/eyangband-052/src/main-vcs.c http://manpages.ubuntu.com/manpages/trusty/man1/screader.1.html - implement speechdriver espeak https://github.com/relsi/python-espeak - detect collumns in TTYs automaticaly. it seems we have this info in vcsa - get current cursor - shortcut handling https://docs.python.org/2/library/termios.html http://stackoverflow.com/questions/287757/pythons-configparser-unique-keys-per-section 0=down, 1=press, 2=hold 2KEY_SHIFT, 1KEY_A = say_current_line_cursor - implement command structure - implement speechdriver speechd https://git.gnome.org/browse/orca/tree/src/orca/speech.py https://git.gnome.org/browse/orca/tree/src/orca/speechdispatcherfactory.py http://devel.freebsoft.org/doc/speechd/speech-dispatcher.html#Client-Programming - autodetect current TTY maybe with (PAM or a sys folder) cat /sys/devices/virtual/tty/tty0/active http://serverfault.com/questions/306854/how-to-find-out-the-currently-active-linux-virtual-terminal-while-connected-via - Input http://python-evdev.readthedocs.io/en/latest/tutorial.html http://stackoverflow.com/questions/12384772/how-can-i-capture-mouseevents-and-keyevents-using-python-in-background-on-linux maybe TTY in RAW MODE - Settings (make it configureable) - improve differ speed - lock mechanism for threads - restructure loops to listen for events inputloop -> does block with an select commands -> a new thread should spawned from inputloop updatescreen -> maybe we could watch it with inotify vsca should support polling COMMENT: sadly not possible, poll events not fired as expected https://github.com/seb-m/pyinotify/wiki/Tutorial import pyinotify import glob class Identity(pyinotify.ProcessEvent): def process_default(self, event): p = event.pathname print(p) wm = pyinotify.WatchManager() notifier = pyinotify.Notifier(wm, default_proc_fun=Identity(), timeout=5) wm.add_watch('/sys/devices/virtual/tty/tty0/active', pyinotify.IN_CLOSE_WRITE) for file in list(glob.glob('/dev/vcsa[0-64]')): wm.add_watch(file, pyinotify.IN_CLOSE_WRITE) print(file) try: while 1: notifier.process_events() if notifier.check_events( timeout=1000): notifier.read_events() print('events') else: print('timeout') except KeyboardInterrupt: notifier.stop() print('fin') https://www.infoq.com/articles/inotify-linux-file-system-event-monitoring https://github.com/seb-m/pyinotify/wiki/Tutorial http://www.saltycrane.com/blog/2010/04/monitoring-filesystem-python-and-pyinotify/ - add setting for ignore screens ( dont grab shortcuts from X or orca) - soundIcons - performance tuning - add sound volume - convert volume to percent in config - convert pitch to percent in config - convert rate to percent in config - make screenUpdate rate configurable - default soundIcon theme (soundfiles) - debugging - threading ReadContent, ReadShortcuts, executeCommands, listenNewTTYsForListen, controllThread (main) - autoload plugins while starting - implement sounddriver generic (use current sox and make it configurable) - add setting for autodetect X ps a -o tty,comm | grep -e Xorg | grep -v "grep -e Xorg" - respect window mode in differ (getwindow code is already in place) - parse punctuation setting file in conf/substitution - implement commands curr_word curr_char next_word next_char prev_word prev_char enable_disable_speech #enable, disable speech enable_disable_braile #enable, disable braile enable_disable_sound #enable, disable sound enable_disable_output #enable, disable speech, braile and sound next_clipboard prev_clipboard first_clipboard last_clipboard curr_clipboard paste_clipboard define_window remove_window reset_review_on_screen_change remove_clipboard_marks copy_marked set_mark (this could also used for area?) read_clipboard_mark_text curr_screen curr_screen_before_cursor curr_screen_after_cursor cursor_position indention add_bookmark (per application) remove_bookmark present_bookmark say_char_phonetic spell_word_phonetic "alpha", "bravo", "charlie", "delta", "echo", "foxtrot", "golf", "hotel", "india", "juliet", "kilo", "lima", "mike", "november", "oscar", "papa", "quebec", "romeo", "sierra", "tango", "uniform", "victor", "whisky", "x ray", "yankee", "zulu" next_char_phonetic prev_char_phonetic next_word_phonetic prev_word_phonetic toggle_highlighted_mode - implement onInput commands read_line_if_cursor_change_vertical (needed if you arrow up and down, we want to announce the line) read_char_if_cursur_change_horizontal (needed if you arrow left and right, we want to announce the char under the cursor) echo_char (echos the last char on pressing space or return) echo_word (echos the last word) echo_deleted_char (echos deleted char on screen read highlighted - implement onScreenChange commands promoted text clear_marks_on_screen_change leve_review_mode_on_screen_change window mode (define a area and just read that changes) - add screenManager abstract screen driver - pass environment instance in init and remove it from function calls - New Triggers onAppChange onAppProfileChange onScreenChange rename current onScreenChange to onScreenUpdate - rework inputManager try to consume shortcuts grab keyboard exclusive release keyboard on error or quit grab shortcuts with fenrir key grab "singel key shortcuts" like numpad navigation for review forwart nonshortcuts to system make grabbing configuarble possiblity to forewart shortcut [proxyshortcut] possiblity to forewart shortcut (or use them as shortcut) [pressing twice while timeout] cleanup inputManager split input driver out of the handler - dictonary for special chars and string replacements - punctuation - beep on cursor to capital letters in cursor and review - add pause handling create pause make it configurable when the pause the pause happens - external scripting load scripts from a folder as subprocess create thread load key definition of keybindings like SOPS did - add an daemonize mode https://github.com/thesharp/daemonize https://web.archive.org/web/20131017130434/http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/ - announce capslock - anounce numlock - anounce scroll - add the debugging to core - autostart systemd https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System_Administrators_Guide/sect-Managing_Services_with_systemd-Unit_Files.html fenrir-1.5.1/LICENCE000066400000000000000000000167441317357605400140170ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. fenrir-1.5.1/Maintainer000066400000000000000000000000561317357605400150310ustar00rootroot00000000000000chrys (chrys87@web.de) storm_dragon Jeremiah fenrir-1.5.1/README.md000066400000000000000000000051531317357605400143010ustar00rootroot00000000000000# Fenrir A TTY screenreader for Linux. In theory it's not just limited to Linux. but i currently only provide drivers for that since I do not have another system here. If you want to help, or write drivers to make it work on other systems, just let me know. This software is licensed under the LGPL v3 . # Requirements (core) - Linux (currently only screen and input drivers available) - python3 >= 3.3 - python-configargparse - screen, input, speech, sound or braille drivers see "Features, Drivers, Extras". # Features, Drivers, Extras, Dependencies # Input Drivers: 1. "evdevDriver" input driver for linux evdev - python-evdev >=0.6.3 - python-pyudev - This is commonly referred to as python3-evdev by your distribution - loaded uinput kernel module - ReadWrite permission - /dev/input - /dev/uinput # Screen Drivers: 1. "vcsaDriver" screen driver for linux VCSA devices - python-dbus - Read permission to the following files and services: - /sys/devices/virtual/tty/tty0/active - /dev/tty[1-64] - /dev/vcsa[1-64] - read logind DBUS # Speech Drivers: 1. "EspeakDriver" speech driver for Espeak: - python-espeak - "speechdDriver" speech driver for Speech-dispatcher: - Speech-dispatcher - python-speechd 2. "dummyDriver" speech driver for debugging # Braille Drivers: 1. "BrlttyDriver" braille driver (WIP): - brltty (configured and running) - python-brlapi 2. "dummyDriver" Braille driver for debugging # Sound Drivers: 1. "genericDriver" sound driver for sound as subprocess: - Sox 2. "gstreamerDriver" sound driver for gstreamer - gstreamer >=1.0 - GLib 3. "dummyDriver" sound driver for debugging # Extras: 1. spellchecker - python-pyenchant - aspell-YourLanguageCode (example aspell-en for us English) 2. Unix daemon (also needed for Systemd): - python-daemonize 3. Modify system volume: - pyalsaaudio (needs libasound2's headers). # installation - Archlinux: PKGBUILD in AUR - Manual: run install.sh and uninstall.sh as root - you also can just run it from Git without installing: You can just run the following as root: if you are in Fenrir Git rootfolder: cd src/fenrir/ sudo ./fenrir Settings "settings.conf" is located in the "config" directory or after installation in /etc/fenrir/settings. Take care to use drivers from the config matching your installed drivers. By default it uses: - sound driver: genericDriver (via sox, could configured in settings.conf) - speech driver: speechdDriver - braille driver: brlttyDriver (WIP) - input driver: evdevDriver # Documentation You can see all information on the Wiki: https://wiki.linux-a11y.org/doku.php?id=fenrir_user_manual&s[]=fenrir fenrir-1.5.1/TODO v2.0000066400000000000000000000070171317357605400141610ustar00rootroot00000000000000ToDo list for Fenrir Version 2.0 Things needing little knowledge are marked with "(Easy for contribution)". so just start with those :). [] = ToDo [W] = WIP [X] = Done Cleanups: - split oldValues := newValues out to helper function (Easy for contribution) [] split it out [] use it in vcsa driver [] Migrate *Data.py to classes and use getter/setter (Easy for contribution) [] commandsData.py [] eventData.py [] generalData.py [] inputData.py [] outputData.py [] punctuationData.py [] runtimeData.py [] screenData.py [] settingsData -> defaultSettings.py General: - commands [] place last spoken to clipboard - imporove attribute handling [] improve attributes_curr_char [] add an attribute sound [] beep on cursor/ review by char (capital wins) [] beep on review by word (once for multiple, capital wins) [] configurable (by char, by word, none) https://github.com/jwilk/vcsapeek/blob/master/linuxvt.py - Improved Say all [] all the text of all pages [] command to stop and place review cursor at this position [] command to slow down speech on keypress - generic list or see Tutorial mode list (convert clipboard management) (Easy for contribution) [] next item [] prev item [] curr item [] first item [] last item - make it runnable via pypy3 [] wrapper script for running Fenrir to check if pypy exists, use python3 as fallback. Braille Support: [] brailleFocusMode: [] manual = no automatic toggle command used [] last = follow last used cursor [] print cursor in review [] print cursor in textmode [] word wrapping (if word does not fit print it at next page) [] command toggle used cursor (in manual brailleFocusMode) [] capture input from braile [] make routing keys assignable by keyboard [] make brailleTable configurable [] pkg-config --variable=tablesdir liblouis returns on Arch:/usr/share/liblouis/tables http://mielke.cc/brltty/doc/Manual-BrlAPI/English/BrlAPI.html https://git.gnome.org/browse/orca/tree/src/orca/braille.py https://wiki.gnome.org/Attic/LSR/ScratchPad/Braille/BrlAPI https://github.com/google/brailleback/blob/master/third_party/brltty/Bindings/Python/brlapi.pyx Driver: [W] PTY Screen driver (to use gnome-terminal and other terminal emulators) https://docs.python.org/3.2/library/pty.html http://sqizit.bartletts.id.au/2011/02/14/pseudo-terminals-in-python/ https://blog.konpat.me/pythons-pseudo-terminal-pty-examples/ [] talkey driver [W] emacspeak driver [W] PTY Input driver [] ATK input driver (don't grab on graphical interface) https://git.linux-a11y.org/AIT/pyatspi2/src/master/examples/keypress.py [] Dectalk SpeechDriver (Easy for contribution, device needed - i dont own one) https://github.com/tvraman/emacspeak/blob/master/servers/obsolete/python/dectalk.py Settings: [] write settings (Easy for contribution) [] menue for settings configuration (Easy for contribution) Application Profiles (low priority): - reimplement process detection without subprocessing // this is started by chrys - fenrir is not able to detect the current application inside of screen. ps -e -H -o pid,pgrp,ppid,tty,cmd http://stackoverflow.com/questions/24861351/how-to-detect-if-python-script-is-being-run-as-a-background-process/24862213 fd = os.open("/dev/tty5", os.O_RDONLY ) os.tcgetpgrp(fd) - add perApplicationTrigger trigger per application commands per application onScreenChange per application onInput - per application shortcuts -----------DONE---------------- General: Braille Support: Driver: Settings: Application Profiles: fenrir-1.5.1/autostart/000077500000000000000000000000001317357605400150445ustar00rootroot00000000000000fenrir-1.5.1/autostart/runit/000077500000000000000000000000001317357605400162055ustar00rootroot00000000000000fenrir-1.5.1/autostart/runit/fenrir/000077500000000000000000000000001317357605400174725ustar00rootroot00000000000000fenrir-1.5.1/autostart/runit/fenrir/run000066400000000000000000000000261317357605400202170ustar00rootroot00000000000000#!/bin/sh exec fenrir fenrir-1.5.1/autostart/systemd/000077500000000000000000000000001317357605400165345ustar00rootroot00000000000000fenrir-1.5.1/autostart/systemd/fenrir.service000066400000000000000000000004761317357605400214120ustar00rootroot00000000000000[Unit] Description=Fenrir screenreader Wants=systemd-udev-settle.service After=systemd-udev-settle.service sound.target [Service] Type=forking PIDFile=/var/run/fenrir.pid ExecStart=/usr/bin/fenrir-daemon ExecReload=/usr/bin/kill -HUP $MAINPID Restart=always #Group=fenrir #User=fenrir [Install] WantedBy=sound.target fenrir-1.5.1/bugs000066400000000000000000000006621317357605400137050ustar00rootroot00000000000000Please report Bugs and feature requests to: https://github.com/chrys87/fenrir/issues For bugs, please provide a debug file that shows the issue. How to create a debug file: 1. first delete old stuff: sudo rm /var/log/fenrir.log 2. start fenrir in debug mode sudo fenrir -d 3. stop fenrir (fenrirKey + q) the debug file is in /var/log/fenrir.log plese be as precise as possible to make it easy to solve the problem. fenrir-1.5.1/check-dependencies.py000077500000000000000000000076061317357605400171050ustar00rootroot00000000000000#!/bin/env python3 import os, sys # default installation # core # speech: speech-dispatcher # sound: sox # braille: brltty: defaultInstallation = ['FenrirCore','vcsaDriver','brlapiDriver','evdevDriver','speechdDriver', 'genericDriver'] currentInstallation = [] print('checking dependencys...') # CORE print('') print('fenrir core:') available = True try: from daemonize import Daemonize print('python3-daemonize: OK') except: print('python3-daemonize: FAIL') available = available and False try: import enchant print('pyenchant: OK') except: print('pyenchant: FAIL') available = available and False if available: currentInstallation.append('FenrirCore') # SCREEN print('') print('screen driver') # VCSA (screen driver) print('vcsaDriver') available = True try: import dbus print('python3-dbus: OK') except: print('python3-dbus: FAIL') available = available and False if os.path.exists('/dev/vcsa'): print('VCSA Device: OK') else: print('VCSA Device: FAIL') available = available and False if available: currentInstallation.append('vcsaDriver') # BRAILLE print('') print('braille driver') # brltty (braille driver) print('brlapiDriver') available = True try: import brlapi print('python3-brlapi: OK') except: print('python3-brlapi: FAIL') available = available and False if available: currentInstallation.append('brlapiDriver') # INPUT print('') print('input driver') # evdev (input driver) print('evdevDriver') available = True try: import evdev from evdev import InputDevice, UInput print('python3-evdev: OK') except: print('python3-evdev: FAIL') available = available and False try: import pyudev print('python3-pyudev: OK') except: print('python3-pyudev: FAIL') available = available and False if available: currentInstallation.append('evdevDriver') # SOUND print('') print('sound driver') print('genericDriver (uses sox by default)') available = True if os.path.exists('/usr/bin/play') and os.path.exists('/usr/bin/sox'): print('sox: OK') else: print('sox: FAIL') available = available and False if available: currentInstallation.append('genericDriver') # gstreamer (sound driver) print('gstreamerDriver') available = True try: import gi print('gi: OK') except: print('gi: FAIL') available = available and False try: from gi.repository import GLib print('gi GLib: OK') except: print('gi GLib: FAIL') available = available and False try: gi.require_version('Gst', '1.0') from gi.repository import Gst print('gi Gst: OK') except: print('gi Gst: FAIL') available = available and False if available: currentInstallation.append('gstreamerDriver') # SPEECH print('') print('speech driver') # speechd (speech driver) print('speechdDriver') available = True try: import speechd print('python3-speechd: OK') except: print('python3-speechd: FAIL') available = available and False if available: currentInstallation.append('speechdDriver') # espeak (speech driver) print('espeakDriver') available = True try: from espeak import espeak print('python3-espeak: OK') except: print('python3-espeak: FAIL') available = available and False if available: currentInstallation.append('espeakDriver') # SUMMERY print('') available = True missing = [] for element in defaultInstallation: if not element in currentInstallation: available = False missing.append(element) if available: print('Default Setup: OK') else: print('Default Setup: FAIL') print('Unavailable Default Modules:') for e in missing: print(e) print('you may need to install the missing dependencys for the modules above or reconfigure fenrir to not use them') print('') print('Available Modules:') for element in currentInstallation: print(element) fenrir-1.5.1/config/000077500000000000000000000000001317357605400142635ustar00rootroot00000000000000fenrir-1.5.1/config/keyboard/000077500000000000000000000000001317357605400160635ustar00rootroot00000000000000fenrir-1.5.1/config/keyboard/Readme.md000066400000000000000000000153221317357605400176050ustar00rootroot00000000000000 Keymap for Fenrir KEY_RESERVED KEY_ESC KEY_1 KEY_2 KEY_3 KEY_4 KEY_5 KEY_6 KEY_7 KEY_8 KEY_9 KEY_0 KEY_MINUS KEY_EQUAL KEY_BACKSPACE KEY_TAB KEY_Q KEY_W KEY_E KEY_R KEY_T KEY_Y KEY_U KEY_I KEY_O KEY_P KEY_LEFTBRACE KEY_RIGHTBRACE KEY_ENTER KEY_LEFTCTRL KEY_A KEY_S KEY_D KEY_F KEY_G KEY_H KEY_J KEY_K KEY_L KEY_SEMICOLON KEY_APOSTROPHE KEY_GRAVE KEY_LEFTSHIFT KEY_BACKSLASH KEY_Z KEY_X KEY_C KEY_V KEY_B KEY_N KEY_M KEY_COMMA KEY_DOT KEY_SLASH KEY_RIGHTSHIFT KEY_KPASTERISK KEY_LEFTALT KEY_SPACE KEY_CAPSLOCK KEY_F1 KEY_F2 KEY_F3 KEY_F4 KEY_F5 KEY_F6 KEY_F7 KEY_F8 KEY_F9 KEY_F10 KEY_NUMLOCK KEY_SCROLLLOCK KEY_KP7 KEY_KP8 KEY_KP9 KEY_KPMINUS KEY_KP4 KEY_KP5 KEY_KP6 KEY_KPPLUS KEY_KP1 KEY_KP2 KEY_KP3 KEY_KP0 KEY_KPDOT KEY_ZENKAKUHANKAKU KEY_102ND KEY_F11 KEY_F12 KEY_RO KEY_KATAKANA KEY_HIRAGANA KEY_HENKAN KEY_KATAKANAHIRAGANA KEY_MUHENKAN KEY_KPJPCOMMA KEY_KPENTER KEY_RIGHTCTRL KEY_KPSLASH KEY_SYSRQ KEY_RIGHTALT KEY_LINEFEED KEY_HOME KEY_UP KEY_PAGEUP KEY_LEFT KEY_RIGHT KEY_END KEY_DOWN KEY_PAGEDOWN KEY_INSERT KEY_DELETE KEY_MACRO ['KEY_MIN_INTERESTING', 'KEY_MUTE'] KEY_VOLUMEDOWN KEY_VOLUMEUP KEY_POWER KEY_KPEQUAL KEY_KPPLUSMINUS KEY_PAUSE KEY_SCALE KEY_KPCOMMA ['KEY_HANGEUL', 'KEY_HANGUEL'] KEY_HANJA KEY_YEN KEY_LEFTMETA KEY_RIGHTMETA KEY_COMPOSE KEY_STOP KEY_AGAIN KEY_PROPS KEY_UNDO KEY_FRONT KEY_COPY KEY_OPEN KEY_PASTE KEY_FIND KEY_CUT KEY_HELP KEY_MENU KEY_CALC KEY_SETUP KEY_SLEEP KEY_WAKEUP KEY_FILE KEY_SENDFILE KEY_DELETEFILE KEY_XFER KEY_PROG1 KEY_PROG2 KEY_WWW KEY_MSDOS ['KEY_COFFEE', 'KEY_SCREENLOCK'] ['KEY_DIRECTION', 'KEY_ROTATE_DISPLAY'] KEY_CYCLEWINDOWS KEY_MAIL KEY_BOOKMARKS KEY_COMPUTER KEY_BACK KEY_FORWARD KEY_CLOSECD KEY_EJECTCD KEY_EJECTCLOSECD KEY_NEXTSONG KEY_PLAYPAUSE KEY_PREVIOUSSONG KEY_STOPCD KEY_RECORD KEY_REWIND KEY_PHONE KEY_ISO KEY_CONFIG KEY_HOMEPAGE KEY_REFRESH KEY_EXIT KEY_MOVE KEY_EDIT KEY_SCROLLUP KEY_SCROLLDOWN KEY_KPLEFTPAREN KEY_KPRIGHTPAREN KEY_NEW KEY_REDO KEY_F13 KEY_F14 KEY_F15 KEY_F16 KEY_F17 KEY_F18 KEY_F19 KEY_F20 KEY_F21 KEY_F22 KEY_F23 KEY_F24 KEY_PLAYCD KEY_PAUSECD KEY_PROG3 KEY_PROG4 KEY_DASHBOARD KEY_SUSPEND KEY_CLOSE KEY_PLAY KEY_FASTFORWARD KEY_BASSBOOST KEY_PRINT KEY_HP KEY_CAMERA KEY_SOUND KEY_QUESTION KEY_EMAIL KEY_CHAT KEY_SEARCH KEY_CONNECT KEY_FINANCE KEY_SPORT KEY_SHOP KEY_ALTERASE KEY_CANCEL KEY_BRIGHTNESSDOWN KEY_BRIGHTNESSUP KEY_MEDIA KEY_SWITCHVIDEOMODE KEY_KBDILLUMTOGGLE KEY_KBDILLUMDOWN KEY_KBDILLUMUP KEY_SEND KEY_REPLY KEY_FORWARDMAIL KEY_SAVE KEY_DOCUMENTS KEY_BATTERY KEY_BLUETOOTH KEY_WLAN KEY_UWB KEY_UNKNOWN KEY_VIDEO_NEXT KEY_VIDEO_PREV KEY_BRIGHTNESS_CYCLE ['KEY_BRIGHTNESS_AUTO', 'KEY_BRIGHTNESS_ZERO'] KEY_DISPLAY_OFF ['KEY_WIMAX', 'KEY_WWAN'] KEY_RFKILL KEY_MICMUTE ['BTN_0', 'BTN_MISC'] BTN_1 BTN_2 BTN_3 BTN_4 BTN_5 BTN_6 BTN_7 BTN_8 BTN_9 ['BTN_LEFT', 'BTN_MOUSE'] BTN_RIGHT BTN_MIDDLE BTN_SIDE BTN_EXTRA BTN_FORWARD BTN_BACK BTN_TASK ['BTN_JOYSTICK', 'BTN_TRIGGER'] BTN_THUMB BTN_THUMB2 BTN_TOP BTN_TOP2 BTN_PINKIE BTN_BASE BTN_BASE2 BTN_BASE3 BTN_BASE4 BTN_BASE5 BTN_BASE6 BTN_DEAD ['BTN_A', 'BTN_GAMEPAD', 'BTN_SOUTH'] ['BTN_B', 'BTN_EAST'] BTN_C ['BTN_NORTH', 'BTN_X'] ['BTN_WEST', 'BTN_Y'] BTN_Z BTN_TL BTN_TR BTN_TL2 BTN_TR2 BTN_SELECT BTN_START BTN_MODE BTN_THUMBL BTN_THUMBR ['BTN_DIGI', 'BTN_TOOL_PEN'] BTN_TOOL_RUBBER BTN_TOOL_BRUSH BTN_TOOL_PENCIL BTN_TOOL_AIRBRUSH BTN_TOOL_FINGER BTN_TOOL_MOUSE BTN_TOOL_LENS BTN_TOOL_QUINTTAP BTN_TOUCH BTN_STYLUS BTN_STYLUS2 BTN_TOOL_DOUBLETAP BTN_TOOL_TRIPLETAP BTN_TOOL_QUADTAP ['BTN_GEAR_DOWN', 'BTN_WHEEL'] BTN_GEAR_UP KEY_OK KEY_SELECT KEY_GOTO KEY_CLEAR KEY_POWER2 KEY_OPTION KEY_INFO KEY_TIME KEY_VENDOR KEY_ARCHIVE KEY_PROGRAM KEY_CHANNEL KEY_FAVORITES KEY_EPG KEY_PVR KEY_MHP KEY_LANGUAGE KEY_TITLE KEY_SUBTITLE KEY_ANGLE KEY_ZOOM KEY_MODE KEY_KEYBOARD KEY_SCREEN KEY_PC KEY_TV KEY_TV2 KEY_VCR KEY_VCR2 KEY_SAT KEY_SAT2 KEY_CD KEY_TAPE KEY_RADIO KEY_TUNER KEY_PLAYER KEY_TEXT KEY_DVD KEY_AUX KEY_MP3 KEY_AUDIO KEY_VIDEO KEY_DIRECTORY KEY_LIST KEY_MEMO KEY_CALENDAR KEY_RED KEY_GREEN KEY_YELLOW KEY_BLUE KEY_CHANNELUP KEY_CHANNELDOWN KEY_FIRST KEY_LAST KEY_AB KEY_NEXT KEY_RESTART KEY_SLOW KEY_SHUFFLE KEY_BREAK KEY_PREVIOUS KEY_DIGITS KEY_TEEN KEY_TWEN KEY_VIDEOPHONE KEY_GAMES KEY_ZOOMIN KEY_ZOOMOUT KEY_ZOOMRESET KEY_WORDPROCESSOR KEY_EDITOR KEY_SPREADSHEET KEY_GRAPHICSEDITOR KEY_PRESENTATION KEY_DATABASE KEY_NEWS KEY_VOICEMAIL KEY_ADDRESSBOOK KEY_MESSENGER ['KEY_BRIGHTNESS_TOGGLE', 'KEY_DISPLAYTOGGLE'] KEY_SPELLCHECK KEY_LOGOFF KEY_DOLLAR KEY_EURO KEY_FRAMEBACK KEY_FRAMEFORWARD KEY_CONTEXT_MENU KEY_MEDIA_REPEAT KEY_10CHANNELSUP KEY_10CHANNELSDOWN KEY_IMAGES KEY_DEL_EOL KEY_DEL_EOS KEY_INS_LINE KEY_DEL_LINE KEY_FN KEY_FN_ESC KEY_FN_F1 KEY_FN_F2 KEY_FN_F3 KEY_FN_F4 KEY_FN_F5 KEY_FN_F6 KEY_FN_F7 KEY_FN_F8 KEY_FN_F9 KEY_FN_F10 KEY_FN_F11 KEY_FN_F12 KEY_FN_1 KEY_FN_2 KEY_FN_D KEY_FN_E KEY_FN_F KEY_FN_S KEY_FN_B KEY_BRL_DOT1 KEY_BRL_DOT2 KEY_BRL_DOT3 KEY_BRL_DOT4 KEY_BRL_DOT5 KEY_BRL_DOT6 KEY_BRL_DOT7 KEY_BRL_DOT8 KEY_BRL_DOT9 KEY_BRL_DOT10 KEY_NUMERIC_0 KEY_NUMERIC_1 KEY_NUMERIC_2 KEY_NUMERIC_3 KEY_NUMERIC_4 KEY_NUMERIC_5 KEY_NUMERIC_6 KEY_NUMERIC_7 KEY_NUMERIC_8 KEY_NUMERIC_9 KEY_NUMERIC_STAR KEY_NUMERIC_POUND KEY_NUMERIC_A KEY_NUMERIC_B KEY_NUMERIC_C KEY_NUMERIC_D KEY_CAMERA_FOCUS KEY_WPS_BUTTON KEY_TOUCHPAD_TOGGLE KEY_TOUCHPAD_ON KEY_TOUCHPAD_OFF KEY_CAMERA_ZOOMIN KEY_CAMERA_ZOOMOUT KEY_CAMERA_UP KEY_CAMERA_DOWN KEY_CAMERA_LEFT KEY_CAMERA_RIGHT KEY_ATTENDANT_ON KEY_ATTENDANT_OFF KEY_ATTENDANT_TOGGLE KEY_LIGHTS_TOGGLE BTN_DPAD_UP BTN_DPAD_DOWN BTN_DPAD_LEFT BTN_DPAD_RIGHT KEY_ALS_TOGGLE KEY_BUTTONCONFIG KEY_TASKMANAGER KEY_JOURNAL KEY_CONTROLPANEL KEY_APPSELECT KEY_SCREENSAVER KEY_VOICECOMMAND KEY_BRIGHTNESS_MIN KEY_BRIGHTNESS_MAX KEY_KBDINPUTASSIST_PREV KEY_KBDINPUTASSIST_NEXT KEY_KBDINPUTASSIST_PREVGROUP KEY_KBDINPUTASSIST_NEXTGROUP KEY_KBDINPUTASSIST_ACCEPT KEY_KBDINPUTASSIST_CANCEL KEY_RIGHT_UP KEY_RIGHT_DOWN KEY_LEFT_UP KEY_LEFT_DOWN KEY_ROOT_MENU KEY_MEDIA_TOP_MENU KEY_NUMERIC_11 KEY_NUMERIC_12 KEY_AUDIO_DESC KEY_3D_MODE KEY_NEXT_FAVORITE KEY_STOP_RECORD KEY_PAUSE_RECORD KEY_VOD KEY_UNMUTE ['KEY_DATA', 'KEY_FASTREVERSE'] KEY_SLOWREVERSE ['BTN_TRIGGER_HAPPY', 'BTN_TRIGGER_HAPPY1'] BTN_TRIGGER_HAPPY2 BTN_TRIGGER_HAPPY3 BTN_TRIGGER_HAPPY4 BTN_TRIGGER_HAPPY5 BTN_TRIGGER_HAPPY6 BTN_TRIGGER_HAPPY7 BTN_TRIGGER_HAPPY8 BTN_TRIGGER_HAPPY9 BTN_TRIGGER_HAPPY10 BTN_TRIGGER_HAPPY11 BTN_TRIGGER_HAPPY12 BTN_TRIGGER_HAPPY13 BTN_TRIGGER_HAPPY14 BTN_TRIGGER_HAPPY15 BTN_TRIGGER_HAPPY16 BTN_TRIGGER_HAPPY17 BTN_TRIGGER_HAPPY18 BTN_TRIGGER_HAPPY19 BTN_TRIGGER_HAPPY20 BTN_TRIGGER_HAPPY21 BTN_TRIGGER_HAPPY22 BTN_TRIGGER_HAPPY23 BTN_TRIGGER_HAPPY24 BTN_TRIGGER_HAPPY25 BTN_TRIGGER_HAPPY26 BTN_TRIGGER_HAPPY27 BTN_TRIGGER_HAPPY28 BTN_TRIGGER_HAPPY29 BTN_TRIGGER_HAPPY30 BTN_TRIGGER_HAPPY31 BTN_TRIGGER_HAPPY32 BTN_TRIGGER_HAPPY33 BTN_TRIGGER_HAPPY34 BTN_TRIGGER_HAPPY35 BTN_TRIGGER_HAPPY36 BTN_TRIGGER_HAPPY37 BTN_TRIGGER_HAPPY38 BTN_TRIGGER_HAPPY39 BTN_TRIGGER_HAPPY40 fenrir-1.5.1/config/keyboard/desktop.conf000066400000000000000000000103301317357605400204000ustar00rootroot00000000000000KEY_FENRIR,KEY_H=toggle_tutorial_mode KEY_CTRL=shut_up KEY_FENRIR,KEY_KP9=review_bottom KEY_FENRIR,KEY_KP7=review_top KEY_KP8=review_curr_line KEY_KP7=review_prev_line KEY_KP9=review_next_line KEY_FENRIR,KEY_KP4=review_line_begin KEY_FENRIR,KEY_KP6=review_line_end KEY_FENRIR,KEY_KP1=review_line_first_char KEY_FENRIR,KEY_KP3=review_line_last_char KEY_FENRIR,KEY_ALT,KEY_1=present_first_line KEY_FENRIR,KEY_ALT,KEY_2=present_last_line KEY_KP5=review_curr_word KEY_KP4=review_prev_word KEY_KP6=review_next_word KEY_FENRIR,KEY_SHIFT,KEY_KP5=review_curr_word_phonetic KEY_FENRIR,KEY_SHIFT,KEY_KP4=review_prev_word_phonetic KEY_FENRIR,KEY_SHIFT,KEY_KP6=review_next_word_phonetic KEY_KP2=review_curr_char KEY_KP1=review_prev_char KEY_KP3=review_next_char KEY_FENRIR,KEY_SHIFT,KEY_KP2=review_curr_char_phonetic KEY_FENRIR,KEY_SHIFT,KEY_KP1=review_prev_char_phonetic KEY_FENRIR,KEY_SHIFT,KEY_KP3=review_next_char_phonetic KEY_FENRIR,KEY_CTRL,KEY_KP8=review_up KEY_FENRIR,KEY_CTRL,KEY_KP2=review_down KEY_FENRIR,KEY_KPDOT=exit_review KEY_KPDOT=cursor_position KEY_FENRIR,KEY_I=indent_curr_line KEY_FENRIR,KEY_KP5=curr_screen KEY_FENRIR,KEY_KP8=curr_screen_before_cursor KEY_FENRIR,KEY_KP2=curr_screen_after_cursor #=cursor_read_to_end_of_line #=cursor_column #=cursor_lineno #=braille_flush #=braille_return_to_cursor #=braille_pan_left #=braille_pan_right KEY_FENRIR,KEY_CTRL,KEY_1=clear_bookmark_1 KEY_FENRIR,KEY_SHIFT,KEY_1=set_bookmark_1 KEY_FENRIR,KEY_1=bookmark_1 KEY_FENRIR,KEY_CTRL,KEY_2=clear_bookmark_2 KEY_FENRIR,KEY_SHIFT,KEY_2=set_bookmark_2 KEY_FENRIR,KEY_2=bookmark_2 KEY_FENRIR,KEY_CTRL,KEY_3=clear_bookmark_3 KEY_FENRIR,KEY_SHIFT,KEY_3=set_bookmark_3 KEY_FENRIR,KEY_3=bookmark_3 KEY_FENRIR,KEY_CTRL,KEY_4=clear_bookmark_4 KEY_FENRIR,KEY_SHIFT,KEY_4=set_bookmark_4 KEY_FENRIR,KEY_4=bookmark_4 KEY_FENRIR,KEY_CTRL,KEY_5=clear_bookmark_5 KEY_FENRIR,KEY_SHIFT,KEY_5=set_bookmark_5 KEY_FENRIR,KEY_5=bookmark_5 KEY_FENRIR,KEY_CTRL,KEY_6=clear_bookmark_6 KEY_FENRIR,KEY_SHIFT,KEY_6=set_bookmark_6 KEY_FENRIR,KEY_6=bookmark_6 KEY_FENRIR,KEY_CTRL,KEY_7=clear_bookmark_7 KEY_FENRIR,KEY_SHIFT,KEY_7=set_bookmark_7 KEY_FENRIR,KEY_7=bookmark_7 KEY_FENRIR,KEY_CTRL,KEY_8=clear_bookmark_8 KEY_FENRIR,KEY_SHIFT,KEY_8=set_bookmark_8 #KEY_FENRIR,KEY_8=bookmark_8 KEY_FENRIR,KEY_CTRL,KEY_9=clear_bookmark_9 KEY_FENRIR,KEY_SHIFT,KEY_9=set_bookmark_9 KEY_FENRIR,KEY_9=bookmark_9 KEY_FENRIR,KEY_CTRL,KEY_0=clear_bookmark_10 KEY_FENRIR,KEY_SHIFT,KEY_0=set_bookmark_10 KEY_FENRIR,KEY_0=bookmark_10 KEY_FENRIR,KEY_KPSLASH=set_window_application 2,KEY_FENRIR,KEY_KPSLASH=clear_window_application KEY_KPPLUS=last_incoming KEY_FENRIR,KEY_F2=toggle_braille KEY_FENRIR,KEY_F3=toggle_sound KEY_FENRIR,KEY_F4=toggle_speech KEY_KPENTER=temp_disable_speech KEY_FENRIR,KEY_CTRL,KEY_P=toggle_punctuation_level KEY_FENRIR,KEY_RIGHTBRACE=toggle_auto_spell_check KEY_FENRIR,KEY_BACKSLASH=toggle_output KEY_FENRIR,KEY_CTRL,KEY_E=toggle_emoticons key_FENRIR,KEY_KPENTER=toggle_auto_read KEY_FENRIR,KEY_CTRL,KEY_T=toggle_auto_time KEY_FENRIR,KEY_KPASTERISK=toggle_highlight_tracking KEY_FENRIR,KEY_Q=quit_fenrir KEY_FENRIR,KEY_T=time 2,KEY_FENRIR,KEY_T=date KEY_KPMINUS=attribute_cursor KEY_FENRIR,KEY_S=spell_check 2,KEY_FENRIR,KEY_S=add_word_to_spell_check KEY_FENRIR,KEY_SHIFT,KEY_S=remove_word_from_spell_check KEY_FENRIR,KEY_BACKSPACE=forward_keypress KEY_FENRIR,KEY_UP=inc_speech_volume KEY_FENRIR,KEY_DOWN=dec_speech_volume KEY_FENRIR,KEY_RIGHT=inc_speech_rate KEY_FENRIR,KEY_LEFT=dec_speech_rate KEY_FENRIR,KEY_ALT,KEY_RIGHT=inc_speech_pitch KEY_FENRIR,KEY_ALT,KEY_LEFT=dec_speech_pitch KEY_FENRIR,KEY_ALT,KEY_UP=inc_sound_volume KEY_FENRIR,KEY_ALT,KEY_DOWN=dec_sound_volume KEY_FENRIR,KEY_CTRL,KEY_SHIFT,KEY_C=clear_clipboard KEY_FENRIR,KEY_HOME=first_clipboard KEY_FENRIR,KEY_END=last_clipboard KEY_FENRIR,KEY_PAGEUP=prev_clipboard KEY_FENRIR,KEY_PAGEDOWN=next_clipboard KEY_FENRIR,KEY_SHIFT,KEY_C=curr_clipboard KEY_FENRIR,KEY_C=copy_marked_to_clipboard KEY_FENRIR,KEY_V=paste_clipboard KEY_FENRIR,KEY_F5=import_clipboard_from_file KEY_FENRIR,KEY_F6=export_clipboard_to_file KEY_FENRIR,KEY_CTRL,KEY_SHIFT,KEY_X=remove_marks KEY_FENRIR,KEY_X=set_mark KEY_FENRIR,KEY_SHIFT,KEY_X=marked_text # linux specific KEY_FENRIR,KEY_F7=export_clipboard_to_x KEY_FENRIR,KEY_CTRL,KEY_UP=inc_alsa_volume KEY_FENRIR,KEY_CTRL,KEY_DOWN=dec_alsa_volume fenrir-1.5.1/config/keyboard/laptop.conf000066400000000000000000000107101317357605400202300ustar00rootroot00000000000000KEY_FENRIR,KEY_H=toggle_tutorial_mode KEY_CTRL=shut_up KEY_FENRIR,KEY_SHIFT,KEY_O=review_bottom KEY_FENRIR,KEY_SHIFT,KEY_U=review_top KEY_FENRIR,KEY_I=review_curr_line KEY_FENRIR,KEY_U=review_prev_line KEY_FENRIR,KEY_O=review_next_line KEY_FENRIR,KEY_SHIFT,KEY_J=review_line_begin KEY_FENRIR,KEY_SHFIT,KEY_L=review_line_end KEY_FENRIR,KEY_CTRL,KEY_J=review_line_first_char KEY_FENRIR,KEY_CTRL,KEY_L=review_line_last_char KEY_FENRIR,KEY_ALT,KEY_1=present_first_line KEY_FENRIR,KEY_ALT,KEY_2=present_last_line KEY_FENRIR,KEY_K=review_curr_word KEY_FENRIR,KEY_J=review_prev_word KEY_FENRIR,KEY_L=review_next_word KEY_FENRIR,KEY_ALT,KEY_CTRL,KEY_K=review_curr_word_phonetic KEY_FENRIR,KEY_ALT,KEY_CTRL,KEY_J=review_prev_word_phonetic KEY_FENRIR,KEY_ALT,KEY_CTRL,KEY_L=review_next_word_phonetic KEY_FENRIR,KEY_COMMA=review_curr_char KEY_FENRIR,KEY_M=review_prev_char KEY_FENRIR,KEY_DOT=review_next_char KEY_FENRIR,KEY_ALT,KEY_CTRL,KEY_COMMA=curr_char_phonetic KEY_FENRIR,KEY_ALT,KEY_CTRL,KEY_M=prev_char_phonetic KEY_FENRIR,KEY_ALT,KEY_CTRL,KEY_DOT=prev_char_phonetic KEY_FENRIR,KEY_CTRL,KEY_I=review_up KEY_FENRIR,KEY_CTRL,KEY_COMMA=review_down KEY_FENRIR,KEY_SLASH=exit_review KEY_FENRIR,KEY_SHIFT,KEY_DOT=cursor_position 2,KEY_FENRIR,KEY_I=indent_curr_line KEY_FENRIR,KEY_SHIFT,KEY_K=curr_screen KEY_FENRIR,KEY_SHIFT,KEY_I=curr_screen_before_cursor KEY_FENRIR,KEY_SHIFT,KEY_COMMA=curr_screen_after_cursor #=cursor_read_to_end_of_line #=cursor_column #=cursor_lineno #=braille_flush #=braille_return_to_cursor #=braille_pan_left #=braille_pan_right KEY_FENRIR,KEY_CTRL,KEY_1=clear_bookmark_1 KEY_FENRIR,KEY_SHIFT,KEY_1=set_bookmark_1 KEY_FENRIR,KEY_1=bookmark_1 KEY_FENRIR,KEY_CTRL,KEY_2=clear_bookmark_2 KEY_FENRIR,KEY_SHIFT,KEY_2=set_bookmark_2 KEY_FENRIR,KEY_2=bookmark_2 KEY_FENRIR,KEY_CTRL,KEY_3=clear_bookmark_3 KEY_FENRIR,KEY_SHIFT,KEY_3=set_bookmark_3 KEY_FENRIR,KEY_3=bookmark_3 KEY_FENRIR,KEY_CTRL,KEY_4=clear_bookmark_4 KEY_FENRIR,KEY_SHIFT,KEY_4=set_bookmark_4 KEY_FENRIR,KEY_4=bookmark_4 KEY_FENRIR,KEY_CTRL,KEY_5=clear_bookmark_5 KEY_FENRIR,KEY_SHIFT,KEY_5=set_bookmark_5 KEY_FENRIR,KEY_5=bookmark_5 KEY_FENRIR,KEY_CTRL,KEY_6=clear_bookmark_6 KEY_FENRIR,KEY_SHIFT,KEY_6=set_bookmark_6 KEY_FENRIR,KEY_6=bookmark_6 KEY_FENRIR,KEY_CTRL,KEY_7=clear_bookmark_7 KEY_FENRIR,KEY_SHIFT,KEY_7=set_bookmark_7 KEY_FENRIR,KEY_7=bookmark_7 KEY_FENRIR,KEY_CTRL,KEY_8=clear_bookmark_8 KEY_FENRIR,KEY_SHIFT,KEY_8=set_bookmark_8 KEY_FENRIR,KEY_8=bookmark_8 KEY_FENRIR,KEY_CTRL,KEY_9=clear_bookmark_9 KEY_FENRIR,KEY_SHIFT,KEY_9=set_bookmark_9 KEY_FENRIR,KEY_9=bookmark_9 KEY_FENRIR,KEY_CTRL,KEY_0=clear_bookmark_10 KEY_FENRIR,KEY_SHIFT,KEY_0=set_bookmark_10 KEY_FENRIR,KEY_0=bookmark_10 KEY_FENRIR,KEY_CTRL,KEY_8=set_window_application 2,KEY_FENRIR,KEY_CTRL,KEY_8=clear_window_application KEY_FENRIR,KEY_SEMICOLON=last_incoming KEY_FENRIR,KEY_F2=toggle_braille KEY_FENRIR,KEY_F3=toggle_sound KEY_FENRIR,KEY_F4=toggle_speech KEY_FENRIR,KEY_ENTER=temp_disable_speech KEY_FENRIR,KEY_SHIFT,KEY_CTRL,KEY_P=toggle_punctuation_level KEY_FENRIR,KEY_RIGHTBRACE=toggle_auto_spell_check KEY_FENRIR,KEY_SHIFT,KEY_ENTER=toggle_output KEY_FENRIR,KEY_SHIFT,KEY_E=toggle_emoticons KEY_FENRIR,KEY_ENTER=toggle_auto_read KEY_FENRIR,KEY_CTRL,KEY_T=toggle_auto_time KEY_FENRIR,KEY_Y=toggle_highlight_tracking KEY_FENRIR,KEY_Q=quit_fenrir KEY_FENRIR,KEY_T=time 2,KEY_FENRIR,KEY_T=date KEY_FENRIRDict] is the section name. Dict is a keyword # the entrys are seperated with :===: in words colon tripple equal colon ( to not collide with substitutions) [levelDict] none:===: some:===:.-$~+*-/\@ most:===:.,:-$~+*-/\@!#%^&*()[]}{<>; all:===:!"#$%& \'()*+,-./:;<=>?@[\\]^_`{|}~ [punctDict] :===:Leer &:===:Und ':===:Apostroph @:===:At \:===:Backslash |:===:Pipe !:===:Ausrufezeichen ^:===:Hoch ::===:Doppelpunkt ,:===:Komma -:===:Minus $:===:Dollar .:===:Punkt >:===:Größer als `:===:Grave #:===:Hash {:===:Geschweifte Klammer auf [:===:eckige Klammer auf (:===:Klammer auf <:===:Kleiner als %:===:Prozent +:===:Plus ?:===:Fragezeichen? ":===:Gänsefüßchen ):===:Klammer zu }:===:Geschweifte Klammer zu ]:===:Eckige Klammer zu ;:===:Semikolon /:===:Geteilt durch *:===:Mal ~:===:Tilde _:===:Lienie unten =:===:Istgleich [customDict] [emoticonDict] :):===:Grins ;):===:Zwinker XD:===:loool :D:===:Lach <{-.-}>:===:Raves fenrir-1.5.1/config/punctuation/default.conf000066400000000000000000000017161317357605400211340ustar00rootroot00000000000000# how to use this file? # the # on the beginning of the line is a comment # the different sections are seperated by [Dict] is the section name. Dict is a keyword # the entrys are seperated with :===: in words colon tripple equal colon ( to not collide with substitutions) [levelDict] none:===: some:===:-$~+*-/\@ most:===:.,:-$~+*-/\@!#%^&*()[]}{<>; all:===:!"#$%& \'()*+,-./:;<=>?@[\\]^_`{|}~ [punctDict] :===:space &:===:and ':===:apostrophe @:===:at \:===:backslash |:===:bar !:===:bang ^:===:carrot ::===:colon ,:===:comma -:===:dash $:===:dollar .:===:dot >:===:greater `:===:grave #:===:hash {:===:left brace [:===:left bracket (:===:left paren <:===:less %:===:percent +:===:plus ?:===:question? ":===:quote ):===:right paren }:===:right brace ]:===:right bracket ;:===:semicolon /:===:slash *:===:star ~:===:tilde _:===:line =:===:equals [customDict] [emoticonDict] :):===:smile ;):===:wink XD:===:LOL :D:===:laugh <{-.-}>:===:Raves \o/:===:Hurray fenrir-1.5.1/config/punctuation/en.conf000066400000000000000000000017051317357605400201100ustar00rootroot00000000000000# how to use this file? # the # on the beginning of the line is a comment # the different sections are seperated by [Dict] is the section name. Dict is a keyword # the entrys are seperated with :===: in words colon tripple equal colon ( to not collide with substitutions) [levelDict] none:===: some:===:-$~+*-/\@ most:===:.,:-$~+*-/\@!#%^&*()[]}{<>; all:===:!"#$%& \'()*+,-./:;<=>?@[\\]^_`{|}~ [punctDict] :===:space &:===:and ':===:apostrophe @:===:at \:===:backslash |:===:bar !:===:bang ^:===:carrot ::===:colon ,:===:comma -:===:dash $:===:dollar .:===:dot >:===:greater `:===:grave #:===:hash {:===:left brace [:===:left bracket (:===:left paren <:===:less %:===:percent +:===:plus ?:===:question? ":===:quote ):===:right paren }:===:right brace ]:===:right bracket ;:===:semicolon /:===:slash *:===:star ~:===:tilde _:===:line =:===:equals [customDict] [emoticonDict] :):===:smile ;):===:twinker XD:===:loool :D:===:lought <{-.-}>:===:Raves fenrir-1.5.1/config/punctuation/es.conf000066400000000000000000000020721317357605400201130ustar00rootroot00000000000000# how to use this file? # the # on the beginning of the line is a comment # the different sections are seperated by [Dict] is the section name. Dict is a keyword # the entrys are seperated with :===: in words colon tripple equal colon ( to not collide with substitutions) [levelDict] none:===: some:===:.-$~+*-/\@ most:===:.,:-$~+*-/\@!#%^&*()[]}{<>; all:===:!"#$%& \'()*+,-./:;<=>?@[\\]^_`{|}~ [punctDict] :===:espacio &:===:et ':===:apóstrofo @:===:arroba \:===:barra inversa |:===:barra vertical !:===:Cerrar exclamación ^:===:circumplejo ::===:dos puntos ,:===:coma -:===:guion $:===:dólar .:===:punto >:===:mayor que `:===:grave #:===:signo de número {:===:abrir yave [:===:abrir corchete (:===:abrir paréntesis <:===:menor que %:===:porciento +:===:más ?:===:cerrar interrogación? ":===:comillas ):===:cerrar paréntesis }:===:cerrar yave ]:===:cerrar corchete ;:===:punto y coma /:===:barra *:===:asterisco ~:===:tilde _:===:subrayado =:===:igual [customDict] [emoticonDict] :):===:sonrisa ;):===:twinker XD:===:loool :D:===:lought <{-.-}>:===:Raves fenrir-1.5.1/config/punctuation/fr.conf000066400000000000000000000022051317357605400201110ustar00rootroot00000000000000# how to use this file? # the # on the beginning of the line is a comment # the different sections are seperated by [Dict] is the section name. Dict is a keyword # the entrys are seperated with :===: in words colon tripple equal colon ( to not collide with substitutions) [levelDict] none:===: some:===:.-$~+*-/\@ most:===:.,:-$~+*-/\@!#%^&*()[]}{<>; all:===:!"#$%& \'()*+,-./:;<=>?@[\\]^_`{|}~ [punctDict] :===:espace &:===:et ':===:apostrophe @:===:arobase \:===:barre oblique inversée |:===:barre verticale !:===:point d'exclamation ^:===:accent circonflexe ::===:deux points ,:===:virgule -:===:tiret $:===:dollar .:===:point >:===:suppérieur à `:===:accent grave #:===:dièse {:===:accolade ouvrante [:===:crochet ouvrant (:===:parenthèse ouvrante <:===:inférieur à %:===:pourcent +:===:plus ?:===:point d'interrogation ":===:guillemet ):===:parenthèse fermante }:===:accolade fermante ]:===:crochet fermant ;:===:point virgule /:===:barre oblique *:===:astérisque ~:===:tildé _:===:souligné =:===:égale à [customDict] [emoticonDict] :):===:sourire ;):===:clin d'oeil XD:===:explosé de rire :D:===:rire <{-.-}>:===:Raves fenrir-1.5.1/config/punctuation/pl.conf000066400000000000000000000020401317357605400201120ustar00rootroot00000000000000# how to use this file? # the # on the beginning of the line is a comment # the different sections are seperated by [Dict] is the section name. Dict is a keyword # the entrys are seperated with :===: in words colon tripple equal colon ( to not collide with substitutions) [levelDict] none:===: some:===:.-$~+*-/\@ most:===:.,:-$~+*-/\@!#%^&*()[]}{<>; all:===:!"#$%& \'()*+,-./:;<=>?@[\\]^_`{|}~ [punctDict] :===:spacja &:===:ampersant ':===:apostrof @:===:małpa \:===:bekslesz |:===:pionowa kreska !:===:wykrzyknik ^:===:daszek ::===:dwukropek ,:===:przecinek -:===:myślnik $:===:dolar .:===:kropka >:===:większe `:===:akcent #:===:hasz {:===:lewa klamra [:===:lewy nawias kwadratowy (:===:lewy nawias <:===:mniejsze %:===:procent +:===:plus ?:===:pytajnik ":===:cudzysłów ):===:prawy nawias }:===:prawa klamra ]:===:prawy nawias kwadratowy ;:===:średnik /:===:slesz *:===:gwiazdka ~:===:tylda _:===:podkreślnik =:===:równa się [customDict] [emoticonDict] :):===:smile ;):===:twinker XD:===:loool :D:===:lought <{-.-}>:===:Raves fenrir-1.5.1/config/scripts/000077500000000000000000000000001317357605400157525ustar00rootroot00000000000000fenrir-1.5.1/config/scripts/wlan__-__key_y.sh000077500000000000000000000005651317357605400211720ustar00rootroot00000000000000#!/bin/sh #output the ESSID and signal level #needs iw (for iwconfig) if [[ $(nmcli device wifi | wc -l ) -ge 2 ]]; then echo "Signal $(nmcli -f IN-USE,SIGNAL device wifi | grep "*" | tail -n1 | cut -f 2 -d '*') %" echo "Name $(nmcli -f IN-USE,SSID device wifi | grep "*" | tail -n1 | cut -f 2 -d '*') " else echo "Leider keine Wlan verbindung $(whoami)" fi fenrir-1.5.1/config/settings/000077500000000000000000000000001317357605400161235ustar00rootroot00000000000000fenrir-1.5.1/config/settings/espeak.settings.conf000066400000000000000000000146721317357605400221130ustar00rootroot00000000000000[sound] # Turn sound on or off: enabled=True # Select the driver used to play sounds, choices are generic and gstreamer. # Sox is the default. driver=genericDriver # Sound themes. These are the pack of sounds used for sound alerts. # Sound packs may be located at /usr/share/sounds # For system wide availability, or ~/.local/share/fenrir/sounds # For the current user. theme=default-wav # Sound volume controls how loud the sounds for your chosen soundpack are. # 0 is quietest, 1.0 is loudest. volume=1.0 # shell commands for generic sound driver # the folowing variable are substituded # fenrirVolume = the current volume setting # fenrirSoundFile = the soundfile for an soundicon # fenrirFrequence = the frequence to play # fenrirDuration = the duration of the frequence # the following command is used for play a soundfile genericPlayFileCommand=play -q -v fenrirVolume fenrirSoundFile 2>/dev/null #the following command is used for generating a frequency beep genericFrequencyCommand=play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence 2>/dev/null [speech] # Turn speech on or off: enabled=True # Select speech driver, options are speechdDriver (default), genericDriver or espeakDriver: #driver=speechdDriver #driver=genericDriver driver=espeakDriver # server path for emacspeak serverPath= # The rate selects how fast Fenrir will speak. Options range from 0, slowest, to 1.0, fastest. rate=0.35 # Pitch controls the pitch of the voice, select from 0, lowest, to 1.0, highest. pitch=0.5 # Pitch for capital letters capitalPitch=0.9 # Volume controls the loudness of the voice, select from 0, quietest, to 1.0, loudest. volume=1.0 # Module is used for Speech-dispatcher, to select the speech module you want to use. # Consult Speech-dispatcher's configuration and help ti find out which modules are available. # The default is Espeak. module=espeak # Voice selects the varient you want to use, for example, f5 will use the female voice #5 in Espeak, # or if using the Espeak module in Speech-dispatcher. To find out which voices are available, consult the documentation provided with your selected synthesizer. voice=f3 # Select the language you want Fenrir to use. language=en_US # Read new text as it happens? autoReadIncoming=True # genericSpeechCommand is the command that is executed for talking # the following variables are replaced with values # fenrirText = is the text that should be spoken # fenrirModule = may be the speech module used in Speech-dispatcher, not every TTY needs this # fenrirLanguage = the language # fenrirVoice = is the current voice that should be used # the current volume, pitch and rate is calculated like this # value = min + settingValue * (min - max ) # fenrirVolume = is replaced with the current volume # fenrirPitch = is replaced with the current pitch # fenrirRate = is replaced with the current speed (speech rate) genericSpeechCommand=espeak -a fenrirVolume -s fenrirRate -p fenrirPitch -v fenrirVoice "fenrirText" # these are the minimum and maximum values of the TTS system used in genericSpeechCommand fenrirMinVolume=0 fenrirMaxVolume=200 fenrirMinPitch=0 fenrirMaxPitch=99 fenrirMinRate=80 fenrirMaxRate=450 [braille] enabled=False driver=dummyDriver layout=en # to what should the flush timeout relate to # word = flush after (number of words to display) * seconds # char = flush after (number of chars to display) * seconds # fix = flush after X seconds # none = no automatic flush (manual via shortcut) flushMode=word # seconds to flush or # -1 = no automatic flush (manual via shortcut) flushTimeout=3 # how should the cursor be focused? # page = if cursor cross the border move to next page and start at beginn # fixCell = ajust the cursor on an special cell where it is always placed. the display scroll here more smooth. cursorFocusMode=page # define the cell on the Braille device where fenrir should scroll and keep the cursor # 0 = first cell on device # -1 = last cell on device # >0 = fix cell number fixCursorOnCell=-1 #How should the braille follow the focus # none = no automatic toggle command used # review = priority to review # last = follow last used cursor cursorFollowMode=review # number of cells in panning (horizontal) # 0 = display size, >0 number of cells panSizeHorizontal=0 [screen] driver=vcsaDriver encoding=auto screenUpdateDelay=0.05 suspendingScreen= autodetectSuspendingScreen=True [keyboard] driver=evdevDriver # filter input devices NOMICE, ALL or a DEVICE NAME device=ALL # gives Fenrir exclusive access to the keyboard and let consume keystrokes. grabDevices=True ignoreShortcuts=False # the current shortcut layout located in /etc/fenrir/keyboard keyboardLayout=desktop # echo chars while typing. charEcho=True ## echo deleted chars charDeleteEcho=True # echo word after pressing space wordEcho=True # interrupt speech on any keypress interruptOnKeyPress=True # you can filter the keys on that the speech should interrupt (empty = all keys, otherwhise the given keys) interruptOnKeyPressFilter= # timeout for double tap in sec doubleTapTimeout=0.2 [general] debugLevel=0 debugMode=File punctuationProfile=default punctuationLevel=some respectPunctuationPause=True newLinePause=True numberOfClipboards=10 # used path for "export_clipboard_to_file" # $user is replaced by username clipboardExportPath=/tmp/fenrirClipboard emoticons=True # define the current Fenrir key fenrirKeys=KEY_KP0,KEY_META scriptKey=KEY_COMPOSE timeFormat=%H:%M:%P dateFormat=%A, %B %d, %Y autoSpellCheck=True spellCheckLanguage=en_US scriptPath=/usr/share/fenrir/scripts commandPath= #fenrirBGColor = the backgroundcolor #fenrirFGColor = the foregroundcolor #fenrirUnderline = speak the underline attribute #fenrirBold = speak the bold attribute #fenrirBlink = speak the blink attribute #fenrirFont = the font #fenrirFontSize = the fontsize attributeFormatString=Background fenrirBGColor,Foreground fenrirFGColor,fenrirUnderline,fenrirBold,fenrirBlink, Font fenrirFont,Fontsize fenrirFontSize [focus] cursor=True highlight=False [review] lineBreak=True endOfScreen=True # leave the review when pressing a key leaveReviewOnCursorChange=True # leave the review when changing the screen leaveReviewOnScreenChange=True [promote] enabled=True inactiveTimeoutSec=120 list= [time] enabled=False presentTime=True presentDate=True delaySec=0 # present time after to given minutes example every 15 minutes: 00,15,30,45 # if delaySec is >0 onMinutes is ignored onMinutes=00,30 # announce via soundicon announce=True # interrupt current speech for time announcement interrupt=False fenrir-1.5.1/config/settings/settings.conf000066400000000000000000000161441317357605400206400ustar00rootroot00000000000000[sound] # Turn sound on or off: enabled=True # Select the driver used to play sounds, choices are genericDriver and gstreamerDriver. # Sox is the default. #driver=gstreamerDriver driver=genericDriver # Sound themes. These are the pack of sounds used for sound alerts. # Sound packs may be located at /usr/share/sounds # For system wide availability, or ~/.local/share/fenrir/sounds # For the current user. theme=default-wav # Sound volume controls how loud the sounds for your selected soundpack are. # 0 is quietest, 1.0 is loudest. volume=1.0 # shell commands for generic sound driver # the folowing variable are substituted # fenrirVolume = the current volume setting # fenrirSoundFile = the soundfile for an soundicon # fenrirFrequence = the frequency to play # fenrirDuration = the duration of the frequency # the following command is used to play a soundfile genericPlayFileCommand=play -q -v fenrirVolume fenrirSoundFile #the following command is used to generate a frequency beep genericFrequencyCommand=play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence [speech] # Turn speech on or off: enabled=True # Select speech driver, options are speechdDriver (default), genericDriver or espeakDriver: driver=speechdDriver #driver=espeakDriver #driver=genericDriver # server path for emacspeak serverPath=/home/chrys/Projekte/emacspeak/servers/espeak # The rate selects how fast Fenrir will speak. Options range from 0, slowest, to 1.0, fastest. rate=0.65 # Pitch controls the pitch of the voice, select from 0, lowest, to 1.0, highest. pitch=0.5 # Pitch for capital letters capitalPitch=0.9 # Volume controls the loudness of the voice, select from 0, quietest, to 1.0, loudest. volume=1.0 # Module is used for Speech-dispatcher, to select the speech module you want to use. # Consult Speech-dispatcher's configuration and help Fenrir find out which modules are available. # The default is espeak. module=espeak # Voice selects the varient you want to use, for example, f5 will use the female voice #5 in Espeak, # or if using the Espeak module in Speech-dispatcher. To find out which voices are available, consult the documentation provided with your selected synthesizer. # This also sets the voice used in the generic driver. voice= # Select the language you want Fenrir to use. language=english-us # Read new text as it happens? autoReadIncoming=True # genericSpeechCommand is the command that is executed for talking # the following variables are replaced with values # fenrirText = is the text that should be spoken # fenrirModule = may be the speech module like used in speech-dispatcher, not every TTY need this # fenrirLanguage = the language # fenrirVoice = is the current voice that should be used. Set the voice variable above. # the current volume, pitch and rate is calculated like this # value = min + settingValue * (min - max ) # fenrirVolume = is replaced with the current volume # fenrirPitch = is replaced with the current pitch # fenrirRate = is replaced with the current speed (speech rate) genericSpeechCommand=espeak -a fenrirVolume -s fenrirRate -p fenrirPitch -v fenrirVoice "fenrirText" # those are the min and max values of the TTS system that is used in genericSpeechCommand fenrirMinVolume=0 fenrirMaxVolume=200 fenrirMinPitch=0 fenrirMaxPitch=99 fenrirMinRate=80 fenrirMaxRate=450 [braille] enabled=False driver=dummyDriver layout=en # to what should the flush timeout relate to # word = flush after (number of words to display) * seconds # char = flush after (number of chars to display) * seconds # fix = flush after X seconds # none = no automatic flush (manual via shortcut) flushMode=word # seconds to flush or # -1 = no automatic flush (manual via shortcut) flushTimeout=3 # how should the cursor be focused? # page = if cursor cross the border move to next page and start at beginn # fixCell = ajust the cursor on an special cell where it is always placed. the display scroll here more smooth. cursorFocusMode=page # define the cell on the Braille device where fenrir should scroll and keep the cursor # 0 = first cell on device # -1 = last cell on device # >0 = fix cell number fixCursorOnCell=-1 #How should the braille follow the focus # none = no automatic toggle command used # review = priority to review # last = follow last used cursor cursorFollowMode=review # number of cells in panning (horizontal) # 0 = display size, >0 number of cells panSizeHorizontal=0 [screen] driver=vcsaDriver encoding=auto screenUpdateDelay=0.05 suspendingScreen= autodetectSuspendingScreen=True [keyboard] driver=evdevDriver # filter input devices NOMICE, ALL or a DEVICE NAME device=ALL # gives Fenrir exclusive access to the keyboard and lets it control keystrokes. grabDevices=True ignoreShortcuts=False # the current shortcut layout located in /etc/fenrir/keyboard keyboardLayout=desktop # echo chars while typing. charEcho=False # echo deleted chars charDeleteEcho=True # echo word after pressing space wordEcho=False # interrupt speech on any keypress interruptOnKeyPress=False # you can filter the keys on that the speech should interrupt (empty = all keys, otherwhise the given keys) interruptOnKeyPressFilter= # timeout for double tap in sec doubleTapTimeout=0.2 [general] debugLevel=0 # debugMode sets where the debug output should send to: # debugMode=File writes to /var/log/fenrir.log # debugMode=Print just prints on the screen debugMode=File punctuationProfile=default punctuationLevel=some respectPunctuationPause=True newLinePause=True numberOfClipboards=10 # used path for "export_clipboard_to_file" # $user is replaced by username #clipboardExportPath=/home/$user/fenrirClipboard clipboardExportPath=/tmp/fenrirClipboard emoticons=True # define the current Fenrir key fenrirKeys=KEY_KP0,KEY_META,KEY_INSERT scriptKey=KEY_COMPOSE timeFormat=%H:%M:%P dateFormat=%A, %B %d, %Y autoSpellCheck=True spellCheckLanguage=en_US # path for your scripts "scriptKey" functionality scriptPath=/usr/share/fenrir/scripts # overload commands, and create new one without changing Fenrir default commandPath= #fenrirBGColor = the backgroundcolor #fenrirFGColor = the foregroundcolor #fenrirUnderline = speak the underline attribute #fenrirBold = speak the bold attribute #fenrirBlink = speak the blink attribute #fenrirFont = the font #fenrirFontSize = the fontsize attributeFormatString=Background fenrirBGColor,Foreground fenrirFGColor,fenrirUnderline,fenrirBold,fenrirBlink, Font fenrirFont,Fontsize fenrirFontSize [focus] #follow the text cursor cursor=True #follow highlighted text changes highlight=False [review] lineBreak=True endOfScreen=True # leave the review when pressing a key leaveReviewOnCursorChange=True # leave the review when changing the screen leaveReviewOnScreenChange=True [promote] enabled=True inactiveTimeoutSec=120 list= [time] # automatic time anouncement enabled=False # present time presentTime=True # present date (on change) presentDate=True # present time after a given period of seconds delaySec=0 # present time after to given minutes example every 15 minutes: 00,15,30,45 # if delaySec is >0 onMinutes is ignored onMinutes=00,30 # announce via soundicon (not interrupting) announce=True # interrupt current speech for time announcement interrupt=False fenrir-1.5.1/config/settings/settings.conf.example000066400000000000000000000162071317357605400222720ustar00rootroot00000000000000[sound] # Turn sound on or off: enabled=True # Select the driver used to play sounds, choices are genericDriver and gstreamerDriver. # Sox is the default. #driver=gstreamerDriver driver=genericDriver # Sound themes. These are the pack of sounds used for sound alerts. # Sound packs may be located at /usr/share/sounds # For system wide availability, or ~/.local/share/fenrir/sounds # For the current user. theme=default-wav # Sound volume controls how loud the sounds for your selected soundpack are. # 0 is quietest, 1.0 is loudest. volume=1.0 # shell commands for generic sound driver # the folowing variable are substituted # fenrirVolume = the current volume setting # fenrirSoundFile = the soundfile for an soundicon # fenrirFrequence = the frequency to play # fenrirDuration = the duration of the frequency # the following command is used to play a soundfile genericPlayFileCommand=play -q -v fenrirVolume fenrirSoundFile #the following command is used to generate a frequency beep genericFrequencyCommand=play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence [speech] # Turn speech on or off: enabled=True # Select speech driver, options are speechdDriver (default), genericDriver, emacspeak or espeakDriver: driver=speechdDriver #driver=espeakDriver #driver=genericDriver #driver=emacspeakDriver # server path for emacspeak serverPath=/home/chrys/Projekte/emacspeak/servers/espeak # The rate selects how fast Fenrir will speak. Options range from 0, slowest, to 1.0, fastest. rate=0.65 # Pitch controls the pitch of the voice, select from 0, lowest, to 1.0, highest. pitch=0.5 # Pitch for capital letters capitalPitch=0.9 # Volume controls the loudness of the voice, select from 0, quietest, to 1.0, loudest. volume=1.0 # Module is used for Speech-dispatcher, to select the speech module you want to use. # Consult Speech-dispatcher's configuration and help Fenrir find out which modules are available. # The default is espeak. module=espeak # Voice selects the varient you want to use, for example, f5 will use the female voice #5 in Espeak, # or if using the Espeak module in Speech-dispatcher. To find out which voices are available, consult the documentation provided with your selected synthesizer. # This also sets the voice used in the generic driver. voice= # Select the language you want Fenrir to use. language=english-us # Read new text as it happens? autoReadIncoming=True # genericSpeechCommand is the command that is executed for talking # the following variables are replaced with values # fenrirText = is the text that should be spoken # fenrirModule = may be the speech module like used in speech-dispatcher, not every TTY need this # fenrirLanguage = the language # fenrirVoice = is the current voice that should be used. Set the voice variable above. # the current volume, pitch and rate is calculated like this # value = min + settingValue * (min - max ) # fenrirVolume = is replaced with the current volume # fenrirPitch = is replaced with the current pitch # fenrirRate = is replaced with the current speed (speech rate) genericSpeechCommand=espeak -a fenrirVolume -s fenrirRate -p fenrirPitch -v fenrirVoice "fenrirText" # those are the min and max values of the TTS system that is used in genericSpeechCommand fenrirMinVolume=0 fenrirMaxVolume=200 fenrirMinPitch=0 fenrirMaxPitch=99 fenrirMinRate=80 fenrirMaxRate=450 [braille] enabled=False driver=dummyDriver layout=en # to what should the flush timeout relate to # word = flush after (number of words to display) * seconds # char = flush after (number of chars to display) * seconds # fix = flush after X seconds # none = no automatic flush (manual via shortcut) flushMode=word # seconds to flush or # -1 = no automatic flush (manual via shortcut) flushTimeout=3 # how should the cursor be focused? # page = if cursor cross the border move to next page and start at beginn # fixCell = ajust the cursor on an special cell where it is always placed. the display scroll here more smooth. cursorFocusMode=page # define the cell on the Braille device where fenrir should scroll and keep the cursor # 0 = first cell on device # -1 = last cell on device # >0 = fix cell number fixCursorOnCell=-1 #How should the braille follow the focus # none = no automatic toggle command used # review = priority to review # last = follow last used cursor cursorFollowMode=review # number of cells in panning (horizontal) # 0 = display size, >0 number of cells panSizeHorizontal=0 [screen] driver=vcsaDriver encoding=auto screenUpdateDelay=0.05 suspendingScreen= autodetectSuspendingScreen=True [keyboard] driver=evdevDriver # filter input devices NOMICE, ALL or a DEVICE NAME device=ALL # gives Fenrir exclusive access to the keyboard and lets it control keystrokes. grabDevices=True ignoreShortcuts=False # the current shortcut layout located in /etc/fenrir/keyboard keyboardLayout=desktop # echo chars while typing. charEcho=False # echo deleted chars charDeleteEcho=True # echo word after pressing space wordEcho=False # interrupt speech on any keypress interruptOnKeyPress=False # you can filter the keys on that the speech should interrupt (empty = all keys, otherwhise the given keys) interruptOnKeyPressFilter= # timeout for double tap in sec doubleTapTimeout=0.2 [general] debugLevel=0 # debugMode sets where the debug output should send to: # debugMode=File writes to /var/log/fenrir.log # debugMode=Print just prints on the screen debugMode=File punctuationProfile=default punctuationLevel=some respectPunctuationPause=True newLinePause=True numberOfClipboards=10 # used path for "export_clipboard_to_file" # $user is replaced by username #clipboardExportPath=/home/$user/fenrirClipboard clipboardExportPath=/tmp/fenrirClipboard emoticons=True # define the current Fenrir key fenrirKeys=KEY_KP0,KEY_META,KEY_INSERT scriptKey=KEY_COMPOSE timeFormat=%H:%M:%P dateFormat=%A, %B %d, %Y autoSpellCheck=True spellCheckLanguage=en_US # path for your scripts "scriptKey" functionality scriptPath=/usr/share/fenrir/scripts # overload commands, and create new one without changing Fenrir default commandPath= #fenrirBGColor = the backgroundcolor #fenrirFGColor = the foregroundcolor #fenrirUnderline = speak the underline attribute #fenrirBold = speak the bold attribute #fenrirBlink = speak the blink attribute #fenrirFont = the font #fenrirFontSize = the fontsize attributeFormatString=Background fenrirBGColor,Foreground fenrirFGColor,fenrirUnderline,fenrirBold,fenrirBlink, Font fenrirFont,Fontsize fenrirFontSize [focus] #follow the text cursor cursor=True #follow highlighted text changes highlight=False [review] lineBreak=True endOfScreen=True # leave the review when pressing a key leaveReviewOnCursorChange=True # leave the review when changing the screen leaveReviewOnScreenChange=True [promote] enabled=True inactiveTimeoutSec=120 list= [time] # automatic time anouncement enabled=False # present time presentTime=True # present date (on change) presentDate=True # present time after a given period of seconds delaySec=0 # present time after to given minutes example every 15 minutes: 00,15,30,45 # if delaySec is >0 onMinutes is ignored onMinutes=00,30 # announce via soundicon (not interrupting) announce=True # interrupt current speech for time announcement interrupt=False fenrir-1.5.1/config/settings/settings.conf.storm000066400000000000000000000114451317357605400220020ustar00rootroot00000000000000[sound] enabled=True driver=genericDriver theme=default volume=1.0 # shell commands for generic sound driver genericPlayFileCommand=play -q -v fenrirVolume fenrirSoundFile genericFrequencyCommand=play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence [speech] enabled=True driver=speechdDriver #driver=genericDriver serverPath= rate=0.95 pitch=0.5 # Pitch for capital letters capitalPitch=0.9 module=espeak voice=en-us language=english-us volume=1.0 autoReadIncoming=True # genericSpeechCommand is the command that is executed for talking # the following variables are replaced with values # fenrirText = is the text that should be spoken # fenrirModule = may be the speech module like used in speech-dispatcher, not every TTY need this # fenrirLanguage = the language # fenrirVoice = is the current voice that should be used # the current volume, pitch and rate is calculated like this # value = min + settingValue * (min - max ) # fenrirVolume = is replaced with the current volume # fenrirPitch = is replaced with the current pitch # fenrirRate = is replaced with the current speed (speech rate) genericSpeechCommand=espeak -a fenrirVolume -s fenrirRate -p fenrirPitch -v fenrirVoice "fenrirText" # these are the min and max values of the TTS system that is used in genericSpeechCommand fenrirMinVolume=0 fenrirMaxVolume=200 fenrirMinPitch=0 fenrirMaxPitch=99 fenrirMinRate=80 fenrirMaxRate=890 [braille] enabled=False driver=dummyDriver layout=en # to what should the flush timeout relate to # word = flush after (number of words to display) * seconds # char = flush after (number of chars to display) * seconds # fix = flush after X seconds # none = no automatic flush (manual via shortcut) flushMode=word # seconds to flush or # -1 = no automatic flush (manual via shortcut) flushTimeout=3 # how should the cursor be focused? # page = if cursor cross the border move to next page and start at beginn # fixCell = ajust the cursor on an special cell where it is always placed. the display scroll here more smooth. cursorFocusMode=page # define the cell on the Braille device where fenrir should scroll and keep the cursor # 0 = first cell on device # -1 = last cell on device # >0 = fix cell number fixCursorOnCell=-1 #How should the braille follow the focus # none = no automatic toggle command used # review = priority to review # last = follow last used cursor cursorFollowMode=review # number of cells in panning (horizontal) # 0 = display size, >0 number of cells panSizeHorizontal=0 [screen] driver=vcsaDriver encoding=auto screenUpdateDelay=0.05 suspendingScreen= autodetectSuspendingScreen=True [keyboard] driver=evdevDriver # filter input devices NOMICE, ALL or a DEVICE NAME device=ALL grabDevices=True ignoreShortcuts=False keyboardLayout=desktop charEcho=False charDeleteEcho=True wordEcho=False interruptOnKeyPress=True # you can filter the keys on that the speech should interrupt (empty = all keys, otherwhise the given keys) interruptOnKeyPressFilter= # timeout for double tap in sec doubleTapTimeout=0.2 [general] debugLevel=1 # debugMode sets where the debug output should send to: # debugMode=File writes to /var/log/fenrir.log # debugMode=Print just prints on the screen debugMode=File punctuationProfile=default punctuationLevel=some respectPunctuationPause=True newLinePause=True numberOfClipboards=10 # used path for "export_clipboard_to_file" # $user is replaced by username clipboardExportPath=/tmp/fenrirClipboard emoticons=True fenrirKeys=KEY_KP0,KEY_META scriptKey=KEY_COMPOSE timeFormat=%H:%M:%P dateFormat="%A, %B %d, %Y" autoSpellCheck=True spellCheckLanguage=en_US scriptPath=/usr/share/fenrir/scripts # overload commands, and create new one without changing Fenrir default commandPath= #fenrirBGColor = the backgroundcolor #fenrirFGColor = the foregroundcolor #fenrirUnderline = speak the underline attribute #fenrirBold = speak the bold attribute #fenrirBlink = speak the blink attribute #fenrirFont = the font #fenrirFontSize = the fontsize attributeFormatString=Background fenrirBGColor,Foreground fenrirFGColor,fenrirUnderline,fenrirBold,fenrirBlink, Font fenrirFont,Fontsize fenrirFontSize [focus] #follow the text cursor cursor=True #follow highlighted text changes highlight=False [review] lineBreak=True endOfScreen=True # leave the review when pressing a key leaveReviewOnCursorChange=True # leave the review when changing the screen leaveReviewOnScreenChange=True [promote] enabled=True inactiveTimeoutSec=120 list= [time] # automatic time anouncement enabled=False # present time presentTime=True # present date (on change) presentDate=True # present time after x seconds delaySec=0 # present time after to given minutes example every 15 minutes: 00,15,30,45 # if delaySec is >0 onMinutes is ignored onMinutes=00,30 # announce via soundicon announce=True # interrupt current speech for time announcement interrupt=False fenrir-1.5.1/config/sound/000077500000000000000000000000001317357605400154135ustar00rootroot00000000000000fenrir-1.5.1/config/sound/default-wav/000077500000000000000000000000001317357605400176325ustar00rootroot00000000000000fenrir-1.5.1/config/sound/default-wav/Accept.wav000066400000000000000000001131201317357605400215460ustar00rootroot00000000000000RIFFHWAVEfmt (  8qfact%data1j6tO G> ue ' v"tA}}dl|O`#!h,"#%?E%V&'?)o*#+gW-hH.i}/t012{4I,5b<6E7׀H8%iX?o@2@#Ap&BB0ZCQC+mDPDD\EE<(FKFFdGRGGU.GG]G!PG G5G4IGBGoG1G NG^GMF<3wFFDE9KEtD]TDCk8CBAIAN#@Uo?L ?9>#_=;}<ޒ;I֟:9T87< 6Lh5F4uP3Z1H0Bt/n.., +e5*}(v6q'-&“$&#o!J$ 3]6$_KG)a o>ﯕX z< & z *kv'ڢ VEED5cʀՃDgq \G{2 -fy&2%a>EG'vA Pe~1vx0i\Ѳs OḚX c@ǂPƿŠAzø ‰B$" ?z[Mɽ2K{yVgӺU[z%4`BoDl$p,Pd깸P ¬6oۆmaa!4oi[\ݾAz{ZB6572Y9ŭJƋdǟa (w/o˾ΊЉvm\MǽB Sڧ6-~ڔ߀Ej䬳珮Am ]?ZZg($,@VO xVNPi).&mOFY } N F6l:&-uO$ sn !"3>i$&b'')9*Y/,-/ʙ01:3H4"5 7J ?8th9݇: ;է<=J>?f@ g:A=B BoC?D D8EE]+F[FcF]9Gt)zG G&GKG G7GZGGc@GqG2/G|F.FFE2[ETʍDuCuFCBAz@!@<:?_F>MG=Y<<%;qY:8i(7]60l5!3Y2"|0Ɣ{/:y-mx,n*NR)+r'v &]$P"@ ([_$/_b+=7SL]qk Bw pܮF^Zji7S ށ8. _Pv红e_ߠ& .nJܜ\ث/׃Չ\|4LQ+k~݇Xa#9.o ?ij߱}#E޽ g;^nuW!",ָEDVL,|;fZkB"sTy濹g :3úFZ>HwH'-G/qA+çMĚ|PƴNkTLb7ŖFϑ&< ӍZ;O ܧbi#@$%]{gں =+@a6Xqn!D@*߱U3 pL }b Pv{†Vßxd@za!e A#%&(aBn*>#,~-0o/]=12r4#P566/L8ǜ9J:\<==X>Td?.b@DgQAD1BCChwD*EE/FŤFGWG`G}GؽGEG GG:GG{FKG-/FjFoFoE=DTDGC,dB{AF#A#@a??i>#<A;j:97 S6Q4V31(0.DH, +B)n'8%#!!l ֩ύDylzX2s@ ' )t==U!!̨}r%?"g뚘wa^ L㆔@<_@ۦLۘa[yzݷb?o.)tu5z7îi^ٿپ ?ȃ?ٺdU@9#D AQ%J YC/"`I}bܹ"2j 6j~{S":2&;U´^L/Ũ_NǁkBSʸ_̟O `"trZ=ӁDgت k-j]k%rBoǣ5b>SEJw*iI7ΠQWQO)7 J iH*ilkW:88 4ST (?k"x$o|&npv(Ze*BH,'n.[/{1(W3z4%368?ֆ9j:A<}=8ո>?f@/A1B\.CstD'EPEzSFF^0GɀGGG*GGGGKzGҋ(GF2FFɷE5E]DLCMBA ٿ@?̓>C=q;:(97"6uv421Ǯ9/V^-ޒu+)"}'=p%XW#3!n*ƟH9+HH0k $ ɬ;07W Qq@Y#HglS2"?*|@z"xjV4Cr#ҎiH˳ɣJvtI&yʎyMUiDhj(]B<V|a ^a* DnU9toƸ-L. i?麍z|ehdmw( z(mGVPߏ >B#R .+p'A1؈NT_F:1QY 's!Z3W_5ey|$ P >"ĬZ4 4/ Ɵ9i*A@;aٷ!'G#S~%')+-S/1͉3M5~7ZN8_/:{;8=Kf>S? @x-ABNCxDm^E{FaϒF G6iGGBGGdG7GpG>fGGiFOEUE†D@C~ B4A@L݄??>b ŀTx~+߆xC-X>}졭[mոk⻍QXgP!ٺ_7ҵߚ~ U̐jɶi{ipLC6up%F(jՕ۽Z3ؼ6Nz^w3øym 51pauZLA与\r▙]&; 1E?xe1C8cÔb}c *ȟn,<ͬj +<,/rM]BmBa鼃 'MNFlonO* ZXe|A"S > WF}֚C:B^ Y!x#G#&st(CO*,J/^134fi6y8_?:C;uT=8> @;EAxdBֻjC9WDR)EHE-FGhGʴG,G]GG^GJ G 8G(Fy1FElDCPB,zA|@aQ? =u<::9g{7pY5}3%1./CJ-M+3)(5&C$!VHC_s` HH ۆ ,4Ƃ<trfں}8SҐe!WvU◗ARݵ>lO؛urP)zѴ'͌k_<,E3kv>{M.׾%n=a;ϺE7lrIk?˔3?W9A(+rRw-Tغ%j\76:8ods\-ժ 4_'3wi? wzqBތ x f({C?:-YqUZrE2"  C"apj6)JoZ$!$@ 'Uy)j+Z$.']0<2ۏ46 i82:b ;)x=g>YU@.AFgBCD!E~EFc-F-PGkGOG[bGV"GGGr$G,FE# >E^DDaChFBښA"չ?H>l<3;ǸS9{x7#?5y3W1>/w,ip*Q'{u%$," 7 yW"=$w1MLE?R hX mu[ZD]X4zU SSWL}`Нo]q`}FG(DgعՓ~,'ќYYxf[Vƿ*LHÇ״<=<솼{JT=dDs$ĸ ld%3 /lu)ܸc # ԺĽXƼ824%:levM?)J&nߪ!f1sٶSŝ aƼ@W,"!(W6H}^Mv`"GS 3Od5vlgP_ ' #M@%oh(*vf-=u/D2H@4lX6gV89: 2v@A AC{ ;D;4E FJFCGGGGG@G0WGFl*FЫZEeDKCa B @f&? =S; 9E7 5¡X3d0<|.+:)Yw&͇#L w~j~[ !% h aOɧvJRk8`o6 Eiw=`gA@?5jAR1FYTDzq["}䠱笎vHHc?Ug<"Q`8X E J _V4o 8* A$#{&(7+c. 0j3Q57[q:< =թ?FACzBCDE@F?5G GLG"G5GtG1XGFFZ=ES7D CųA46@>w<:86M4 1cN/h,)&'u$9j t'm7hS G Q/oy';?)s9\)WRKqo2'Pא!O_Ҭ5".8GwRkM~lFsc)%Wo9 E>{`ܸhhE!"cR-ѺsO^kMQF$RſcxRƾ̻Jяԑڏ}>j]I%c0,̈+Il^ ![g?-|/!`9%(oS*- 03K5,C7 :uaC̒AW@b>Op@3@A;C[TDOhE^MF GjGGGG$G4GFEVjDVCB;@f><:k8.63*0d%."4+W%($y!2JWέ_q$Lt (O 89tT<8;vT V9d} Jٽ-cYRxvBRvh0761@U=(׻z+ɹR *IgzWܒ͸|3vZVQ%j^k uOoÏa/-Z[]wң<2rU=Hpourco OsĂ8v±iT! 0G*Zg7!:0%Qm(+%=.k1%4 %6+&9i;fE=Ehj?&A^B D85E+F? F4|GJGGG1G(GJxFBNE|D-52CsŵAp@.k+> <9yQ7O47B2Sh/mj,)K) &iб"<˯ YdFm b J% >AAZVzMPcL?A}؞>GWS1A=p oE0ZH)Kư Crw ۺ޹S1*iQVNb<⸺ΙƆVFJ4šQQ~M s5:,uowގd,Ssp7>BtF_AR` ݏ3f,h:#Sq&ƾ),/25X+8`ߒ:ݝ<>?@VB9C~4E< FzFhsGGGG<+GG-^F,jEj@DsBZ6JA䨀?필=W;(8Tq6.3W0--*=`'#}uj d5 ]*=P\an pt p|s sm~eTN`ө_\EgSz"pjХ⡵w"Cr!΋'K J mgX%6 WCi6" vګYWڸp]큷tk¦iċ/6:XyҥG1y+ّܪMGཱུj-߯oZ!$ODj  Wm&?F)# &*ZW-Ñt0םi3:36X8r?;9|=Ņ?XZA]Bbn^D|TE ~F?5GGCrG!GŻG]FGFED8CA?$=p;981d6380k}-B4*G&d:#B92  SvGO߉,هI$K .j߮l9 8=џ1tu}}Ȼ4+SLÁjݽٵS̔)eW#"5,]%L ю;cDh: /5TƀjȼΖl)x<1_K߬ㅈb&5lA !)342S %$0(͗+I. 2z)4 7W:I<>w @9 B;DREh2/:,c(4%o}!62xů Z-h W/ !#c> "\|T4f6>tU]]q.{,Z2oPí6"fc\RDӸpO X OҸ*Vz̜ ⻛e.'*$N [ÌnFOXĆѤԛr!rߕG*dI96azfun|n L+Y7>}d%ɧ"f&L*>t-$0S3:69F]^@3BzCN!E j7Fl GPGgGvGGNAGCF>EO;DBY@\S>%*; 6hq% w^'ͭM9xc&LZq()  *ܑj}<)^{7ή)6"uŇ4"}ɾ# n?fOXYV(C0Ű7 Bׁ%b=u6_NPN5›8jrSl;|Ϳ!-}SppvwR׵ ~LXMd> Y`9+#ݖ'=+ . 2$5C 8A:_z6=]r?,oA+CLD(LE6K9@20@mBС_DE׉FqG=GGKGGG_yF^EvCODBfI@ >;/ߺ8&58t2#. O+r'j#T`;Absy u`bS yPe6u|׆&ZiO߰J)|+m[jXRy"&/Ə{e ]%iG"‰t MgEùQu7@>DUSņ+7ȞYj9Ms82׵|:Rp<oGOMA AAk@jBdD\(E9FbGRGGG4IGaHvFKRECQmB@c*=>8;;98v5lz1.wN*N&""mKFY_Z (Ɏ9orkKG󳜋 uU幱ܖvأ"~|q1ͭ hq\/8oُn6.zy WP ع %j߳*Yȸ.;W6h6W׃eul.)-!l.%Z+vт SVesH*BD!;|%X)%-w1+4q,8J};=ӡ$@P8BEACIqEF_GG6_GjGw=G^F3,ECA:վ{`Ɔ@io5X؜dɛV7eB}\tdg5o.޻>%6 [;,奻LM"-&H*y.$y2+g%6_9+P<>DABCAD7]6FA)GGG}G~VGyFiAE.CAI?<.:63n3/!+m'T,#gNeJ !Wm[F~xkIjу眬آqͦB d YP& 1'Z<񺼃.M3¹ϸ>;hE.@:wCEzrj'^>&Anݹ!_u,c % B.Im:j]$ i=wg# ':,03TJ7d.z:\=^?s&BsDEdF+GGG ˚GXfF@vE8dTDBmU@=7:7Éc4\0(,Cw([$+hh欄퉮¡Z"~ JJ];jkR쨱Twg ݡ<ԐZо"AVjd";H*R޲5@on\W EW|=Zm ss!H LW  ^vLAG&%gL;Ġڄ)֠\z=$ƗIz:~xZ׺kQB·#YR3LG \9m <*ؙlȍ˃q[X>挜R' iXDʴix)y; RD(ItXA w$-)c-u1!̕5 93+<>IgA9yCk*EzwF^GGaGHGrbFUE(MDWfB@z=}:.*7 3И/=/e+6&TF"Nh2_kP2, yđbΪ=}uXv/~HjI0r611s ;XiĢflZ$A){Y-1H5i9sB) !%bK ;E]q3X (U73Ps SWD'We녽LS=n/4V|0ɜ1P'>$2Qz (Fnd֜gbr}Pc:Ξɾ p4חʙKq8}4miw3  K cN Y!$\1& *)/<3#7p:4=T<@Bt{}DFGG|GkG GS"F"DBS@ n=e:,J7WdS3=/*c;&}P]!!J1 QI** E ];@>$[Sf6ܫփ21Ne\ϚQ4yͷEWx"\G]E%/i+[[:Hd-ZXȳ],bKl/ٰe(m˷C`䨤NoY k \Ռ$R)-2I5A9#;y4gYm@L&dz=>"R^XzM"*DDCÞWֽĻ_# oJB3@xEQ󾻐rѽSc?'+EʻS΂qҺlcDUܭĄ& t25"ַx e '(YΧWo$)'d].Zj2ѫ69K:'=X^@~BvD~?F\KG"G'GْG̶FebE֗CHZA>ٔ; 8i94ƀ0sy+J&B6!@QU T }Gh`'{M≖{-V7(ˇUZ36Y$;{.$V J$PO7R@ &ƽPHEƺo鿐^?Ӽh^ܕ"4ϞF+7|q4 Y;_6_'!ЦN&=3+/-47;;>`A$ C-qEqFzGG)GԞ3GF d}D9lBs?lД(կd4 nQm䫶≮B~Za@< % r*h/ 37k;¿> AebCwEF*G_GsG!FEGCA A>3$;k83Z/B*J%AO 84_0>o{Lj~S:/h*)ԼЯ՚rǍ@BXڻ M3\.aVB vTV1|ݿ#J~ @3j˚$ PRv LtX~6"G (K -051#5-9Y=P[@BDuF7 wG~G%Gr IGzA)FՃD[BAT?C<9j50+=&X!`!dp ~[\1(6$@ip txԤ ˝ւwc}θ'n> %yq򺠹~'¤qŞrɹ2N(%WLb*#J/3m7I;pF>APDMEwGDGGG F(E=[&C7@؇= !:!261|-ZY (&i"q=$* Z ZVS G񭛯?@X Jlڗ/ժGw4wzxSKܺG?¸!=(1En85N ]% ޸_w^Ttiô~T'`o l ;I֮7Om3.ù)b$(0' a65sw2tbACbEJGG{GRGZGQF. E;BY@4=]9?u5y>0+&?!$AN+7mu0ɢ苝_Tׄ(҆|[ͫȨ3%kiB{"2vuav4 ..AaݿrƳ¤=ԉƍ߭{ uYs_^  }1;ikn3$]n) .f3=7Y;&?~BWD ~FKG;GkG/DUG*FMlDPBtD?;VC83&.)oO$*$z;t> &VwMXBho@匱Iߟl73[k%hfͺ~=I[gwIWt%GۘCwm7X’h3ʜ#sZ8pxލRGif3Xmؾx #R7P-($]))I._3a8R;Z?z6BsD@F7dGG*G62Gz{ED{AK>!;37(ۢ2-į2إBA6ȶ,ѥ-#(ܽ'X藻aG>m7 26gwYt#(~- 28i7m;a>n{A.LD&bFQGSGsG>GެE DA>x;7|2aG- !(ig"ebAM." 3`íGrA+Ѐۓ];Кyɫǿ PCV|52yNui8Ww耼q!OS!eLb%3d)G1"3; _PD0af RBWN~ \&r+ 1&5:<=U@CHEG/GG\|GaF&ݧDSBDh?2;OL73k3v.)]#k>Q - cTwQ7A`k[ ajbS ̖ ƃõ#?0aNCs.kCHE4z(1&+м½?pÑπ51RLMJ!̟5H ehW8`TRLXmz"M(_-b'2Ak7| ;?B}DrGFpGGUGT G ]E{C@L=kr95߷0,zx+n%g͏ ^ *79^. Jݓw|b(! penkлoԐzH v/"j^}-ukM.erϓC)ڥW)u0\s pOS9w"(36. G3~_7;?tBDF~GGwGF9E+C/@'<8;G4I/) $'xz$ !")h5aQc {0ZՐգQ+D27\J5F4s?[ p5'w }m8hT!|'zhX~h]AD *Co!q'-v L28 7KE;>fB*~DPPFcyGGiGHzFVaE2Ca@."<8Tl4hld/ ) $S TĶB,ڙ jsϾʁ<}L3¼E=9/ϸS#V&ĸtiƾ »(WʍFϤz(M|چY <ӵ( Ym6$*k(/oE4s69~5=@ iCqJEG%GLGkZGC3F$DAQ>}:H6/1{+,%S[AW Hrj<334z6-iqv]˨|LZgfi_'m.6jJ_:ʃ3]զ yCM&] ;9gL QF*=$*Jv[0*b5v9=+A:*CwEuBG*G\G@GE CF@J=A94b/lb)6#B  ([m9Be/”uڽF\n޵2DS~V? @rd0BwEML͔ҹ*k-A]2vnj(R'gU) AcDIgFwGuAG4GFIDeB@?v;-7G2,v&+2` qa/ ?jp9'-2Ώ炒 ᖝaRXߨwc/v,w/f yAQX`޹?wJZШqhٲ^ Hy#o8@I0y v$47f%(^+*l1!d}6:*>BIBDA%FGnGJrGwFDB><:$R67:1p=+%wPG G3 b3sa`v PSu1ipةCW^Q hEm/kV̺7"+p7 >|L 'վM]Nl%nР{6oK騅D_޿n!K p څ&#[i))):n>>!A\DSFމG?]GJ$G F D: B>q: 60R+RW$1BOgzR+B=NYrVGݜilUg~./H71p[ ?ɴjΓ5! Ruv2z Ke3"(C.u4O9zI= @CܩEVXGRGG/F1 EBRK?w0[;76ϑ1+j%~㿻L u4*\늈=ulK2'P((uJfzԾ`[L0\4KXн1(2Jyɠ:01H/X۟!bq+S>_n#Ò;b#.8*~!0s5I: k>)A?%D.3|FGKGGBFr>7D KhA=١9R|4 G/F)"M_ Q1vbO@e: HMΡ=ȍs9ĉOeGo:&P_h۸Xkdļ\߿ӴP8V]ӻOK5zP,u<g .inU"X(.^z4Ll9$?=NA(D*G:&5ho/})%#>z|7E $^>:s.bX5āW3lúݼ[yjḇ%yu&/oj\Haζ@9rn+TݡWG ,dE$C*0 6p:K>]BDQKF^G}GEGE%xC{a@<8U2Q -&Cz Nwsd J[z;S X+Kn6[= {<\VhrM"E䚸Ì;(V?|C٦efؠ&mnqDm` *T 3m{IX"ps)//Տ$5:X>tAwՠDXF!ZGdG׍dGpwEMC'@8DB*D3FGG9*G0EBCJ?1;46v1e+%$ixWM/WN+v#45zۏ̷ `ܹ^ao $lfػҾuR#Ǭ1_̐=b`'|d `aV*RN:elY$nB-+dL1c6;G?_C E}-GtGxGM7FDTBE> ,:5x`/w);"2e@ ŗؒC;ݥ:bbJw$JFZݺ+$& tڊT_ŕ_ ʐxς0չiU_m]ikjl J#<.5")l/-5D:5Ӡ>3BDF`GG~GKbEB%a?:*;36R"0L*C#/Ds _vgHBhݥ19Jgx& z) lZGtw"ʩO*֗}ݴQ䤞ΰwF  9S|"ܪ)0/05 ::-7??BXQEk9GG'YGeFD3%B>Z:Uo40%/>(!NDg ~kq`L%:zTM wMv1ȣSiO(+]P5X&I+ [-xCǩʥ̙A)Sُtu> 0BEFfGl}GaF@vDrAN.>R94Cg->'8k=e/#dM('60?MA2U|#O6Һ:W38H7QT9Y4n8(.N_Q'nզ1d) TL޸=Q.UG/ʳUEoca $kiV8ésΫg6.gN1<>%.,F v {p5%q,328|=}ADZQF]GGFnE;D(Bv<9?G4Y-v &Gez8T6.=4w[֢7n(t}g@Rtzq2}rn  'TԸa@# ɝ=˛0Ei3 tu\ %'N.4W:>)BDHpE4GhGeG>[F)` D5@B EW"SGG_GwEeZCٲ?&;-5I*/( ;a 0.o2nA7D;۔o20Dz_jeo; J6W!j xgb'D H#`]Sj<X[a"Iȣ)O0B62<Ǣ@BDsF2GG$F&DIpA+g=8+2j+.e$ b>) 9>*_)}ҩŐZ<ʹ~͟qy߹ѧev ͸c٤tg}s6+Ӫ͌M ޵Y}(+I tNs'ϰ.&5:@m?CCEGfG&LGEB>d93hA-?%9}j` 59 j(. 63L>X7ǼK|| ^h^WQn.̊.WE$(E_1Ǎe-xѠY J'.Y5I;)?mC0FF&GG4 3G#9MEeLB>>W19#;3cs,$-uXWOz Sbm@VZZŒD߲qשYCl{KĹ0!\I&Q{HW''HlԬ3l[GAO1SJZf`BZ"̱*""16xe7.<*AƂD BF-GGF?D'@N< C6}0g[Z)!3r/m.H8+9e%p۶ ӹB$$)p~'˸ǹpRՀS~΅!&iĬˏ!D3 +SQ R'P.EF5 V;? ہC-#FנGGZGE!Aú=pG8l[2 b+Ί#§p r,T[GjJ0ݴm$;]λȇpsv.% 'JB9࿜gE_w/>/ɵ=܉-&C* V'tZ&6=.4<:1?obCC|FGfGG*E_AN=r8T@279+z#,&1^)!H Su S=܇Ի,XTK ߸} 7h0S.g=D_[ل*S4X=   >(/@d6<@P".Dx#FGG F[QDST@oA?<&6(0( Q]U'N{PFIa<O>iŗBEEiGxGKTGHyE1qBI>k9p2A%+@$ 6Mq-IJk4T0~AG\!Lԧ 8hD.3;DY"s̨nG+gd젦 UFP#T*2f8ҿ=ղ B6ER3GsOGUGaKEtBP>d9"3r,R%Ph\ &YѼvN}D" 4jl0T^Y>Ÿ4S>R*=be24?_4a vf~ #+2a8t3>8jB<{E2XG7GO ^Gl>EtxBE>&8j2v+@W#(X*)CdGԶB+Bۙpdz4>V$ $%v,xa(*ڸLD9* }*!i1vx2 ø,bk&.4:?CUF+GFGvF6nD @4<%0x6x_/s@(  c82`Ȃc;t d>Ϻ;ɇv羪ai< -OD!̹uℼmKu݄@ K5)➈0 'MZA#%C+ 2nU87>wBaEtdGGJGWE*B=n`8Hv1Mɛ*" "9E '{R7fvsʮĊI޿8E3)ҭe.f}r\Z;$lUH,(b,Ffy;8"[*1;8>=DB2QEHGGЏbGE4:fB!>@8Y?2*p",d*CRf ۣčgo+:1肹09!翫!1<>6H!f6t6U`#u+2$9 K>ڿBTErG'uG!GEsA" =j7ݿ0*2)k =c=a@3 ky~'6ms3_>SiC8/ w2h2ihƚ)*|f܃]G|3.Wq 8$&{.w5Jy;Cf@%DPFGղG4XF|ΥCtڵ?f:r@n49@K-S%  ~ U>o5_X۟>E<{q}Ӓ0D=6[KíĻ$D9inl$lњGᦇ`~8,p|#+)3짍9Q> CECGGlFlD=AO5@BE wG>3GG\DM6AoruKA &#I,23E9b6?%UCn.FGG:@F10Db@\;iS85=. &O*W }w 7C@ c2#njt&(k94k!,w x^Um;JpWC z 3%i.'i /:6<$@FD$F޾G0GFEuB8X>JC8(2Л*;&" ‹ej'WGB!ֆCb*]Tbҽ1NbXӸ*|ȃ;ðo%{hy٧P~GR#j,"3" :fW?vC+IFJGGt\FC?i9:g4y-$i!v"XGY\'^*ɪ 8P׾3:Q Fd3aǰq2^֪["~񵶾bMKm"*T2%9 ޭ>(BFhGG[GNF->DkSd@pOI;{5-y%%J `lA?;:k -ٙ j5]E~ ągVۦI2Җ΢QjZ@RA`dBfRV¸J~#+73V9X ?pWC8JV8{z1+)W  ʘ;ۑd܊65Ԙ̾.f!&l˚E057CePn/Zqt Ss71 t>*'Bqlg!s *V18V!h>OB+/E;GuG>Fj D8\)@W:{{x4,ʙ$'t Y{dɇ|a{ pV<םq@ϥ{?s]3MTjV~" uq2=.W6 X=ik/'?R݂ :x7'Me/uX73 =ggAqWEaDaG/GGD>A׎<`5t. ?&m2vG G׹7zɅ_]!:-Ý0Cºs`-ظ;e[ɾׅ:WьB+A{Xph8wB .E'/6E|K;jZѱeHⰒdl g-^G(׀07 =B EmQGf3GˮFC?SW:E3+'#C@F|czIuu<,=kO:/׺P{c"%2&{"c,B,.F[|Oxs_]*v PPF+x  xd‰2 Lı":+tH3d:}??DFШGcG1EyB^ =Y6E/&8cB`8YO5btTJKmP6ξ B4ⲼY-(C?zMN*u 60g1ơIA8 H&œU'SdT0^7G=cB`E{GDGyFCh?BF902')P Hm Ù Zr ]ُЭAbBHtqPw)K\DCfYKń̚ӽ޽L4;-j0@$%2t.6o<_:AQEanGGF.;D@&jy:3C+"QPGpkWfq?ޫڵr{4ʇò}ʺ^ǝ,* ߶ VRο` 7AɁJNd#q&@~}յO%.a5:X<.AAt3fG:GFDD1{@|:3z+Pk"ߖrF4BǶrGڂ ɶ[W=*nScyM5aN;$͎̠&!K}2軌 b / Pk&8/6f3=(S0BkE [GG5F ҥC-1?oO9Z 2) , D<jP6 1ȣ5Qò@2ƹS$;.G'7ȡ5߭X]w < uk)]1-9]G?C;ăFGOG1qED9B8=6O)/7m&*ыD`w*@2je\oʿSb'$~U^@>t%\F3V4yD0$H-5s/E2Ls*_*!Jp B`iC fd?>9,U ֹv6>e﹫>8Bb>h<w|Bff3 ^!*"@3.6T:d@sLD\F[GW%PG6E*AX&;L4,#9?LFmt2s5pn-ѵ(&>g6Vg6khJuDhvB &uΡ֟z]|mfޓ\ l> M0)"2Nl9q^?N[CV2FGxzGRXEXA/6|veҗ^$N]Qq_R{ځ >u )_29?pCFGcfGj*E7KA g;5-,$N#j<[E 4nL٬Aј>B ݧVC( P*8H(& m!չ $lކ Z:-["Jī+j3]):5 @9D3GOGem GȬiD'@8 _:&23n*pHb!+cg W?a(Ꮒ_Aʹ7Ǽ-q`=lg> x2Oegfʈs9YÖ>SD[gkc&% K.|6oI=_8aB>EG.G,2F;Bb=Ζ7T/c&'@>@Vo!\`TS#˩7k|5Ӻo[K C,oøck?dl?E>TC6* BTL!*<3!t:A@@DGfGJGNDNH@a{:D3*bO!f1w$ p2μCY;%3 hd]P+mPؒIzA݉z Mt'1 7)(IR0w8Ĺ>tC FGMGdEA%<3A5-#NJfVQu؁Z#ȒE߼ L "ZYbcb7MKlp{;w,\ҽw@i3j=ϲߠF&C/T%7O>XB CFkGjçGE B<5i- ӟ$5{n4Wc㍇gk^Zo0& nʼ@,(iYnOMØʹ|B)̈] &5̊i&u./70>1HC0\F)GfGEAMc<^}5C-7#oIHًs5Ȑ패c+rؔB}!e`*t!yoQ, 7{ܨeBky!{x^+e+0H  "+Z44a;AmEHlGGQFbwC>}k8^0|'P>33b"ef >(d1(ս!. J5)򹍺s7b:zڍ SOu8 B3d&z07Dq>8UCx̄F@G|G~>E>A;k4"+L" VK?O%ֳ^fs|Kݿ{ظyػ"]f*c6;׺nJW؎ S y#!,_5b(Z8: 0&K'0O-myQ'QGVݹMȓ tIwڬg^İXCO3ԍdBLv y" B*Bq39z:@VD)3`GGʤFaC[> 8!0D8&\r=)܈!%3| mǼc⇸ֺe*=R:M\@ u!1W+(A4T;IAQEձGGZFBBܐ=7%.%)]t2@0W탯]*#-$G g&/e=dָ!фH)Z CzFTm~A$(-l46'=}B\F=GҨGnEZ}A!E-b%(WR\t<ݺs W=߼4+CЀ`X=荙)P ww(hHD1!9l{?%DGpG Gb7D?A!A9g1ʂ>(nPq̴Y=f{kVռ󪄹b;Ht*߼H3u@Rv~c$^ :d#!-ܩ5B57.3V%Eh[us}P()> I65\4ܿ_SM OG1^ojX1ȡHД2ZIˍ Fܗ Ј`A(1o>h9}n?5`DK#G xGF $C>.U860I&6SIMtogl)'؟4qVJv븘$3~_evÆj!Z'Z1Q9_?]?D{GDG;SFCS?1m8I0f&CwMQ<SEN^(EͪGENpٸ.F2; )@!?r A;icW``iG~(@19k@HDEG=Gg%FuiCOPO>}7-$/`}%~eob& ocZBwhaWAdP]h"[홹R\^³Fb)ٵl/"N7W  * 30ni;OTA"pEQ GG@FIBW< s5,I"Eul& 2P=HZi6 {cؽ6 3tY9~y ) ;>)\قVk$ ?.Q6j=(C|FbG]GDDS@ :%2w(henEFCZ:'R:gqqǵUW&Mǂ ? RΊa q[zxZ{e)2{:Z@ ExGGJF.B;A=6^-d2c#rhu 3Q6հ'ʫ{à~н.U/IbȾxpģ+܀\;?`./;3p%XV/H>7跙>CfF˸G7G.0/DY?48*{0&I&MW` ?쮭@EZTq͑iT-f8ùgB‚S72ݧ.E> $ U"XL-5=EBgEFazG[vG/DM@G:V2m(h*bTQP sqP)GrOƸۦ I]0 D $gUos -0yi!+4+gBF GԍG1E,@3:⏪2gD)rD0C`&(82>lؚΙh|aT5d{`Ʌe3K^gձ|%D% W2#Z->316Mt=B uF^]GQGlD?la9?(1҄'M "f^ kqutA487`XG4* r}wԃy@ߚb'0^%L/hI8ܼ?DG/\GF{C8>~"7n.#o]$:WZ ViA;W"DoO*'H᥹cG~b)B8(q+NOx82l)@T)F3 r);MAW?E2G8GlE|AO;) 3X*)80^+{"~  Iϗt]#l$;>?2eU ͕$zf.O7 >ռCMFGIFe Cfenrir-1.5.1/config/sound/default-wav/Announce.wav000066400000000000000000003077101317357605400221270ustar00rootroot00000000000000RIFFWAVEfmt (D 8qfactBdatax &"HBzp΂=#v@%F}+J"Kx ^6nNP3C13\Ƶl+4(iQEUOF GB-ʐ_u &&V*)V +  R)pUQW,oH÷6Fٝˍf(?IFcJC$B4SfȊ358$RQU`z<ۧfaRU6d5l2[fd%Z*JA~FkKICa9ٌ8FX|Ys(%D{@'ڞُPT?)> bƖsm',.uWWK ݐ n=0Hg|Ū Z>\]+X)e#U$ ށAZCW;Q-PӚ4RC3'p,TYYYo%[>wO*QDaB G׵4bћ6{=@VSTR%_M_po+W>Z.].A)EzΜٛfKOUFRFZ}|{er'+[e8] ;@a٩KIHi ~3W[U5Xv2ͣߗ+NPթ; >yVþWKvGv'su4'?Z\ Hwʜ@J0;z8K)Oi8KkJޚ$5Ż[}a,r)26d.&Q"SZEpBs㲜_Wfnj`/}6\_{ ˮu2xj\b2-3ɘ:މ'CJUĕV+âIGK)ü3=\ `c4`-9&l!RXtAIKIHKL,I50`*@=H5WW7K@ۨi[x|\`+6M37֠CP_XIIA0 پj`'/D ]`e*$LkIsWY_ȃ9L6Pvg;^CS-[[m> h9b>࿵d4!%+Ӣ_zd%w Q([)램< OC VDnQOk}490= ѐD9{C :Z&]ӓ bAխZKZX^?YC<տ/1ɛ$!K_wT}OPKHƨa/s+^ u(c|]a($[R¦ -V^H^?Q>ܲٴ7˜g^avc4"=ƮZ]Q pǯ/崷g!]Zb~+n)*bȊ۟IH PiTOUkK&GVȗ51:p[Ta*Z;jhQ JۜkGohuU6]23DdLCpݟԜcSuKtDYORPVVi [Eq1!~]pc0,lk}pgT*@MSb ]@EDڭУ)=t.8h\aCFJ}Ű w\d3]-1΀x(ftᑩdDWMpVɿXo|*QŎ$+>~6Zv\b3'Eر mu3MN QrZI J@VVS+)B ۰?fJU1[fW>\ c_tY[M]d851ϝi3ͥM9iY"HKblk=Ņ7&o0\Hgd"tCM DWbsG98\ltl.&Ҵ)² kDTV#a. =V;d:}AsϳjdhMI$VaNR( ֻ֫9|!v,\Fde'<#)E'绫}M Ua_U>r?oEu ƛ%#)/6eDCaY `:gg~'Ze0v*)T( "O'gGTAPTi!˹?pF$2>YYlb#ݐp! @iϩŽ S(9`XB{2C^jӟ?=R nDR P،W5H],lr$y$wZ!-e.5k,:[IE&~rR"`yDGYsۈ$}n"7a/RL<`=[/d< C>GtDQw{Y~e91i1 [Nĭ E]8:BOTd=ZWTe:ƞ,r!8xYackæ Ůǧ)JjP0]G5I23.^uzWl?LS_u[ " _һXOUd{54!S /jhJN[G Lfʮ̫fNc<)J5~ZAdgKFMT JVud/68|V^˞ޡ<]J0V]I1մW} § l%0zYRueH"ONLѭi3iKvYWJ.O*_ qi'خ9a$GT^ ٲ*z<4 nT9b,9:/P HDIWdJQNj'hJO"-ϲY e%#|F+Ĩ eUncHPf_?E^{5ԙD51H>]Wb/f߫d습ػ ]! VVLeײ-כ/2REJȆB"Q[PY^ӭ1̉a-X9i.VDdcױz%˥5aXcNRC]]BIXH-U^mOU8G>@L\N/Z]&NLKݝuUc^03v{аG-^ML [kBKlI2 >R'*6xVcȿ)VܯMT?d17-G{ˋѮ̟2oشl:CcQa kɑ彧_! UQ`~7k@ ߮AF7HcU@,GRTjNj[Y l"FR)4rTpc""'I7l/ҁ onRM`7=SARꡰLq4I8?RM`_ ~ @H'-5b$Ud<$+3|ÐqpCPI>>K&L^YdwN+-4FTcl K%M1JY*@_K&} ࠖd/|ݹ @-KëM}[e0wUMW^TÚ8h1RP@bo /DC6RpšYMcB[ۇA~MS ,[`ɝ)E2fTcW!f!V4ŷT&cm0I: ׾~w.oߺ@:'9FI;Our]PP=ҥ$e3`&-0UdT#p IJG"VD Q-F햙b˞-U:DkP_9 -W-d0PI~`5>ל)dnyzH6VxE3S+6thHW!]"^*RSc;C!5O&K/dgU e SQa5@'sײz9gت4?xP1y_O N Wiϸ' '!& UEdF#:*Y"Y>#DQGTMt閯\7'4*>*Rloa@DZ8仏䭏ɡ 3Nm]/:Cʱ g-jDPUOI>W Y>=X39"Sj.GH8VBN@OM'WݫցR;=EO$^M8U0@wrԾ*ۊÃ$Q8_`^E3v b;(R00 mOVֽW>K&QIVmγ"Őј-dh5pQua׶9Z6Q)!J#Yp®KïY>p:K*+($ PWʛ)12QwaBj/5b36SR|Xb*.d7VzMb Z:FCLZmV7kʻ+'.,SNcXM|ŢHCSH>V1AMdέ| i6:~ qJ!ӏ&S2c ]'ɳK_aDˈQzE8RB!AV},L4='UPn_ 7jު{ mM#\6@rӎ㞨}L\tDPP'GT)c/ݳѤvͽ4ۇ#'-Ra8)$_i*9ѳgrj\t{I@LHx`)e1)c#n_BL;Yp=ḬÉ1HBǠS ԫTR+)[3Q ` Ͷ7odmRsa,g5:\ఠiҽ;KGrKYI!pۦ~(\/R"'bj9lĘڵHV"@ LY繩]ީױ#;E_M5"\Pel {ڿ"56P`/8aC?Isw,I`V9XB'9O*>f%,Rfb* $L ^Q`2<ګJB/afu7lDBKN]dzz-+ԝ.d"'&TcK &܄ϲlJESwEARRwOBjY<5'?P_& a BN+NS J Os^6ç@&O蠥E R`GVUF@oiQE%BStcu#) _^w+O/^:9PjD; ۨ׮O/f]2g<Q(a^ M\AiH(1T+c&׳.P >԰Y; ~y=AfNI*9WB=`})[v/v7WRxa- Q!%LN AMj[;Fߍ~@Ik{(x@K6JXN'bİjߵR.b*1Τz졯$L:Z=%I02L]&Y6,m4RaO:ޯ.sND+R a,+5Oٯ﫠S,<7=H~8LZk6gOd("/PRaM4ŵÞdIV@0K#zZoxJ:x4ELZ#lsw\(rPT_$F/+7ҠH֯cBGRXHDUtLAM긱ۢ2Rh&-!RIa,& jm(ê+ ; {P_17;' ͨ7|AZM\Y,錧%U'"'RVa2q$;Zp(E,RCO)ꂢ؟A>w5 >ANB] q rZ khR N7]4{ >ؚUM~z}D7PYE RgzszXH= -&Q@`q:!fB'?IĻl\nGNZj\6s@^0B`"܌Q2S<5O;(^E a y 骷.Sdt! #R@a|$ޖ+) ABύN9GsuTkl^򙅯 8/lL8P4_I5+NW;$`WayLM[2]9"D*a Gf@ ILbIVfUo#ϥLdЖs+Ra C'd.ʝ⭱p dwLsZ!)<{GR0= .6_Q1`Zq4|R׏cRYa*3S~sv%C^>JЁJX,W kI]cuT)f1U[Ra? `Bz,JU~X >HId{Or'!-I  `LiQ[`o0=9֪oϣFL㮣1H:%E;M [5& +Ϥk#5*VSob."\3ޣ7j&GU vB#ONvfuyҶ6@5O ] z Ȫgۻ7{a ?1P6_N3<ղBs^oj}EZRE%pR aɡÿ!4(aSb{%-Vd^BO0O6]x7A^$H׳5'33=P6_E W} ۗܨ %s < S[5c%K,+Dʮ՟Ǿ1CgOmCHhU5Iz/8b RO-a3ü]#\M\o9dD@a֪\k@cMIGW (1}(K OR_~bm+&G-poe+?M[;>GvDޖ5ʮi/\8SQ>`Uub[/D]6F4S;b])1܅ϛ.VV6sA@LIWmNPK+~3RTb=넿n l{7gKZ<HAuXYƠ=MH+RLRZ* Qi!zhnO!R5azZ+3™Y_AJLX@L{0vuЁ9)1R7bpzvbhiqEJRar0Y9.Έ][C%;GBF*XM7\ZbUh$z<+SPc.i"N깿ʢ9fH V({BLOZ f\s5b7AO9^AKv u]QĦ -ڲP`2<PqB.FaSVE SD`˯3O"(,xSfc4>%0kM^O3_g7Aݕ ׷c{ԩ4>/`Pų_ ^th˯m:! Tc%+vK˿9C՟c(DQ!oGUPd{S$Lɒ0#:Rna#[d,7+N] 9C&zV⭧ANxJ5W\GAèj LeS=c&b-KX۽!z)^H~M) \ -bZ/ V8Rba:#+IM^+}S#c*32~2y٭,SPg5@Y6LJ8X8{?$̌ZÙ+3ESbV'<EDMȼ(IILZU=I*s Ǜt#=uILA[o ťwسR$bd+T3k̀ZhծD%!QKt_YO@LK`^,Ѝ~*7v2;Szc_ZH267RBWbw(0(9pn/]cլIi"4^QlC59T.g)E:ArQ2`351::0:zdGNUD$QwxRp%ʹ@$~H+aSc|"ʴ{q Qu`5]?Ԧg [6ZnA0PJ_t׳-a%Ε/%qTvd'#y))پZfSq~E SGoFS|?*쭮ܜdJ;̧3 =Qa3 O-h4ON zO^In7#Ap w?HJKc@Z 'p$2ʣ8X3R]b_*'2NVC幯N,KY\?lDKVt2mx|*b3aR3b',E7BTȬdRoaR.%6Sz o#X; G'LXZIƧ>ɑh޽&O.R&eb~6&v $HV] @LD\<K3.95D7M[Lt:ʷ#Y̱7*'Pd_P/+82 ;9{FM#GTFBNapL7(ô$>+QU:ab[Fhuѩ  O0^۬20<u5.6CA}M|[FQ>ԦK0R. 8&@R:axs%quKj8kD QlCoO{Ms.ݧ|+4d=N]hl O ,Aa, E *N\J4=fnIR홙FCPQPER }yl!%Qa+!,'}E8cRmM\7A%ߠٍh9;ګ[Ӂ2Wn;؋O;^}v j 㷺krUKGHRa%,P@ÆA~>gpAM@oG:Toulcqe.qȼ.o7GQ`!_J$g0L~#uF=LbZ :;Dc Ŵ\?BKIBkW- 饎raE2Q*`Ki(Ǧ/Lq8 CK'fYG=HqRƮy^nC+W3}gQg`8Oc- Qja9, 5K.ǮdLOu3$rB+URavH]!~굨&yC N VO_H3G=%ڠt"M6 @ߥN(]R䴼Sr1Mܴ%%SbX &52R13=DQEQJQ>On* ]3Qp=M-P5_ E ½-ҭڹ5#  ܸNf]*62@AQ-ì9j>v CՑP0G:T[t;Q][ |N$R9b"<){ Ɨ*)* N؉]8ڣC2#q8ѝ1-;SPK_. \̩ErLSHcj&-ě[sVI#ꌵAM H V)p~s:Ϭƅ.7Ra@U$W/e_L [:EyZ@R.@LxoJ;X(D 0>- e.oD38wC ެE#+E&?RE;SW9/\ɘ侗 t&0zRrbZ+!g'UC@SZOW_^6=7AOI!ݭTD2[<]P7_: .g 6Ҩr^mOxq ʘS mc$+mDurw<}BkNGWUyI)l&涞Ч/ 8Qab*^:E޾ dLc[@ : E `#@<M޿IW"1gJR߈ER؎;@FvLZotp9Y۳_tP `g-4d6ZЋ{Ǖ鮫߹yHVA@L\\碧ВpA'tK.QKa5关R 4'P_Z09W%BgPw܏x8DB6Lu[žOڳKH=VAb'\Bx8Q=FaW5'.ŝbL=+oK2Y ;_FE6߯)6'լy-62Q`X߭¢tDQFa)1 )!wӟ؊n>LJIXˡ>l w͊iÄ*2QaiFG WuAS+3qΥUŭ5D0w;^I@W>Kd[> ѮǷ)Ć0QMaJy>I|F˫B^P4`/08\^]Sm㴴:DLi[[MUՃMn*:#*HRaK8!œ IDGT6BN޿hc6R@N \[a/u/Ez iO^ٞ2/L<4d1U`1 ELRɟ QR >IyJX~FG>K)_1Q*`cEL3C|J! Xf=I'3Jc;,G^KYjp (ҧr tP_,fw49`]7$1X3IVC?bK@/`0"&+X`Y(/uQ`)\9ܾ3z:. =P_(%/*8 OZ} 2ݛ9^{D(LZۿ /R8pt$i +cRa8d Ӂ'3﫤RF6.TA/M'>ɘ#ۿ{H7GfAM&4\`?{=l AN]I1:yլ P۟RȥEiRXCP:IO`I# "((HQ̵`#63S0RN<0]w4 >b;M)q%;3h=N\1Y :-1VN8"ERiEaRF")ʄRwTBN2HERA﹦>"Ԍ˨09Op^R ڼXCn8ZLpZf7< B\? _S@sLZGTDmD1lsG9QR`:%t,iɃ)#K KYK:4EwޮUʟ6a5-D6O_%bE!fGYQl`[(40ЪkȈ߯]ɠC t?=,TI}H@V~.ě*>52'P_W10E3IXWN%JI#sl 3RB(z/VP_xE [pC(O^ -6^zf*+X|G9C5K˙YW~Y!֥ZL<뾚$>+QT`sMٜ蝥QdFSSy@vL#sŮwJ3I7AALFZKO6 RcN]f0T:p8ո Dς~EiR/tBO,܎V|"y) Q`0\q"\N׷G_ {OAi^(ְ<#9ELWZ\7ĶA PTCn5ڴ@LFT`+}iyɻ+ P`3$M*)mw -ڥ5BKZܑ8tC6܊KE P/ /x7yO]Et(¿ͳ#P` j&-q,AX۰7Ρ ?K?GTB_ww>y,?4O#^{,QjǿسL,'qRgJX9zDmhI=h`IH:VrNrÍPJWP_;'(q/̉\bB.JX; AGZw\X7SW~+3EP Q_J6<3sCP_* 2[һSOmMJo

`|FǶ)?Ah{"IAVI== IaBTsޞj+૧:E'KTY_GaW)BPM_`~,l4mHI LaHUXP?mKSvQU(/4Q?O`yrkhG܁թ] ݷi4>N^o]?f 0O+˨_˷4>#[RHa?!"(ӰxwCÈPLBER $`i14;~fOe^Ji fXslԘ ZMK<\B6B@غV>,#A?N`FkSDJ]HLǮʼq=#QPa"T)Z7JP(qzL [8{Bsڧb٭ѡ0!:%ORd^I 4q R3|Q`%d,!Z\Lcrż@M 0GnTmZn멡ߐ z-6O^1kzrF &巂xZK*Z9CXؔ3 >+?KHU.J̳]qk>չ.~:Q=z`W&s-ʟӲ̍ !\>KWY2:E L}ޣewV*-68P>_Rb)k,`:f+;Q h`h(M_0Q+ȏ/Qzv渌>ubJ;HӅV)3[q+Tj*20P0_(~;$ΟNZ8I W[=THwKTfaL(ʪ)29P_x0̱fDPP/_,4ԷoYK9/8:q6FJΥXc(}6%T-P_-{ĉͼ+ӦllG;U:>J߮$ خ08$C{hKfY ByCC؀%y#(O2^ g.#6 ӱWʂ С'Hd&FSx@u9LjizBq<% ,P$-`~IFy RN] 0"K9L5_䟝^7܇7 oBLZOȦ%"j(NHQń`"q!<0nC ZEKSTAM.]^ᡮ.]rڢv5^Q@ʾG/xu81N9]0]б[qVݫK!YJ7mBA&ef㦧?uKF} T(3Pф?U#T٢P_%,~pL0u-/'KdYذ9!&DB01cDЯנJ&Iy-V6OH^Yo<88 ^~P`W(\Y/|Ѡ}?硹\=I̼H>GV%@.9D\ΑE*b3`Pf_nH촞ﶾALJEX;DFB YF !ej =HI@W@dXSChJrP `:)fP1#͗Ir^J}X<G[.&QӀp+3P`vDek˸ⅻƲi#]kKQ!`D+52˹I]&cJSrm/ѕk'*,/P_xY 󿵽z1笧9nO\^-P.L6u"1N.9C1K|7Y+]m/5R̾*${O+PJ"`I\~!ͦݽFS?KQX̓-{ք^7BRK4Zs3"Mu#N]x/8-ٌOd'NKFbuSA[4M.S2Ű}/,ΖŘ$l+Q(`X Pr NV];V1c:hٔx8^_70AL[٭FWd8v)x.2!'Q\`M#i߈>^^E+rRmBN(+8gE4>MK\7p n޹8cOïX* mNkJ]2G N]֧:ܭt4 <>4N] ڶ:þZ2#KQs*a!'dצT15L-G[6/YA/$(wk *ӿ1ʴ:O]-J R ̸Lmל;D<*4Qn``$Gs+9͎Á nAWMnFASjWO/.7r[O9|^~xi`de˱V;>Y܍j`LVZI8Bڣ݂w΁"\b?KMzGUr 3[Xh"&xQq`%~,ʳ&XA%oK0Yy<:>EhYiXH.׫6PGY_5̺F2OBQٷ` (p05R;}>=HJJIV=2 5Q&J#+T3P@`Zkx[fG\KX@mA#J<1ര=EE;:CENkKYe\1ō# $}PY_,))54zZDA>zHDVI_?|K+j$5<' /C;QM`}`~pF<ʬ߶.O=_qz.7]B\şjNlu9TDJKYVBɼ$ri+ 9Q`|̳؋ȀoFYS:@_LԐ/箩{oܾվO7A] LZ)riZY@XN]0'9ԣt4ES=AjNf @1)5X,w1#) QC`Hpp!B FYb Q _N]=2 M\ Y52?D^މꮞ t2Y 652@tڭ"3,~D֚"Qb`"8)3As,~WCM[57Btڏ~Vٕѧ09Oy^ .\̻RrH`9Ram% ,Re ZX@LVG=Tt,ĉꯠ>P&.n7@P`tG4:ayWũH&L{/Z:1D޹:1OR?KHZVOI PL7ɤΏvp RaW'1/,qFǢy $LzpZ;>G6Ԟb~ժ̕,5keQ)M`c 4c޺._د0=RaG-*D2t5EMutqon >RIJQX6EP졕̦%è*h2,QQ`a:lx#&)NhGJ4Xd=Hyޡ0< HJ8/YrLt3TsP`r+3zB[@%eSIWE>TJ;1b% vN')`%1bQi`tD~P0`p,5Ԫ|ԓA p:E*qKBYǰak0&-ϕQ aĭiwOw,CGUUT?4#K&6ҭϞh s6p93C$KcZt_|]!DA#`!~O{<^.6m]Ґ ʹȯ ͷGTU@kMd?:n=Xŝ%,Q`Mwsݷm pt}PRY_0:!XдgOIn7TBrM1i[^N\]{ik)[J]$QsaS &㎿ &]8F]FC.PD9!Q*CΟ={Α3Ql<#NW] % <Σƪ㫭@X [Mj[B5A>ȝjҠCp%C|O#E[R/qIC8$/Q`"'0Ƙb%j M(\6BARX/䖮q"7tu15; On]*6 |i2 R(`a#z*g Kˆ0AAiN9paǚ$P=+Z~RaK 8]ӳʤx5F.oTIA#bMD刔DE8B~M9`\z=TL;U~O^e1~9Y&#ȸ۞&Sp'GT&BB+WO!6rt͠z|O#l*tQa 8!EWT + P_m1&<`wك}C&rٯ6AN\Eӳĥ@!&RBbh)`%°kñ>DBRpEDQ+vu/]cϧ4>Mys]`|^ ۺ,̭i p dWM\`4=׫;6{2-SDPCWQ|61z]x%P!at o&diž-#lM`\g4@9ӍX䞊VC1<xM.A2NW1EER>x0MA_K%U3(1[ : N?^g3 xپm!Y{L[Z6I@fku$mp~>Qw7BimN ESͣmȷ2Ek"cP`.w#^A)>柼gWadM\J7fBZ(ڊ ]Sus0z:IO^ O tQḣQIay$,ͯHϠs@yMHQ U,&+3v!:nѣ '0OPf2_{SG^:7$mO#_0,tU5J͗~Šj9bE6KX9YkɱYZ&W-[QRa՗Ļ&M?"G[UTn@eKn|ǝxvQ9D L[[Y0mWըjpzPOV_.4|6^VHiHU@M2~"?bλNŋ%±-nQa &YdİyA >( PG_N/C9i`farܗ;79BtKYG,GYƢ{}#x)!Q5ba5Ros!q庆صc7uESAwM]7lɴ&:ڜ?d7/=AM\a\g}Lf} N\q0B9>ˀQEcyRAXoN/>a+Ê!(*P_J!š{{#Y NAN\1;{cL!%L3u=ALLBZ޴O%o+wδ$$P _-"%O%*_snB^uOC@O(v^x֊ܓ30] .һb 44.; RxL [i4=tqumoACUOPDRu_J*zH_UP>GGc3,a4BPD_L/0ֿ&lg JMAXR;F |=x#>y]IQHjV(E){ He:P_ *d51 /˳5*K\Y:4=RBaH)f ԭ谹Fs=1SC%b9*2AF(4ycޞ&]<HJXUlXnƢ/e)0A'Q_ԵJeu1G4rU}=UHT>8^K|;79F[J&WS,}2OH ^T,BA4amgǛҡ{(I˫V>NJayʠm@@'ZJ/P _ka#o 3%P@_>-56gMi@M9DK-7YH('":Tr]%t},FQE`QU<@j@F%T ?W:J g's$<ݵE8 BIKDYJxFP_%%1M] }.E}6DӵNʜ믏nܵɨGHTpk?KK|f踦dK$v,O_Lk`7W!w㪐 YJLP_/8'@, L̝69BOM{[K! s["X)RRa.I"ԜY O|PC6QB= O/玲l ҿ6\@!M[fg!G2rX P oM]3G$=Gt 9^8muEjR 4CgPw Ӟ{1/hs%.PU` O1&mqk>)MJ\83Q>V%Mlܼ21Bhc)̟ր 0>:Nj4^f* w+xd3Q:\ap#,--êѱJ {qw|@5NFUjz O.7M5^2.{[ʩȴydIHZO9wDFˡrCL>K`JFoT>כ#]C(^;P`_(],̙\A2n\KY9B"ٯ/|nρ--h7Ru^Htn=[u.rȮMARA]&?4/2˝Kn">?HIxXXOX4G7]oe-{3KPOZ_B"ht5s8I*V;>F\ϱ*ɟޙ\=hGH9Vxy@"U[0*O_)a1DZ)]wFIWSjEQꩈ[MΣ4>hOZ^  +Ecy E HM(\)R4ٗ<BPmERtCI#QR ̃Xbj&xO W_V p%ƜTצv"NjLN/]4jP@ݟׂ<o1я<=kN]H MlNըG"@SWc ";U*4KnTFBKxPG[T_Cέ b.09aP`UPuM7KɄZ)6(@ 3tF!UTꔇ5BVLvF:T4X/Aֺ3 R `#*`<ݼ[飤SPMY:`D%BxޝJΘ=0)E7|R_Uw#ҷL)'8ﯔz~+R$_=) 00ϨǦ8Ϡ~==$HF jRP Gz* [ I } m<4q~t / 8 . |[k'JpP "#1'Q] } E@`I3~9 "[ +p Ml 5_I4A<> %Z=O{v5 ; X%~Ϡ}SW8(_K{'pW 33NMHOQap8cUtF4:kNp}!q b)Gd~{zvv l3{4+&T/fR SdCItc$oAP\0%I@y}VYd0<.>Ls#=fZLyC>Khhp9}F;Cb-zgxy3g\&'~L=A3[lC 2M-vXC1Ug@k~2)n |+CC΍1L}=UBv |q!8Z6cqk>@"4MLTi _  >VgaK=֊z 'w0dM,O'T8>6Q7˹}q[1EZuKuXa.q3\5lqaQ%[j-d;f2]z7Ni6zkEuCr=T=.)GF!`VQ0N[_"}f$dcϵ.~@DH"GOE)O d9{z~*X(m+urxU$|0ߑ#uP`*vE)r 3jRs*5 _MnIP7Xlsf|Tan%~]T+1f[͓`@7*aX"N†>d~( >419YO^,~^q1. ?hjAR:x7]!!@ lЫ]XHj=X&g` \E:)$>{%(BS2h8XH7`^=eE`;^@(; I!F adG (ik$-*-wB{+ G@,5E&D[O)3Suuf'3$m?3'`L;)B !EK]L5 Ugq`z[U]5gnV 4zynQD IZ(CÉT{+0SO?jE0YEaK`n?J>*[0?Twq&TeTG}=ggڍ((@L(k%ۑ =NxgH#L8#]qD,3D E-uhܦhldx yKQ0#e m_Q[Oaz6@LL>^3gw>K57^qf۠ (GA$a(@<2" A|D6v"tϣ`̮NJ>L ִ[Q>2}@%7m=mZX\4s!Rqo pvSq*Igie:/|h3uCf r Vѹ(q?<$ZKYq3~ȲuDNJ3nk0yCy|UR_yi3΀4 Qutr/Gq96sTc}{:4mY]fVI oG,r4Q`yg@9|z[΀[M8CB?D Inn0B^T} V! aRaMe'!& !|=UD zy UAiZdPNdv:l6AzVdF8vu'C$* MEQ` i'T1B˯'aX]T -UD9:Pi'aHeڅqphoWµiH0>iQ lf Ja;<ZI(M#/9rP`'x)||t $u/5B~UAD,xvɋC-"lSi&rӂxv8`Ǩ( KFU^VU5'](mbfE U\p`3Oj$9YAMQT {'+e b;-g0SgGsgg5j~ih3aI62|6n%tĖiPWA7 eVs$%5 aNmuCuA$cTo/.+OF˺$\tcn7,Bk ba 8LW]D2<_H>saaz DQ)/L4Gp8C- jLff xP^m"g;N,+?H-.x:T0ktw\] 4NFbag7E>èzE;hj5j1,ISYB&7r^L=:Ɨy\Fyrf|0N35-E'vyzL 2DbU|23-%!YnP 3  K%AB+ne^l|hN1A'#t"'_6#`lhи"LiĪ'b-kZ., uW]&\56Y?NO˳1 Lmx1B9*F-B"y֥N??8#"2fܵO,*B2#~`rdW/)(C/;(]F1>gdi8qB{t?,U-HFsTM ]< ,xm5$zFvT$.[.@9PvN ;6~dU\ Qx\bR(_m*1 Û#LFH!  ݗ)x($,@ ZXhQ {z* nsQmm iQ`J~S ^tw4tʫf `>U[cZ),B<s:6<k5:+lY.8D9X|g2-&zwix FO$ZcċOkO4 YRLv,'\"acՃTs&v'*"WYaW^IPzv=< 8),7$?M{H ן0&[=8]\ 'Ĭ-5ITTp6b9=2U'ST&52$xzω18jl8S4 k,-`p69wv3ʘT,mas 2wzXgX:^`  $U -6hgi!'5`LZPk ΂RN ScQ"I Ik D 5:p~q_ou{wzŤJ*E(T2/4?47ym~Y'y(=u{AwQfde_C3Js(=&1x=@lj=Er 9*Y.-HCJen s|ٓі[X0^k( @gkz\2$iXOTXq eh1gosT.Q)SOw|Zo*% ԖAƸ GL|>T6Z >`:ZI9=I}xS^AqCɤnrdt64c>NPs ts͘ 89AOUBNC̟,cbԬv __|jirCq~|`LKi}''?onJ{zbÔz\g gqYZLQ#Q&JKst2122SQRtdthj$tu&jk`b_6gJ k"OJO;>;gnnkz\->HWG{+ze=;{+31PU}rE D\sb`0iqwpFpUT8DDqu,xrUUppntt^<=c  c $%A"c#qrҭrrmc } rryc< /~&ou>lsE$i$c5؅| 4 l~h4hc 22Wdc[)ee'l'G(r(Ԡ+CB769>q>sEFAx7x QS6\Iqmmt(W]RZT3$K8hvxl=pM3N;:]]_6 FtOu`(>UTC@?\[ν0VQUhIf5wա-)$@",*K:ozxSR"LLŪr/4c^d_ji~Ydc1!/:g:|}/Dq75j&P&}}r6j3@>y)l'eeSaQ20QQQD54j\?<~2yLw5;2A:9Rj53ϾZ4jQhKN3//:d8~I}j.TJH MQO<Q][]۵D 645\on6)'Xbd'J&<\Z%N# : Q$#܅9NTDCrLȾbO$MY1a`<:XbrpGU<~}Wc`;A9A>!w$~!RP^{]Ą/ 0ҿXbWyMcaMK4Z`i[]Y@=?Bٳy91i1g3?VVx!s <=>~[L?21Hsq3pogbg YXAQB]]sY%%aam>oA   MSM{#,8$}rq|b|p[\SgT*+} Sh&'(WW,lͲ;><n$nLM:Vf v/vY+  Ǣȡd))%QPvLwsooPo|mPY{EFa a1zR{ZZ3M1aa] (}Y|Tfqdw}{ηpA!QRZ% M*Nmol=;KI IVӓ/9/YVQOQttJdH89N"s:=I<X^OM,(HEbIb`\us8iuisLݧm+{` `!r!N#?e|)H! T^^}ea w3un\\@*gOO\(('pq`W'">u>h/k(YUT48:7p]i)g??*Y)"VLSǿ1MmlMM]M NrFKI$oBuH4I*$ %KK JI 6zKz<A= f ||6 EE*9U_`##&̈&$bn!!(0){2/Mq>q9A NLN+abP@PNv!UVpm-{7vv,|XZZ1AXHX |p79zͷ,vsW!~TuT!{A&'9`8g#$*vCCWd`b okm/7|6$'"##$Cz?[10!%#Uk1n$($%$7s D =1.Y_/0 " \ -\YG :]]}ۉz'Y24uwx{Kducy00`|le/0oPPL2z}}$Wd1 )=|{WN&Nx= >P*ю0H\*jP?'YXWLKJWbk5v v8MZ)7 / .??.z;9a J~J H\z[$ . .33YY2lE}X wYQ[EsbdQR-jvv/3mg̫ 5h4 (F5ES#@ml]vop"!: <<{ YX@!6wvX4X" RtRA N~2}w ѢM>?h0UnU  /K._po)>:Cfe4<,= ee A4Shj``MP|B`{!_ AY9X)'|=  ޅ93[\Ah;iDiyGFaV:P:܆0k!t ݹba2oo"~NN +lloCC 09;4D4ι[ZVX@yxUUeUSC DO87AnuWLL1hA//=D;9C9&[7[99eqe|GF-M$65X"!}};kjy  0$#ݠ6l.V0H.H)6D81&/W> rr5U<j=T*:' ӒH+->=R^\Wgg ^7}3m'c'bkel !yJoI[$$ R x67kKfe~+8}2B~ i hIA4n4N3W6"dh8Fcx©[)K$ITCD^:G4 jbq r#!;p?GJ les;g%g8%,êénATTVyPw{^zIx)853l#?% -dPMplk#qWq*7*J5EƗ ptQN**ɔu~{|[N:;sY<\`vv9(:rtn*(:5_sqt`߼h{xN;=³ڠR,*Ќ=I D]^Zcd[o?~\} )-F,š&&wj+upvAnkl.EFGU86 A5vi ba c [Z xy#;=ÇY|yJ: : h Rts WU/ZGMK,y{75! vdvXacD!j hg0ss%s% } TkO13 Q%'Š:^uvi|b=bEϹt&, A5AG[liw !!"'4fpe |`ai}0ߓ>VgfnK׭s04@;j]XpX)5x:yf'ǟd(-NLIQDD831(k&mģy75&H-rpqp3v*|v~SzU|Fh n7)-âEY g~HnkrA~~9h88DDVF?"K2 #|`h 6TxS&$&## %WihO_z_b%Ww1w!h?f4b6l6? dso}17SL9UY OZLG+*5}\|QFkTUWY;V\ZU g8 5xjl;9 !plrtr=FH {! m~nqRHwHm)EF|lnf!#gogo~.)=?B;7]\dC>k">$P`XUWtP?XOQ#c_1Y-OZ7s0k_R%L !WZN`/`0"+r7@DMkp?\E9pE&(]XD_^{`^,)P:YeVgaa*0Le<L7Z[>@  "G:OlY^>!h!aa aG*E[[=^;ow 3/.3Y1]X4Z" Xa[^\@@&"I"AHco4LOj IEmpm`^n=8' &;g6fsiNrI6PC;@fa?OTM -e*'CY6Z_t]/3b * A778uRJ$BZ; :(//P,UB:Ete,1nMTJUM*(G(8o;\aZ>D@ %$N HDRDQ\ ^CAK}S_Z.0P43%*.zJKC?6 !DMRW,+!G@ME8Z1#h:q8^bIU"'SGUJI@Cd/(,/,IP[`LF('/"ICEYX\KzLq377,.8CCEiqPquIB1".2[2ZjhTT933,&&BIiw%~7|Sy8?7J+4[mLosWM7/i3/\PRQ{ow^g &):;kpmfg41I$(QYkWtF P  S D*$GkfjPm @&9B9g,^A<pm*g$f _O Tk @HUNM.!Gx3H3OVa7D@U +QLIFt}nC=;[Aa(00FJF5E8Cl?zBDNX"l:8{KKK(.W&>S-Sd aJQ> JNJdOA^/>:XH7dc@O9&LWFH+T*($ LHae4=bJ W:::YQ?;/$3%T'^sXZi^#q&^u >p?`VG%: 9<O%B5F7QFB SS%i8?92 = ^LS9V7BGx'V){g% ^;7+X-iz>%XE?HNI(&_!0 501IRH;<$/',!l"6;RWG~H "+:5fPNuBD*W-k%q&53rQKGF_HX.:6LHI)6;%$:Q6QOI=?D_4#D#@AGL*A C')9(.(QIS=\2}Ga \ 9b1l\VFMXS.&;k$'68.WNmY[Z9EJ" |_?<23\XhWfS9g4D(=( 96\QLOF*M`"0 6D6NfJI~J+4]";4{YWJuQ$B o_IG,8Y@KGE,/3!,F)1Ao@AG@R J#U$?7@D7t5, f$/.=HA@G//b>6JN{B/-nc&5$.H@10 4'5{@;t13 L.U2:,1 +Y/E- 2)n7'r!!F  FE2)' xH>?]$! -Uz"y y"(n ul  :AfD$uOX%c/N ]R>-3R{0G3y!wguPmpxP IdXesiͽx}t\SsQ>?O?>"+o &WOt2~ IGcA BM1V;z7*oZM5c ,|l?6 D,CG    Zp#!M yS9!#17m8 >%!T,7#53M)$+# ";>7\0 "d !!@(075)P(l.5^2<_G-/?A>?,<%`+/BGM>PRO67J<;PLL4EuB,k+~'$>6=TTEGE"%=P:5PpGD 8'&|O-/7=B<P;&#-%' 331/%"" J(0*18674+<#!2&o3 1',419-[+3/D645o4}.374!0'EtFuECgCN=h;[;{.7c73CDL47n!S #$;;xWnWZRtI<5e9L-4?=cPGgOk:7"$B?R>VERY.M3^! *&7L@^J,A?;$+n&V 0-5HB ?u8D!-Q,=Ar5= p /h,+<g6%& \t2/3>bAq,#/ c Z2w387:2!5#+-3 dVN+(*'4 0P }j%$%T% W 0H//-)c %[ .*09p.*!LFK>d3""F]E;g"quCj!#%\t ?#.4+J$MD-4 =D4=/=pv ),%.1=9Et/* 7g34=7d %:5<NEiJ.!2/oh8*-aYThSxR(9,0 (/0DI\GF0x) Q")69YMMqCfB /&680BR33N!o wZ-5(w<>S,1( .@2"+ I 17"-(p'% kG R  )0)t)hS i K$#+  9%E** auo .qRq,*-2-Z Q zQUl^/J'&<#Z b ex .1L>$#W KKlNN5c}+KZ(Rdg >b,j "+0K-@.a%% %=?,8 0)).# '{&>$4:F (E9/ 5 {5&g8;9,.]0(."%8u$  @2D8<H%mW8/f\yQBZU;<8]22f%. 8p;.ET=(?S!$g"b+JtMStZ.= /;EK6L<U?';%7C@o]-y8aMRA>$ -w8g:fM~^Jm'1i3"z?A4nusoW!6Z2$q5FXpn`dc"$8 :2$=iK5zmi\_f//41E+gW@3c+>/Hu-M YXnjjf ]S1//6\\[J G 4?vTp\W3,+8?KU_Vi>jC1$$dH)FpbuȅxrUR<o*%:b5fDPS63D>b,Di-;@@8JK!1"'M<=F850&AE/9<73x<2N8./)02KEV 7e &%". N&\x@6I"$-*YY;kJ`> 8!B'?(<),' P85^*d'" nL W87l!@q2 q aH*<8.~j<  "p}$6A4,FMS!th5 }u"u?">TMiQ+0%*_BZkTLS?M@! $F<8"t(;P1,OW0Z} lFZ%vD1;C?8p^"Kaa.@XW?;,f0QLh?NX+.3$ֽ7-{ 9"78>%F4,GBU]!u3)]8 ]u twO ('#hs#5>JMo'4Y+>(`@g,WEG_ 9A7q 0qN <&g2H",*,^ }]AeMo9MM%7R0~EL+XR (6`56R5? CdZ3S?gpfbX ?4 D ?J9B(9Kb $S-.3a cKDe+-(+@(;_;2`=I,>@%QH7r6IUCx@?>&.j yJ%  :) =YD~/ ]_&VGoWn*j!l M5yQ _i9B 1(=;[]$f%F1=caz* ="2=EkjEh>?#d3Oā W0B2(^.j ,ZQ&I{{neIsھL_+BMޙ/l؃=ӗIx7u.n0Ar]@IoE–GMj's+tuv8-kX/&R1AtL|4MZO.8y|},9}z73T ݪrƿDxa"L3/9'0[%\WEYě~OŦZ3HRcGo*x_ZQ+;C9 YC[vGs.(%Xu)D(>'Emh5Y%,:̵'%#\7yBj0`XѼ|K)i-mgG|Qզ 4x'7 uDda%9Sƴ;…LKH.D'&NV4uտ=/0O$_ Q#!XHxhEKM AIc(AEz dk9h(;%( ~,t {~JP3nP:VřݪC,N5jY'dY4=!c7(|qx7!w0!>2#q$c3Fd:q~|}E`RTUpL7rYYzHկtHp"\w 'f$E.b[]*ؽWA_/ s޶k5#'h "b^XiS8 MC+}-:2-pFYlR^?Vj$88230,g}V<.)LF~CG2̌*i=tzzV;bTQ+dp|3@2T x9-K M #Md~@u?xoK~8* #,I=Z~ln3H&[.-Z5l/D%oWT2^uUc>PM۶ٹ;Vz8=.Ҝf mT9[L J!IC]Qf3=uC|4!GuOu53CMbpŹpYD5JCX&  kbA NIc-.NDa{x S.`=E*pARonbHqyǠqmT F\PI44^i4+f[u6 {٩!DF:x6j%f(aQ7R(i`eU se:5++d:N@`B3? _Hֽ@}m{57|n f-r/1az@G@wF}xzI&3U2cWQ#t'V%%[ YI!ctMl%_$'Ws7/|o@.mwf =N]; qf-1BO,$@B&.H_[dfX kklZVcjiCmuz_I%34s"wmVVbA-f>,wJO17O)3Ͻ 73hJ ._g<143-j6E(mH( jG;#^uj/EAWdhiz_(`bG#oAGlCYwy|@\,R=9m eU/ULNʠ[qZ/VN$h:q9\lr-4 =~9ߤ SZ3J)NBE-ETk% +})ww X9r,*ߙk@Xk7zѢIs\ OTJ<O#`m>D1} ~p;Ս< 8 )wM" n|5h  xiRRBtZ y#&PQ+7b8*Mpx~;+g_̌`5.Mju Ʉ_oGcMf[ms VR ˥A7!O8, UxWΈ9W@FikaTA50]?ѯ_*yF5stg.nȢ{lXTHJW/#)D01Ew߃ t6`ݒ4<A~PP{ U?0b W }'ZEW8als j\*% Bo][B:14nBKc # Q17cLx hz%:D{6G/>SAR3/HWiKnSg UZypox! 7Ps"lhcT9ɸ{%%JZzxe.*(Ƣ $n>֊$tz}ͥ{~p%$KeN g_T'r ='ZVa=>b-Q7RE$dDn QOO Bv f]rP+E [G)8Jvd3'd, RCHDCR^]hQFq1UUmlKoMmZ((-F><jeܩ;BW@;pB~4LUIQmt-o!>D90DVQ@ rE oKF8.Ф@ h@"qpD"P#;ȺsZ1QplZ @0g/\PTf|4Yړ99 ץ+v2X0F77*Λ&!x(*DԴOBò[ƨEҜ[a$U?;M )08\o 4>?[Khѐ\tN'ZJI:HX ?TJö!ٮ*-$G I kX K( k+Hlٽ9]CC:=fFx&aUsD߉C?˜,ƶDO -(8H;Yh pO5ϯ_P |H^W(%-PCkƛd _2I?FSr JĨț [6$J(ZBy˞mƩ"JTpA*jM;EMm@/!ZӊRͦ0yK;FWUd &*fB&ܧ. ,WLY)3˱xҨ4ͲAbNH0{U&9𣢬.]ƞ.^6+Rٛ^Qq\(βɥ~nL_Z:CD թy){䓏?AMSJgWoo%ࠬqsR7c_&-Aǩ\{~Le՛LvN[x.<.I[_$ê4.7+=5Pa+EcB:^bS7a"*Ă35u#6aB'?2JJXTktq1”D+3SQb ib;SˢdȋK_Z`=%AJ.G.@At7#C/P_SM==:E7R޼aH 3;"ybELHuUAD`Pnޯ O#|+Tbd%GgHi x 1S`d5?gr*=׉7APL[_\|s) 열 ƧӶJ! \&STdc Tb'j&Qv\GShF*S~D9ޟe$5>QP`#s nDiLDU Fy TR3`7+@؇=~&h "GeR!G3ST&ĢR+FK t4'U=b&x$")G0Mj[tl0Q^A8'B9%q_1[ۍ9յ4=Q[r_4 n6" 67!Vd%Ç-w z:SD=QKIkV2DrאaOʦ2:RSbwHyq"- N^:DM}ްׄj)咋DOCJpX-.TȲh<?"?Ud).h åTgQ=]׿<[yF: ܐ(5yl2;STb !x#%bV!dY)1Ϟ#6PnA NrKX]  7в/X5 -U:Mdx4zy^_׶"XN[=Hn梟c(唫BK O5[z eťFLȷ(* Uxd+1Pëg_GJN\s1@Lbz/L&l18T dE(>EhRٽeJSUjd-6W~VW~?WL?L5Z|4fuMJ͚č,2TdRQJC@JbK[@QL7*C';@?>IKXM\Mu:Ž"Thd|/gK8ЧObkwGMO[/zB OXPU/̠I+Ȏ,hR4WgUe"ȌFnݺ"ۭUUͦTdp1:"+1W/]f .Ŵ5忶#zgJYaC^PFў c=#BF(O],1XuǕGrL4Tgc!36:jr՟%D¢KYyDQQp[H XI Ɣ|'/Td H-"`JNڬ>5dS[%b5h>*:|ޯ gߔ%:gEbOX^)y w!%w+QW.e!g&T]tqTh`f*IVcFQπA+^L۩ՠ8~C Rt`| ߿k9;౸}ySb6۝?%qb :gWS?JFWXGSRGl¿|T$,$Uuoe"&aQзīm{ T SS-a7 BJ'5{ۗ7)CQ ` ( n  =Va|">(IU`"fl#X*τ+] UNå U,G0 T{GTe8^{D a5U?`Q=!`܀aIHb7 E@hQY`W8&Bo@ ָu>F R$IUH3Ѿ~4h &wTUcS%*UBGb']Q<_:DҪzyHH@|4^>nR`|;V\л" |VN(e'lE.4 N㲯3 CwQJrWa뭰$|;J=3l;T%c&{U qJ} jP\^=XF%]k0&FC P~J%X_eaE&`"pT_d(T/eo 0lrNt]H=bHYjh7r2t;QCaSrvou$+ObU5ddr*23o$2 !A,MgJUWnh5a}hBF/7XTi(cD{  N)L[j=H&\aHZt3%AVKfKYi|ڶ|â4).{s\iSga$+12/C|³'6kuFgMZe?Jic֝fG͢3.M5RUa0aメQ ^Tqck.a60£{$|>FJfKY-CGPQjģ+P2UTtcM^æ7&'2NKX @JsOⱀ1fd>XHDPN{x[:ŒTyY  Q@aYe.Dm5nW {v`^KXYA4Nu!pK\қ$8)>1ROaNso︻i Ra809#ReЁsi{:FMdM`[]ꧻ?=)&-S#c I!IA?ǧjďʕHKV'BNlܯc1t:D3N]ľwլtqP0_|1:PC-L"~R IkU+6D,[P"r z% -SGb744"|`ȷhK m Rj`4=Qԕ&{8/CSO]@aXDHOr#(uT*d ;L'ɞ`gs5I%t*F=S̖EbrQNpjY^-٣ F6W@Pp_R* uT֮!& OQ^76l?|ҪV#30,-F(MS(GmTHfTZ V' eSb-#q(: .ɀo"*"Q^Bd8Bߪ*0UPլ3ȿ=&Q_O ~3߸K"'UDudo%-̀>aCBiPHUxZivV`2:R\b݂JO8i5/]M[G;3E ӟa*BVNI>XDuX&33tRa/)/I)͠EßZF9S@M[R@=H0F/ب7ӡrTe ρe-v&6cQ`sAνt%KS2b+)4$ xۢ飴叛=lIfK1YH0vQ;N<%*32NS`cbEH৸l3_xIWPv@دJ U`V=G|M[`\(7*h eq?}Q9O`1/i6 $<ۢqfy8JiX`AM%(c9~a(b6(30SRDb z+uTRla1;/јWTz9"EN}\wUX&P4$nJ+٢Td{T$F1ϴLɥ`F#TlD?Pa/CjԅڢӪ"8AO_ [2 Ou^+54>Ch<6-58GzSER SxaI[~ !IG(*R Tb"Q'ͺ>+fg(JPm_˻6cA-5;˰ߠݵ֧f3UE>FtPH^_  ÷ ^=Š FF*#T1c#+?́Q ݣުB7OHlTO!)Ӹ32;rQ5`S*(!L؈[#9KC3K)&AZ䊧BiNH`Vo9ut dQa'w .P6粗q`M \j:o[F{䢌ݧY6вH-7eP_'-5sS:b!)H1P҄$m׹5pC=IIJW-(gEweV8,)3oRca)_-*E^kbBIW>t>MGI-xߜnWўTp]q=BHKxYL5囹wž۶x@_P_-e5 ѫǾ;qJW\?wL{n1n*'/vQ`UK\! *VMlQq}`p/8\ط v"G:98CaLGZq֛E^?%+NRAbPp$!?{w-vES?AM*p紷Hۿ{8/eBMMC\IOMjߺ鬸E5Y6G QN ]2HS;Be SGSCP^ynw‹[!^(Q Oa!N$/ľ2r;Ga P^)5? :|He(63`>IOI]} yþªwq#SH}c #:*3>R 06BOGS.<®&C^ª2zl;DlQx`*mభ=/ +MI\Y59Bcݑ%OjXZ[CjNHV;K . !JJJ{WLyװSwī,54RaINY57n^=ӂ=nJߑX= HQY v>H)LPZ^x㶛]hpjHQF`-54d#3;+/KTtX'W@݋Lce$'0QYjai[Q2yMC,YDR'Ca/kf9#84]ެ89DSM+[xW$4r%+NSbsI"rZ´ߢU&F[TWBh5N;ヮbr0xN38wAN T]$(u̺>\G fmNH]2;ub,amSnFSCQ$ﯖIG;«!(QG_asnn$z'>è|. PC^4M?DkH ;d֥Y3i>O] SÅ.#;SbG"Է) 2;sjBOFFzRYv͏29;PZ_`r 42IӰD/ILj[08zAw܂uVYQ.4BN'SGJUTsc8ǓI! IyQ am%,ۣ0?zPqC zMC[9sERz [9+Vϊ .7PU_EXn­Q!R bp(0Іȴ \Dh굹(>ɧJxIW~&舢 ½,a]4Qaٿw}|LIX=GJ< i,sRݚ:>.IQJBY7ҏYK9_'P!I`+C3+ιZhZj OrJdXT>J?o!n~҂(31Qa%^DG֦tCQ6a-e~7:ՠ]lLߢV:E}iLFZ91pI;{'$-kRb:lŋܹ4Il]oPGZU_AtM!~XEic,և}9CGM\ª?Ǹͪ_)>W7OI_-1:ĤD `+GTBEP1vbbUV"P*@)Rual"Nb5 a OP/_s3=T_c̳ 80g"QaG$h*Rre/B'i\M#P\a8oHDY Z ѯJؓyd/u9:P_ <MB#y^ՙRb&G//MA]6IG?I J:XHM15v5 Q`t*2ZF00\vJY/= J%=䗀l:G)U2gQBaP{{TRQja,c61%#擩:FLIZn@ɷ٠';.Rc5b2c ckgEfGN\yfçjҹ _c&ҫRtbw&*F_CUQDZQQ;Y옭׶p,4v=N:] s 'j8zZA 9Mh\5?mP̰jB+G}C.OxiE S`5 +-餹[UH=I#6Q`7B#(ǘnŁJɃM[#7sB[l"Hǰ4-*/a9"OL^ 'R!hS~Qx`g%M-gB kТ A?LzG{ Uưf X->"6OJHVB% UU6ܗPJ`)0 ]Qs#L=ҁJmXbbOΰ^ < FMM-3ҥ LOs^e 6'[?:&JvЪ Zy EƬQ9?F&S i1xlY&~Sc!V"#(ČSfO"^7.B 40X@b3UD=BQ#`- l [m S>Yc8$&, TJeurCOH+U@s`ƞYQ0~9Q aV<1WEuvNw\:QDs$͵ՂL7AQMwI`WY~")ică;' vOSbw'.fvnL-zժBM[G<GiEU~T͞\gͅ_.RI7kRŝa7J*W5"F xRkb*2kjFK䨟=Bm乩>էJvK;EYIQ(Hvd#:H*2R-b`"]\ǵΎnI=J?X"?iJͷg߇+zМ->A?7пb$N}DzQQއEtRdg !z\+ .k&NR]b!'vA}ʳ1SN=]7AH}1͞ 2)<8P1_r  ;Rl9b$F,̩"̰"AwN G UVI+Cn4/7sP_O&:yXC:tGglLZ9ЙDXHئtfA>p?oKvJHhVC-t'EĘ*2FQ`{S%+ yq%J &XMn\@%(m O]`1ӧ:iM["ŮjJ_ÀER3CP*BNc 8ѐ"")poQ`c3#9vD~pVAZFNA]4\>tcaރ׆4>M~\! '¶٨2a]%#RLK|G.Us=\Ŋ+4PL`r]뫴ݯ>G~JnIX:FI'ܜGyGbCeKJ.A*Ƞ~$;)1EP_"7IzԱdкgT P`.-6Z&Pcvd:E JY(XĤdɱ̾#%% C,!Qya/=Ŗx"<'GT?Lxc7F)յ7}NB42M)\+Ƹ /Y+wN^]0B9y2~m.EUS%C/!PfTzw;#;̧¿P#*_IQ1`\?."Jã ٓeُ N(^2K4r>/jǮ8xaؗ"5@?QM-~\|VgyϏF r#(Rb!\(YY7!TC+PXVD OQ7=~;կ"ͥ~1/;DO,^` qxƯF-{ L c[5?fFԠî6X:c+:AMGF25T1MӤLB 85"P2`?#r)%I^kBKZ8Crܨ0 ٢swm/Š8N1] Zcȿn7P`'%. Y]>JFfTڢ[+4Od_`웴<<Ib X7:E J!:O_(!0D*W;IPW=Hnf٠!1*f2O$_cZo QpıնԻɏEQ"Pʵ_~,kt5ߔ]nmѿ :`F JSWX2/٤iEL%^-HQ2 aB(u?ظ}B{ަGU>XJL/sޞ}QFj8dCvLA[ *1YqaOb^.7"Jfjqf3FYTBNf 덎V[ć%DM,XQa7 5-R~ ׉Op^2f%ΛDQ(VC\PP_k||֤J3ٱffŮ=BVB*O2E,SHSIֲEro yf$sPv`! /(`༕ƴ,^HׁLU[~7gBٿ഻Ɛ浟Ӿ0K:MN]Mh tTqz0Q`H%-s50Uɼ?-L7I՝W;GN7lؠ! +l3KO&^"=?sdΈPsd_k+c3dg֨5&?;TFojn&-OPu`1#ąW1Vgz[G"U=Ib}zާ׬l83CzbKY AVr)7pKN]$-6IVY`{~2`U6FS@6M9PAK J8U%D,^Pž_8}vYnڧ  N ]Y1x;هs{럮:P6A#jLZ`Vյn8Ŗ_J&!Q@av$xoȷMœpDaQ[BObOeOϟߨG3Z=bNf] J ʺ-  \M\64=}T)4`IAC`OCyERQ ޺7\rN%p[Qg`!1'[Ƹ 6תE!ieX{R3ai$[+~9mjlE|Ai NJFTۋ򓌯ߤ{ Ѧuڡ.u7|PA`f78GA=I4LxZP@9D"ؕ˝&yܟ?KkI-.WmOKP\ĹuQ`/q'c.=kpKZN<:G*X[D O@ -y5!PO1``C8X.7RIa+3-#Ů`Rz`+N= IyJkX$-cXj=(/tRa_ʹraP&WI\W>TJԔ !ޏe:̓ELX([)# ,cp/OP_.)6ѢсI'<%HUAM~줈jlq g&-Q;a&Vt] ;l zP_R1&;i2МqV2o7BRM[ P!s'S$bN$J YA4HBE+SECO5dE)Gϧ4>{Oa^c PyF?GX6` RNv]4='S| h쨆gDnwQE} SRO?ʰ`^ɂ3U &@Rza| &Hz ʳ٠ N[]gM7AO/ަ띶Pۮԓ3=AObM^ g 3o,XK +Sb$k+GeguHBOhFHS#aѮͅ,F/8ӭ#}B^-6P.`fκ⤭ȯ4R;b*2Ko;0< =IIWIRTڡoMX7)J1BRa<}K Q*FRHICWr=_Iw 8߭1p< ;{FZKqZmҲ_O.O\r_N`,!4[7yl2T6!.RbM#9 *t/C362mBO9EdRuVt:Ӏm0Uj9aO_o3jVKZ 65ATՔ.:{s@L$G Ud*@ƚVNg wIP_I$++Ʌ9FiZ$GKIMZ9Dy()cBLu.{.7wO];^wNí4jA*_B0Q `'(0;VAߠ~uߢ=IWHV_J3o$eDͩl)1vQ`#Q6p_6i#.IYW-X\)~,@}`3i=xM9\X! n(< p"5Raj^"')aO*رviApND Q9;zL+ `z0I9~O^ wyܹ҇QMKv Zx6a Aմ܊>*Ğmgb\@=M'GDT~-0ȕ/&ŻUP6_$e+ɈBФ1b3KO3ZU9E%ׁL-|5LN]l!LIe9`Py`C(A0F`ѧpB0Pu$Jz~xK&&L.?O8^bۻOCiWJ#uO^@.,71s+ED"ޗ7BwJ^X,f= Ef^$- +>Q `=[ ݺ񴳕'Dd,R @KX]-gƔƥ37aACL7[Y9Xof_0 [M[X0S9bpͥ>L Q@[ERBOW1[N=C!'w7P:_[ä"Gx_\'+.f N@]3O= wms]»b63=+M{[F{yC~xF#.RXaDc!(.Bs=V4lAB#NDFQa\ԟ1:|O.^ E7: o KY6m@E0ռ%WHeAMGЩTw:sxKA6tPs_7$Z++宾x_[,,L'[d9Ds.'P-{6ɂO0^Qn!&|VRa ( 0UFwumYj݋˵=pIH`Up3h4o]F,4܊Q `ζ}O,IhWE;F`⩛~{ 5=IJXA,3Aȧ11π81#P_v*z2Fޯ1Fm1JBX]>jJG\z d()0P_u#%k) wQ`-6.MN)"9D>MKF=Y"@6sXZtJ% , 2Rva9y~c?zFEkStu@RLLj:A(ԔQ8u|B.Mʿ[\21j-`nұ mkN\O09Rԓ}̓OIF{8S JB3(OV?K$-Qy!\(:P5_^Z"xƲ"@+ >O!]"3B=a"?믕r0׹3s=9M[?r;`~D;*$QPa 4'eHAN DPI"ß߃yͦp2Ē;QN] .d:魓 KaZo5?/Ӽ˭^W꟝.BXNEZWSX*1i#Vkj!ZJP_@(#˟)&V].L^E[7Bs8xyn.8ONڽ]x Pޫ wQ+%a%-@δtBڱ\>IIAW3[ch.s0Pb_(0ṣdJK~X<=H>n%jh) 2vPD_p)ff~R͚9Q@l`(,"5fvs=naJ:E=JXgDܱ{t4m6&E-=Qa۽ٸp T7FT?aKT\־ ܷ8 CCILL[T.޸)Nn^N^0N8z\ӿTz{^ﴴFSArN[>#t")?*9Q`M*!7qD÷ D: 4MO8^Q2OU< ɟ!ޙ"46r?oM[%m0:e%QO$aGT%3|5"Z,,BM8PC_?PgO%RW|#3^~9`XZo.8 0Ey#BNPDQ)?b<3=㥾"Ol_!'[vpgh=LZ-6AiAڀ㠯0ҴDK\FxSM3@*=ϖn-X5 Ny5^|uFdC %@ I/FX9C[/뭸žV4t=zI4GUI.XV0A zw\O^2l(G/)ͱ `I3xWr;+GMl|Z$mW)E2TO ^0 +J}RbP;5_Ne+W3h\̶e 49EWJ|WmQ1Q5&E-LP`7"eH/FUa?{JCt0H DEfhי8#uCKZ#eC)θɪ!UN]/ U7ɬٮ{WA"<΢FpS@hMPPNk1Y2Ē`#>+EQn`ީݨb DrE* 3@ iO4^1…;m"ӯf[!f5 @M[3w@^S[%D#RGE N&Q4aw%Y!jy!'CPQfCOP>F403o=2N]/  z3zMQG JM5\4=C5sWðKr%,M2CODQLznjȡzA?$?"QmX`!&ߺ7z^'eM[+6)XA86~kPҗH0Zu:WO0]0 Q OoAQQ`K$w3,RQĄ޹ hN?HL~GSB nhTKYms:_+DH6}MM&l#}a>iJåHCpVf"IĒût!ύP_U(.!مˋ K X;8GOC~5h*G4zPNK_b%1Fr Q`$*b83>;вʅȯS户D;\>GlJ|WAvcKJg](ST/ Q.A`&Bô%(@HV>WgIʕ(0Vs:?EKbY<$U% ^`7O^?.75Ǜ2.5?H'Ua@L;V3(9B4 %,QA`nZ?  -PŨ^|0):؋maȮaDM[246}A*MdZÐus*ѥ" 'GRUa`#DȼGYۣXchE-R;COxY+,d׾^z5+>aN~]\ 9Ѻb ̏N= ]Ҁ41=ܬtE ۝_EQ=D~#R4paȜ6'\~%WQh`z %xb $7)lN\{5@`ݢa.4'ڗ1F;PO][ -ߵ8\ܿ蝴" R?a#p<+̯Y=/ @a0M]F.S<*?0ӭ¾I|ɚ071P_̘㲽Pwlw}YKY8hB{ ׫jܝ#fB@eK9GsXUqM-gFPY_%,lW{x((KFY9Erߤh`:+4dOڲ^%-56ӹQWQn`(| 2\JBM{!UwM>Kaa63p%7 -O2o_֊0Sb¸Z.O !OX^{.9yШ&g|ma6A9KsY$nɳ¥pNjӻ"&t(P`wl"P7BaH*ADR AYM y`4]-:5]?-LD\V d"oA ^ LL\1\;Lֳ-2UeCPJyBmPy] p%O_ 6$|^I9-zT/JMo\:49?>݂p)Z۱hۜUԲp1;hM`\` ~scL QJaM").õ,DVcuP@MYD/Rmk Խ%ӂk8/80yNw^͉ 5OqETC6J$YQ7CA<8 VΝ~͝?K7FdU fMjE۹W،OMk_t%f*,3-gq Ly/+KY9pEbhޑMYՈi͈+5,yO^^rF=)<ܨ0Qa_(c1,UwKmoDMOG^9+2?t5ŷlǠ3,HV>-fJh*t W&.L]P`_~㽾?`sl ?P_j-u57&Ι֮M`UU7 CjKQ\Yu0JPo\w?$G*{KQ`LTW>9E(R@ΩLz魓W%6@L<[77X&4戯0 ݥKN\1 :u1TzE\\R'CP`᰺&) 2&QJ>`= n#!iNߦ8{NJ1]3>RܓՖy.ȞVlՊk2̕3VڸO ޼ToDQ<a'/$$¯8T[=0jIb^HU-ujJ8oCL[iˮ¯ر?,YN ^]^05C9:z@ KFSrBCN-&4Ž!/)Qi`x2"1STضIh~ GOz^`3/v=Ts^ݘ6p3 }>4N\rܖy| ҷ$_R-Ab u &徫?բjRCWPDQu{$bɍe43=O9_- IW ҭU M\*A6*@iҍMr {,CfPTFKTmXpXr#?N$d"pQ`q#Y)["V]PcL[1B8I$Cpb%גV.R760O ^"q"۫?cMQaG'.E]sQU#H>rJy^H?U\~, 5ERP_o9kNԶPBIXa:D٠YqF0v=i:IEHWaVk-L=X[ QNyp]C#(a/=eaó H)Wq;&GWXGGDb|ؐ)1*P`7_>eMQR&|Pw`\,4 ˯&妦8:EIWC=9{(&'mo.P \` oØ}3SGwU">IE4;:-ވf 9C]K`vZtַ$UվYN/]v.I6Sz 4FeS!@M"o{+6 $l+PS`?joZച4.  Nas^R1E;,Sm;ꘞN,ڂ6 0ALO\[,vʥF̩ &Qa4$fȥr{Ա!~kDQCO9iGf2`OD_Rfi6<!=#WPЏ`ݲ!'#BiɥNK+[7Bh]WO5h^X0X:MN^ ! xAG۳bPf4a!%,u\_ΰ舡 ?SKiFX}TynK"(Ǖ+4MF]Y۳и/E΂JXX9DSerϭ@~&>JI WvDuѥ ½|'HTQ۟`9)0c M>2^ IIXr; VG%_SҺ̡y+34O'_C;6?{t{ZgPQ+`RG*2!%ꂰ8b⏈:b"FIVv@$R̢:½>'.ӀO-1_|uYԷf޵O/GYT<>HI3kmsJ9-D KY %t`N>Z]!-69lY֪#GT?EK{7r$=+O^mn(T.H{ DNW].|7uaenœ۽5?KYvYe N&P%_/gT#ȔOв]'FAMN-BSNNz!| Il(3<]Lm[v. uE< DQ Mn[-5Տ>QcHʼ!uCPERGry۽Q]#QA`V!4'}*\ HM\\Y}54?ؗg':609hN\U+  ΅Whk*(PԤ_{#QB*J6k3ċ]݇Ӓ>E KZ FSu+! `l)j5f/7HO.^6I~q(ӷXvKyUYG9DDp']/pDI9?K7=H2V+W@n.5;jItPN2]T4 <-RLw :u MV9\3= 9ٗDҖ4!&CDQiDQVC+[25Ͽg % RUEa!!(nn{T7O]68AE82qvMm@2;/O^ |M $m(~U3XcǕxAM+Gz|TTB JU10%8ON/_O> 2~jF,LKiY8 vC42ޚ;5zўTAMGUdpuY.ŧX98R[aO&-vZNʢ-9%jMi[m;@G~E뤮Ģ}wGne,a4+ P!_z{q&}f4vQQ+`(]/1%l=v0O{3<(G7HiVъ@Dw)0oPի_cEV~;wOGTv=/kI9ᢅRu3{\;*E)K6YJX(̝RQ/~% ,O^Kth{# ٱN]>/{82iJD7XA%KYgXþk%l+ ӕb=Q1 :uLZ rǁ ?iES!/Q`m"1){U̅«x1@Յ 0n:N]a _CؽֺpKY6pA܆[ܞABO>GZMU&$@ݏ|d=T Q`%,]*fJ3s֣(<[1PMu[dr9L@Dk'xݙׯwЃE-5Mt\~ }GֆyzޫO'_$Y?,9.Ś&p}"'Jj꓋ס@5_%,O^cNy4pJѾO^~-?6.f 5B㔩ݐ8rB;KYvƱ / $*WQY`:: {M&[CPAvM_ڡ9oڬڱk5@ KY&ZUSD/;6j q RM[1;>#ޭϥɒZCӅP!AZ]NI|yգ5@o#Oh^kgC$vlE[FL0S[R/3+<ܡ֪؟Z p 1:jL}[GMۧ΀"Oa_%?@>mHmFӐ@WLCnPc.+g[509mL[PS ty׷:(J"JMX895ٍ?{ mKA@LDQa aǥwƼ4* O ^7r")/VN;ɤc]KKKY72|Bܲ)6ϟ+.&`6Ns] `7 *k;QG`&W.ϝ.Ɗ*C9旊>9{IH6Uӯd̶Ω"k+3Po_lݿ 8 =J(AW~X;XF> 3j4Zݕ(=\H7IŷWsXwħz̶`)OrW^**}2h9ܰSN? HBU=PsI aᱰ M ]ȣ%a)-N^Wg¿BKк~4f/NVR^_,;5mV;:n t 9C?3JyX:qA=c&7/-XRP `wO.[&D&Qv>1EKMv̟ nh.Ԭ5@3JFY&'Hg+. !L:[..8 X;F^]S?zL6 cF0y"(0[O^cf9^~ [ ^ON\2<:Ԅ0C&X/81Mh;.M[,dc AͶl"?P+r#uP_O X&@a.fA'NbCzPR7Eگn2-M;ųFGJXRu˴7} Y&9.NRXSb/)3 2?I.r1HJVZCmO$뮴BCөr7-`BNU]ְ hP^g0e9܃&qͰ͡-F9}SbB/Noн%_#C*Rah&!,Ļ>o |OՐ^r3t=N`$uq@ّ4>DoM[ &?亹9$Ox<_F] C&9ɲl.5At9NbCOM4ˠρ#2<}Nf] 6 Wf7PF D# KNu\4V?9`HHoW0CѤP5EvS60UGɽj#.P+_a "=)VIմ4AW.KZP6B`?ܑyO э /7 Nm]% I1r#,DDO#_%-,t%Gu C>DIjFTY瑢 RƬ+33oO_^BUuoQY*lJWf9yEkډeX<@HIXȳeK~+.b$P_!)1̬Mıy#;I2fWǻ<,H%キР[)s*2dN^'i[nȹ9YQ`ɓ+;G4 eu5m~=@HBIW:ݱ&>UK,*)01nRbi z_[›6t.)7yyɳdo%Q` \&:ɹ_c MP\8:BLJhi97/S9MM\( b `Ͼ' Rb><&K- w)ٮx @sKc F1SSg>GehQ,t3Q_)ޱiE@&EHTϙ717@!d֭+-G9CVKrU&aՊ ~lcRp]l&+ˋwĻE_@OeKtDFMMj8Y> 7̂PŨ[ K$"k(hM쒮s"E!$gU7Zc#Y{ !"] ?2"B|^Grc&G p2tܗti _L5g? L 7*'DJMMRnx 4 (z_m!wn Ƽ |  B 9 O?KH z j % ÿ:l?V? 9 g T "()$Q \<@ fQ wLXGJbF4W2] ZkTQXHaULh  _O"g^jXAQ M 8Hokl0c +r 1825DzxZ%dkb]_ >H^U|p@ s;f`6C*N@ϡ~:x/X;c"u."qMCI6`SVEe@..sQFA5~NH"U4MߝD|u}G}8w#LJ= ^?q{C^tZa{m H2;wFc?BXv:F$6@Dtnx~m$jx!PfN"Ieg#{7נ~$ta{?ZwA#qPc8G0"Cddd]+0*X~TP 26{"%gmEbg\y WN^uh[k B2m6onf.;m-Ý>*to{v<eFIeIAys 4 @arRs;WWPOn" #o.#)u@q~AVDhpTZM M`<vPsE$$&}1C+z~243uxx ~ |s:eJV@OV8d/D O ^xaQutxQܢ[<Sٲ~\\U)aWKOd &I)JjkX@iśLfz7F0{r@/Eo F4pU 5K@z5nUWexSeX}Ks]*̧EN<0 Lee@tEp+dL9%9[ v%ed3D4*uM?a}.E~@OZa  #\u?U(p l QU"oz,l_sF1DVu?I3k̗@Pa ̛F!ݽN &f+ϪZ@py]%!eJ9k0Eq/%ܷSL X<Q=%Uc/wPǦMYվҨ{X|jL!axY-{L%C8 `.Ү+Ѥ\De|8%Vdz, hg,^|Nd,1 Q4 9DQ/PRp=C |ƣX;?vIrQ d _ cBeaX\miZ!jGu>f54&mH{: _m0l]dD ~EAc,m/9]vK+=xf. NfoIIO{}&l~C|d8P1~{T*{nȂ#2 iKDf۹q~O-fenrir-1.5.1/config/sound/default-wav/BrailleOff.wav000066400000000000000000002735201317357605400223670ustar00rootroot00000000000000RIFFHwWAVEfmt (  8qfact]dataw.+N&+MK/$#9)4C~{Q *o(W 谎sԇGꦇ5u@}- ٰ'rx XީT_Zs2l.+Z.<7Jy4aH>Ae)FF36oDp&Q>^zaFV nMɎ#(lX.d4+4M  O4#S(/ ?/5U ֣ D}'[M`7Ï TV [Vc! 7yeN ZW\ q#H%ԏ)qͷ'1v 7[yk>$ U+!c9}h1' %,- %iR,D+<4#3~B2[ RAk Flw=C`m$OFha*_-X3頰JԩGN+?־֬f{`gU̘1dvf>>V&z6Te0Oz>+^XX v}s3tzcb7,!ߗ:* >.5a& f1KLmMZT4W2g–=i-͟]8?9g v4;^.PBm?7? 9 ,%BaZC rN`CE~@%f&.mi ]Tt=6g cN,~;o=kr*gnQR?\ !U#/66\hʡ#K^0 W$o"vB0 Ϊښ= ,^Y kMtcbNHOlo 4 "! w(J1.#( ;\LR 8(B<? {z y9 A1Q[$>8k3R V;h`w؍{*iշAؕ!l*uvj%d1XҬIhz_`A/bGƠHqjhfL/Ry>nq0M[D"fWLzKa8OA'SA']dqX@뙆uc!@ ԘؿkXkWo ?? :p-,-_ 9-P aJ(!ʢ&څa# d -ճ2k)"3* i>%FM-;]";}6!BJd8Jk:Q,%% 0z@&A[!H$ ș2`3m2ؘ A<iɬ@;S0 $ +le-%b7!Xt : Jt8f'khKZ0_cxa c젇?wI2A3KߊT>YL7):!N!TLO^6SM%lL=Q' +굮EVW|uQ a8 VA "z W]/AMUrAEra=1WWy?WjwQ3 ?RjЙuJlCD `@e 4 gYؤ SQ%e*$%*Q2gF-r  lǔa JM '%@c̔ԳH^{"ؘw+ ]}y>r/qrLiK#f ##H0D<Nvc #"5EiA՚ `pKl&^,4++q` ME ypx ÖY.! }.4 |Hx8F[Zyyy?Ju;hXP؍l-KZ=a |7w8BvTR<퉲f @"9,u>v}?!?.sts8gA!GR3<˽L]UH"QLH,t'ebA^ꜜ-v4([*9]1|IM  vp ֩Ґئ "e %#e""nF ] h} [xU`_V+ }k /1 ~>?H3d? RSh  )یT 3G$ u S%D9y?>whm tNB<%#K|x'D|݊"(E,'H{4 7}!(* W \,?@`䥹PiEoE9ys<;90N߫HE) 1A?K8jKl BK%5ZhԄ8F音=-7 z4XUL?FQ$5S~%G]Uv&zG"/ !hsz5 Ѱ  ?Ci~"nE6 Nj;Da$!B%[ m _ P =\`. ]?0@̥A4^ =7F x{Y<~K~ fE4!jL#٫L+ 3L wkrBԛ\A@'|&> mLtX%@S*D+$=)W64{tp ,G$  2{ g瓧d[2\fpfK 74my{l z֞:}\N.:p@6oQn\sRR% RT"XOo_vT.JS&Pi#Qh.0=?r+a:Ko?]tb`UY[Ly QG15Y2_ҕ\_v>BMaAcv! 2 j< S]"K- ?}6@)C#)$AUgN75 u}x / u l })بtаpGxU1q5dOO0ʷ Wl,C] #/ {Q'S#<#?!8djQpTXboN], Gf_H+a #5\# ]}k'*o)}7 j0{Ntm pz ) LS䓳~ş J y࠾x>= m^~7ssY6R/1qQa^iɋŞIV1FBP]Y*[cjhv +w귾1aQHu$f6S0A@r3- w=8.N9!7Wz3N~$T@E9"X a _YW\.u  (|J6 wIځ$uI"*ɉ + w^V?_ z7׃7M_VdNKY z&a$w5 ,5 NU C&q =hN$EnA'/ k %:-NjbI{ f߮*"<)*~m&Ro4@.e%2M σW 2#+aq)sh^NP_G?n¬08O_sCP,&,!l3B~s/NN!@L{ lOT6aOx\v Uj:VJF, DpQb9R2 ZXH{^Τ堗\xm-"VKIqy^ c ep/sY/  {c Q{cl O0Nx>A U$P50B3 v` y %mqv֓5(Fp RikB>ɖ 2 8)gPT(# >ax8q mw M ;7@Ei ncU Qh%%**U)"r?l ,g| si / d6쓺f ச܀ੜX20dPosm\yw_BuӔh+moѣ쯼Ąj);D*[4ri >A ِ es.G SK7Q3"_`!#5ev$zM  1f9 | o?4JYo#(Ħ]Qz_vns? " o"xSqrD4Y P' ][8; e&T!6 ]y3P8x&*nh KY^ 5@\)ǓZ:S=5 n-')4*ݝ.'ΓtHPl 0|MhS< 鴶 cHiBHUeGP00jcrCOH%&i;`ۯBF8[Ć["R\ w-@Ol|'v HRE-Zc%pD'%K @\=^zgm6}d @sqYq3,f v N1q;/OZL cVr] ES R 첇obd 4*#_%!,F{# D#x awnz })ckۑbqENu&BDWgZp.Aʋ_Qݔ<6` ᙄڢCNfj<ԅ}1[E@ ~ yZ_Dz* t ebxܽ.beqyEt&61 &?Y-HmJO09: K|4; h;f@W1 DBWTak۟F YH MLT 4M ȵvj6 iXTh2hLn|L2$  q )XO轵w :Gfel f,f"҄$"vxT) VYt  W4W0< h<ׇZE*koyv2_sb9+9d@d _i%zWTlk^S8>2{WrCN\^% s1M x^dX7tF: |g3+}wr~+,2Tgɼ{-EH s,A10f: ٔ WEpƟ:C ή) oDItW|eEst6EFӝbbR< @ 94' 8;x![y&Q3hokP  qWGZHr$ ^; QL <bqUc7, >O8Jm T " 4 @IKmUoIN r& ƑrOGRw#@`$. r/ 3lY9/p N|2CeߌLJY3L҂;~ھW,z)h\ˍ B':)cer- > \U`m+܄_JKS/Z "Y3#ꗲR7;8T^O6$4X&s~*<'Ю& bBY !nw}@\ m[3I wxp6*pb힛-lytOnTDzu 7A6Q墤w}Wf9vlz+'/C̑I&\VAfAzr%NV1m)9̎ A#4E ݌b+*#b13R xR%v~aS@ߨϟyu19^cEP"Ă#g_ : 6nsl Ar dMsp[aRMK!fJfYpW1iV|Z-Q:7PзrޖC#G9 %Ey>E* 1` Zm_y D',. 5ߜkZ<B?!nn[PM"_6NtZKuZH(:9` زTׅʭܿ 4梫SI ˒.!^Հz"5*xGbm*0=%؉ /c*d2!Q2n4H86L' 4B H/9GDk_ u4  BW9&?d0&5wVh7uHU/_󃻢p53ΓzJhdJaz[^bV s) K0އiQ w: HhTT]"&؞[ M4FsT 门1_+셔Ov#dǀAuavWCnM=hOihuQJ31lb1e9oiCW'=S\y ,"e =Mo<HCſhEt@f1{4kXُD(dZd؉x Gdst*܋P^ [!!5~? KR ڨ9()HECp( DUJi| 'ۊ g "xLHD[B𰠣pJ g>˪7&z? U!QΏh ڕgJY#1G#W <g!,`%8 S?E2Asʴ-5^+(9sjH]L 4eS j}^:vZF3\s/b޲tE|dckDm3~nov\q婏4c=顕M\GIwasj#<#iDk˜<-T{{:1e~]_kwp׸^Ծ9 U+a"kxl4QJba6@6Od]ɿ>8Gƌ%/n&CԱ4(0fhǏwcNŬh܉_&ӔUG B=~ dR#t,ˊ1ya֚p1-GY>ҫE6*K_T.7eV`E PۗN_FZ[D^ {y~b4 C7#qNq@j'$ƛ-1)H.F,&̌,I4T3(_%=CR s} =GM& )͉6g]w<X( LX}ܲ)"J:X5P(& %Y*p2R?B<yP(tT' X%#e=g'ֈ,1HwWA?  !wj%U [E *Ӎ" O?niH@εU"qf%(,n ƘB:`Z^ɼCp%}G摔 qqk,Wm$lDlmFZ}#\!Gakvɕ$Fdܕkv-ܥgs@ c7-Z> &"׬MHԀX*ٓ"ڪes2/Yں⧧SmeC2%Z(ca)O6j3dQW ? K  mu]oO4O@]y i^[Xń%&(Gϙ#b& vY_LG[> Otק LdRC* (P Ǜ(nFl✪^/;145'[C0 j[ AE#͈&54̯ u| ( h%>8Z!Nxz)PމE80=Ȫ = yV!4Y k+s v ThR~M*MOwIƑa"b [5;#pVyTyߚ86T{߅sSpxɣU@|+h2-q {hk4~vxH[z)eB=?x]4;8*Gl@Su[a6&x).2w?CR-A>xم* !Ҳ:ǿט.ېfZ/o!ɥsO-$^[# &R? OQ&T潆kI~V.z'a,91i#T /O<& ڿ?R ϗU>)L1}1U"&Qޢ_"\..o J>T/4\+T;HE8_KW-ۉ&9,V((u'-@!ȺPA؄C$!luve'T#iS$6ޥ7 x;x#}wwiHG 3|+S#<r(i` B%̦!!Mu j-R"sd'G]1\:A] =6k/:)!ʴ &g sw J X[ l,T[Si-Tp/Q:\H"(n3W=H":g`GB>w/~6J2hImvpM"tZ *rԡEr u kI M = 5C 橁XD Ω׶dg JG!v6Q̲  _#>.=35)+l7e 4f'PLpIvxu0".aM`\'շ`:ؗSߪLG#!Nhem_/HF+$ecB8smi\wV&Y=!EOWCkʿ_D㶨:Qs8 Cu r8e[NVHbYS>zkz Ӷ% g ? aDZ G-I^V^#,?_O \l Kmz'a#p^Rb$(2$Wz};h+e\ < 0Pzm$S%-w iX!/&G$ݙW`<У+}\9vaUmC P$ K x7 gˈgmHl(lxJcK~0E77+eRۉ?Ѩ915蒋c C>YC,$' l $y Z ULQ7p^+:$] 9p;h` {wUV-;ZȴICLTQ:LG}DF3fbK+gwx4+)E-@b㇎b=!n4lRq%Kd ]% .: $ &ZnYD'th){4+b@;?7[CY?gEnu*qR;2 N<df(ÅU}#]h0w1 i(A%A vhT  t\z@;%/v6D3)tڿ"[U> 6^$\(IGm/rjIQv1Sf6Vb87׾v=Gzr+RpfUYf7.H DoiE]`[b] 9@ng~҇PQ`E4T V[i moL`L ̈́qI #(1xZ8tI$!.&@#>a  jϟX,2U9p Mp ;wR߷*{rOa煋90ܹѾڹ64Lx=DtkHTU{BjM_L6<$ 9>A 2M7t+?UU`s* a/ l l׀:aN k>ʳ}i,4. @9*;SA,2ӤO3[E$Vז:Nu~] 2 u6:jr!n CIFtЛah~|\570!Ԃ\)_Rk,%El| =Y Cg3^ֽg {L0Ͱ'a goBwn#">*֢F@ σ3y o$18$>ʿ$ P r%)!&;Jәv#mH?RosamT Z%I WsN\au:Q5p TA&Vs{ȸ,bbdzs85nMyx 946 F2VG,[<}N0+V~b i3w_K`ķ $z]&kN誌_q삞5<질<蕑#h٠Bpڣ9~%Y;ܟ o'\<-#WdYMm)QBMZzE:TE ? W# 3? G g9k8~Au%X( [, <&=V1W) xp0TH ?!~~#2#?!nSl!Q! !4ҏ¦!!( s x n @~#.(8k<_l87(֬WJgaTom O .r}9[ &{J'#}\R&+5(u;$FOzj( "Wz %{$ګ"tIQweI,f"}#[X"j\Di5%ƙ(ȾC]V#BR:gZ۩0&WMtԠ:/#3qԣnXyU=id)x`C ٬\ۚ1ѓY3Vo`X~"}|v`xQ5溞}v~gY6릧ypv1R(D0.1TsV& L]搥'$|}𻲢߯?ZL$Im,y+r]'.2;pS{`2f}&.#'[#5'!E=\X@|1C E zP ʜB: ?B W dg S&  k!;N ZW3%esu^a>8ƧuO-S)U/XGY [v \$M Ӽڗ#!5 K S.J %Bʠ B+H#B p/ Lo U29+<1$ %%<:n`p.ġDw4,ӏ /v3b-eo՟ܖS ݏu1܋8̄dnvfޮg8B ~-x/寷ZA0"M-e :߂f ៺owV:|X>!٪ {A.|9ņxQBqHj`l^hUzq&fJgpNSju `ʔJ18 41J 'B0Dm!nED=W ${8knY J),> 2e8.n[[hF8)}/˃( JH}^f KAg}Q| CC^#>_y3W qe0Ct [sr3V H Bf(v!&k_xj~[o"#E$suX wBsT|?ʞ7hs}I :#wN쩸U\],oIB-+m)|b#:7:PloE}!ռ]&o+2~#+*2i:2sB'/(ϔ)[ nVA&$& z,FP#nU[=ߕ0 5v qDZ}+V(Y'q9!tZ,4N<@1"F+X@DzJ:7aؘSr/=7]!s5ru \t3+Ie~j+aAy}ۭ}c_WE Tƚ3!m CQ0A uG% sТEDEAEGI4A /$)@-xI$_ >:~f*2Q@ ɜ< &ã VW5!` VLeg'a &U .ߗTkt'2 MC.5 }֤[5S~l / XmeRlrU2y=|ʃZZwMO낒yJdE,5-b1^`mu Ee  &(MmWl0  _ + O:S{\ nyqnr. Ÿy+|nW kE/cX\S Gc> #Mty XPocw4Bvz`8:0g5:m!˷R*N/04^%H!)&>zܔQ&5v/"ɐNh1bj{  qߟ@jBUxKqm#GlK X&W.dZ ˄:lV*=960mߙ^ 84ӂP1p_1ւY-?^'8cֿw1]1h@)goQQ&/&=U弅C]>J3挱紜[pC>-(cF-wvHGR80 !š :W3ӈ豟N&mLGj䇕@0O)?jGsTT{I 0. ػUϧ+~-*"ի---M'-1 &N~CHa,XO.(ZVŝu5XP 1 YI A :CQlY1bսIR ? %Qt8}VA~9`kSj3tE[#$' 9o~z\JL7>+ 3i8NwVZe xE)AcINr6Fx1B%.1ƒ*IE7Q쀩޳S׎VLqRIH䝖FwnrD 3)Bb#F $#$@@ET( -($Y&`(˦P(Oԥ#!ʬ$*!G  R 1XE{e P NW 5_jeP'Q|e %DϦi)aS^BQHtu>ޟl"%  f\bW=[3k hDi{!491;3rTD~ry|8W1?H A m<HwȏyAJ![ztċikґ4nXefAO YUY4G׶ f58uaFxM+2V1_ kX1vCfro}>t-Y71٭Y~әkSЊGɦ]ʗIqMpjGeHd1d'1ɥDMqd['rp߽EEj(B:㗔0ݴsf|x3(&ڕs|kHcSˇq; u"g뤻 o $hG*LcL c!"N']p7m"0x%(H,J)\zZpJ`j]a1@ Tr]j "6: } """)S&F+1W71*5J -D$F;'uEu,0$14_;: 7C.< 2 E#U u %BP0a0";*'j)rX $0$*0$m$q1t\1.( p3Ѿep, EG0M*C; n`6luwoPKtxϱ"ToЭuȸ@jo O˩fͅԷ; (yƛ̌*(ˌxF2gk2s;|@WJ|ܽ5äx؇!߰0JtsMخMidhgaf^N;͒ZUՠqز5 G4㵊Q}9kٗ\'B"E[~ ~Uf _d8=FkZ }"[6"q !>v3 ekVG"V{7k>/sRydfgk'2" I}h ,8x[)/lJmLd1/̗dD %R%^&(  ܻJ;BOd+$*";e$ǻA_n).wQy_%9cN\.HVg YZ$j)C.9\h Ĉ9 { | J~qv~>Ik՘חHh[5O%  (o+Þ#0+͘&#&!> K[nSnED)[h +eD% v t$5n:򖉬\n-͘Zu&=f F00ٜ4;`YukN1A5˙胶sFY4q>SNO2NߍB4ܢD .~YR((s'" b'W vt8c xxX,t &Q Z<&'B,lμ -mU sb2R" X [hEkWڱI<{k󅭳3t`bߕO@kru ZC z`QqAу`2{b|t76#B mF<_ $U Eldž V b Q > :so{B"wTRr> Ϛ' mv604t e iPLK`K ߖZ R Ϩ\Ϙ < W‡ ֫-W97`@NezECWԽn'#` F-uUE? Áo}w#hi|#z}*G0J.rq(qޅ, g12!G Ђ d ZucNQ2AJb6UnXЩA  5 ]tײ )Zl FZ~z˒{CujNoGvb؀c1n;ӟgѢO, ٪@׫%n_zecM֤hg}d1O*+= %YMARڼ D$kfHnA/ 8EK4 Îkz5mڌ%zpAׂR{KĎF/~MjL~OeY*9~H9& p !s>, 0!o './l9c =40&Ŕ]RB#N>LސgnԽKsL9`ߜ_@c6D95%gE YX߿n%lx:Ppj [q,z"#|W^ސJSlR뿬*G\7I`&^)wX qC L έH ZI 8@ ;%`QUNc:Q].5c v76;fr|3s%YnO-ǶLn﬊V I K?$":  }#) "UkPi!E#=#c^V"IqcD5PHm`3 { ZS6VaE ;f>x!S^3 OA-$EREqG~F2'\\+ֲMa8 iI˘/Q2"*Y5Wɫw$TYLM0P $:Awo@\]dD Jh=kEi]JeS Un; ,fB GU).^e%ﶥi6'ƕl;Obg H0)"#՛d [@n쇨GG` 96}}N4tP]N4ylִr[1fkѩԏj M պV'8jԕPewrMOCb\/dJkF鿃>|"õN42MtإSuG8HE}. 2u!EEXB~LTg]43id]6oH䋉j.D JI!e \]1 N 4dK< u`b1a)0%" ,&''[(I(a&%$> < ! r"$sx"PWr+ VJ 8܍.a0%d..}0I[,G%V"Ub'ho!Eq<%A') (V$D7%:'[g'%0%w(&_5c&!O(TU,%[0ͽE1ɉ+%"u0 ^? ['Gq3%7KcB60C&" =:!FS & $w>y=2ەg%2לٚ>KЙr?U?C;1:ıƹ0¾ŽH)ˈ\UA>;<4?ڞO?aу{/Ԝֹ܏Y3ڛv.ӡ $[%SKƲݕFOӭ޼d#7-ڹ)skI٠F8F0ܛ0߹ f7M.}})!f+TpR v0}1Q|Ʀ*IF -f)_+w&Z JW\!O}XR)^P 9 !v!˕0Γ} G% P40P h"DJ57"g o91;uq %ܔ "u?IM EiP d|=vye42g1*^V of[H 3NwJ^A쮐h }HsNtA f YQN'q-p5)~ ]6&>N>`qqE V 9 mHzZU^ T>e # AuAWBWQlTB Jd G5 + }n ӕ s n>`P4%"0W?Ͻ42`W sԓJy%w㍬n!A>SI2݅AM d@櫭M\[nr03_v.F<m52,OrvA9t1yg4n&}NJD엦MMeI* 4g ȴ >y ,!/ |67PQBF_)^C557). + _# *]]$$ [#cACC uQp5Y BF_lWO}q>ZO@F sauFPPXcjpGϵ:\B;k`VW*]Jiɴ= f Nz7 OX+B/*| 5F &{'35!ab~[zLMP.I^ ת2#~#C q"1ΔYU^3ܾD:pYhj󽎂T 2˗+kE +Sg C˝Q +S ,"tE} e'ySF\ps Sl8rK w"CAi]1(,T)&"ĕ$J!H|5Rnv,.X6]z%H3n߅Q{/Q2T,FgE>9!3('(~#k.wU 0~ 31 T , Ka@.셆[Acd6f?ۮp֞qjqW9JLUkɼm uuKӛA%7X%$|⌸Lϰ {l[6#jp77Air@۠Ū!џɾ{ UsJt+((W4\[o`-Eo.(ae^ipn;I7 ^6‰[&-% z)&Sj,"ñA ڈ \\&.{%;m ٢hX~UA=?a,2&Y۲#逝/<{ "#m$u*,U3 K KsY**7t{o7f߅4Y\Yb6A 3$ /Gbm {MWb#+Ji8@dL T6  ϻ /tWhV|'\ <<  }#8"(Q_v   ;P7Hrz4^c8--V>kAsMe1MV; FW%>LRՐˠ a4y4E9UMy+ b)7PnLs(rZK8lfrtJFpz).I]mR!]Jw{5 yE_F)%5Q&~d4MH"sd} $/C0U )L')12-//)o2!S6!IC%; kq3F 'o@2X;%W [U5J"_6u$LK+ageD/G9 t " *Bև㖺DB-tP<-3+} ') 5ٜ_8KnYO].Ͷ-a=:GA6do `1 OqM~3W# O`L41> 55+fJG{g-.}s'sUJz++4՛]_z<gb[M}IiX|Gg4gslNV@FM獰gBidv¥E ]8D=44V-l$h '˼*6p]9 /`tg v`;q@T; _;ɑ ߷op^syB)b (#"<"#T7v J|K 1 GE88 P\l! IJx@4^Gz}1?/RX(ݫ,M߭ߙ `&Ymy]B0J_V=֠yZzNk(^TRZ-`6`wrVs Hw\n{r:qƎ%8BP2Y-+qa,:~? ].^,c6?#vE- Ctȷ-{ [G!m$+%/ %^(>nRV| m̷.Xe=Qlٻw,ѦwՅW& ?u ! t4t%J&&4:0K}Lu BWx1AJ?|ǔ Ȭ E& >6Im9qȠS(L?Qv^CIt j 7}qB1ĊXL\ף  G% \` .:^0,O!o .U1qP& U '#`U {# Vx V¿aU"P&"בC;tG7;w|E77!(&,<../(WR#\)5(9q(S|+O*obL 6UV z' "q+ 2,<=W M`?22MpvبHۯpa诎)HϏVX+8m$f. foAx~oN  缆 :DNXgފ.錚%+D_@ӎb>2Q 5a}Pεʻ@5ϼX Vxՠd +! F6) |EPNGkY\w8'ECn2!OGE6rib=9UGD 90y8B8?.A͇nE\0S*'Ie*IinqJ[l赩)qU~ޅpcRL'aR^. A*I(?L,΁-i#ٴ<jqPֶ١4!wNwC D3rb9 p2?q)$OLՌ5!y'8'|Y0-3: 9>:D5Yo-}s'׾ tķܳ<e[,_ ,Nk)gJ (:60JW)6U;9z;CݰCDB>UAQGP7NJTZYS>RLieDE2CEE@;Wd@u9EujNRH9J1Ž&{5pVu@k? qĹbPVl9ћk Hc)ZW{ʭ,*ް-QԸCw3E1E07ӽ>;ͬz4c0˭Z=j7M6 ԳC*1| sR1'=jɆ>ɜO5z=ɒH"p FJxLx&Hwݗܼ۠VCEW]QZ+JRȔEÌ7KssXקyVlvpyɽ=zyB)g35`lz\*]U@lPb !vQII-f'ʪr F$x QԮ!/JT39^b5EΔ  |} *t 'c |rA <:+-/L,b! eEK -)6AF9 i@o[g( |},Rb)h@vBB,^V {um,^#_)/)#hJy奚:bt  ݍ_(%d)7hꝤWa9 45hSI`qs ubYgd:Rb%Ή  V A[1 h( V0fȳ6-"pnv0 t6+*旷iU^ڟeixbZ"HSӨ˞% 惜{4N*eIɍc1Qn3,pGeǤ5h ?  gapks!^]%I &}ElC9R5 Bo #2{n w0jɺR z#!A"\)mKTڼ)_;B!pKKnL6%.=wy*/ =| >3 Z2; V ۫ +Z ϙɚ 5 $t Yr 7r WDPA] Lkw؂莆Kn potQ8P*wŞ短5Beo*Ű]=)SgfzyL! \ X ڣp :U .rT+(X9H Ap1 VoKlKvnKDP8CNUUxwMنz(*K 9^O]7.KD{ ^Uw>'v_3~ 6vO*(Y?>2#϶Tq,BrͶGF<t/x2ZX134W;92 GY{·Q1]Ȃea&Vq +VzI YR9 CPDCw ,< ctoV ޼#SB=+"! 8 5iHp^!Kyàu"> T32 :j m 㰖13~'F4`D]p3^0Qi!ۘ t(5U5 5 ] 5D %aq&W jIK6 _ c(c H $5 .zP`eO\R/[ 6&i^fW  Α>01 ./g K+ 7#Cr5'Vm]<28#%&d'F&S@"H|ʺzlSK^e <Ye&h6B%ldڅpB6"+> 3KWfڇ \`=~z\i C|7ؔUCU{wo`!:"M&beWC5?~s܏+-gޓlMAγ$O<*/;'xRo[xgn۫57|icP)P[;CrMA+ک JWr[tmBZO3 ܅3r,O8D-Li:#C_C fh.ψXJsKt L!?".W$Wʯy-eI  1HYʤwq,8mXk6) ]w$@ź1$x=D$RRL|1C铀.|t kx"!g.!-iWZ^q [+W)?O}zs]mXy$㘯bil4X`fg#ѲZ7>,Rp lO"6C W[ȧ*7*)--?0W((+yP/rh.VS0Z=y= mi: 5t&D{pG^, ,$ d^$$;A. m2z+!!|}7yi%FoUO_ FMwhEjyz܌Ӭ:ɋ5s,5'T}a=L33찼Hw{nrml쥍Q倕?Ǐ.i1j#&^ېБq k / ^` x# | fUGl#"OuH;W)}2G@ Bp/ܟ*u%kb"+7'a"݆sdɯ1mP Uk-ʡ02nY~V Z UZ[f:̕ I`pA.P}FQY.^u%$ *T©5l/ }2y/n34j ,N0r8mח=w4ܗ%GDj"U*x'+aGK   4Uw.=v7 4k[j.&o̅OX;< @E2RT8|l5`?vʚMJD, St%-`ylj ~mASs_{B (Ҙ÷ 2~hOj ?*s?%rwȜ1nr?yV=]2A簾o"d$ǔ *_4DFBP6Λ<Lr; |5VXس{ DŽv eYNȣ1 bץ z{ " qp`  OM 9idJ{մl!Ff) wc} X-=  ^[WlipM d0=yepx:*|]/pm8WG@YY>p!00,8cCM;Bk3(6uT" Q۝"¼&'|5.Q'ز)+':%BƐفGU2U츱HuO+J("U8lYT/6q8 |3@,4A&rYh(n!RJw#uPm%=$hyP^w.>2#/r ej9$sd o\]0K"{>Qٺ+)NKt$(C{w81s -$a)i <9@'U(㛲D.`9f ;d\;""l!nt!$m }xE m3%㡝&EeW g ? D:<j|Y!F)3,ȶ)Ǐ(5l< '$aO'1c4)*hLH%!t#(&"8KI҉rt:8Cƕ3g5zob󠙌3:I*FYp(68K3 `B͍YE -vh'\C1bs帷(j"6k \3B\Oc'XH1[rI _g96FkX"skUD 3^sI*&4p&9A5<%.Z lƜq* :!->L?nXG#D\8Z&ژ%ht"6!?g n T>1u 0%)1-wc/:/@-̮".~|t T I 7UD.>Ug )Hqg!#wS U5 w'LU;>n_?b!'.35Ai3}1t`5j=3b.Y$I #"!J #"(+!Q,r*0<$&w'R%/7 .KqG&ϳ $w(*Dh( ^6%sQ+Zڥ*n%C!E Vw҉\yH9 6d *7 P Q" c2|3WٹG”heD uZMZ7 ֮tsZ)Ҡ=;Xv(A&]oE|+<qj8ҟ-#3}Zm/Ӭ;;g*Rɓ]veXm rF*E _7 MKQH!&c5n_)qBTp>EW哦An?kb yIΔWko>'6xdDMCpqWvcM':D2j.\>o0Kku9ſ<ybpgY-z[kW%ruy;_*^!%nWAvBծ@9M VA (Z2jtZܦmԳ!ũGЊt(B5Aw.CSUaP E9CKf2]{:[!E" Kw&Tv+^m-VQ';ޕ;w  VRv6lbjh1 m c߱P1%Rd*+i6Q? fC>+|44-'/V!osA#II%'Jۜ]+O)][l@G<T  )--홂/¤ ',:8 IȚN`A>:ß_o[ҋ h\AǪ0к ?QMj\ʦԪD"߷ש,B1^s:o>w:ܤh|ɪZ>\x2\ZŏpP 5OH]$zۆTf1Z,P53:_ B׸?3I =(^;@_ơld KvalE S >7IwSؑ]V=&/5M*EZUn'o5!D_ = EK m? ʦVjMoQ?#B[Rx[ Q3\+q.,].biѿMzm ;|"Z0u Ƽtw}P  Y)OkE٫4#zSZN0J&{b>Z ɨg~n 9(.5+(?)_3)#h MxށpV )"*##L *QSf'g.8qK[_O{7Q}Lޜn|^",0[h/in-h,.-J'z8Wss5 O#"(`E]i:i$V9}6/x): ZPK:pmEM\Kb@=xƯ_1FvDvݓ !KWurj$J !n ߥO0~ū2" ro.-wne$El;i* *-4zc$] aQeH,| Jr F8%oйi#S.2|O2fs+0M +)d3&~A"(  gkNhr'6 _0ݟ 0m60|rYrSU =Emb+}n8ə`Iݿ M^Jc5軱TJvH5ϐ"h񼠸@LzK&PcN=6rTߕXmtƆmb?bn(WƐgљ 6<\,Jȉ&UGU0C w>ߠI&[tQ7ݶHZOlw 8wրɲ_1%tɮc۶Տܹ3fkhɇ _,#P{!rs=L="Ц r㞺AD!YW=<[7f[q/G}򬃆 T|?5 9r`;[t {3*>4]=V\Ă'TGIV)}  V˘, +bGJ1ɫ p<D/Ta}@6$ʆ M\[.T ]׳_Jo1%W%^ E g7gmi6n撧6kVNQC]X錩 [(H@F}HA{&U nMjw6yKYNއ#45젢o$t3N}d!ң: .C/2l|"׍ꄱ0㔫}xw>sO"n_hcD5b.m6 _LGSnQ8ǂj8zj| /]@l]AW8 ><  otYYn~ sӁ?@BNRy YlewsO)*sK\}H$d )݀A$2(D&!~jvX:&fG E<%$# p%s#}m"ڡ"̞3$~"fo Gla?SIR+}k y# 0-T/]XIFC8"Yj"$%x& ) P,*+'(IJ/Y R C;VM7.%DCy.W' : v F K؀ cGo>^ Qٺmp0%s+ P-{-k+9-y.ë+P% ",!r",%H(,.F%R::sWI5#Ⱦ'ݽ-kN3Ռ7F79m9&9(1M)"n%!)* :T])BMf{ +؁54P1DٶMlN̒oS|tsDⅢbjcȴ2\ =tV#J`]+"ɽgc c[V5׼9R5pq^.1l~iiՑ@򬏨 iZJyTv:kb)ᏌD}77 |ퟙIZr×DKF#b )C {ps,YfLDz/b5m9!#L:+xK]٫|N Lm=Yo.>8ߌg힥4%=0ơNQ(n ),^{'iW mۈ~g혳0G=jсfӔKH-y]{fOw򽳘ib-\gMxv Ӱ  eɍ( r#\s%S #Y<f#v tV ^H"`z08qr ߟ]=&B"-./Z.{ E+l $. \ё^xAoq~Z  JhXG ##i0 ,0*.'&d߉ lM$ш~Oɋ,/ZK5$GrEfgP鶤dߜT;6+ѝ<0({ԫcSt?d*ݹqP,}|'eyRD%89sٓFs؋ %c[L]WsӾر6VjFfr2||i6b!a0aZKc& MUdvX}]_ _7za9"~pa=.['$ Q |du:+b" 7 J ٶbf +c;Eli UJ)RX1# 9[} XaȽ [D)qNI@Y gu#2]~x{. 2;'WN~@*K 26?m2gἴneCpUKi /:\@ָѮ?IG P8XY!*% o^CUߘ Ϣpx=;G$  ^o " W$I4:W KR;vJY +ok T'- V`%@"]N%)++Aq*–*0,3bt.\0o09,Iܣ#q!Y3 W Y׌WBc 5bG |Q k 2.}nì5# E<KSf)` `ql _C5Bu eA#$S$}BiCVqaM5 HH tVA<++*o!}~G E Q$D!f. "Y"n"k#>H"a %lEX C MPe'NNAn#Ñ-%sz` ]ԍ Ȟ#dLbgw&CA  L / Xy ;Q  گV&UUp6"QU{LlF2Ռ: +,~zI@Y&w~SAcEɚ RC1<تs`rPؘ0ר1*c+ۃyq(ChX"K. &J٨=ίϴЋ =y#2|\dJ>!G+/Z`h9""%=pRlSd]Ctq g3OwdQfՌwl}& X?6;Y' ~6I}e; v fzb$ ](n/9(T`"͵%W&񍤌T6鱾D+H4_c|qJEl} y/ЋD%Z `#8Uy^= 8jhou3^F $칫y3gaX?cM*Ӵ,.c;觮ҧނfU_\Ba5\vunBܣ'g !Y -7+aDO"9(W s,nU + )I0 4qO\┷ ߐ= ` MPVG\HM+٘,ct}PMZuhq$Ԑ%uF խ҅fu.n pdU1K*֢Q+MG1џ/CTh}/1 h  2 9qU{°d vc!Nb$"Jsö&HxZ G+! MsKRFs8.bseԵ\"x u  2I 0 9\t i o8f'"b' u  G O\*){rFޥu1Xg $B2mg7g*WHȽ aQ<ELmrBegOm@ޅaLy"~V?Y'pZ6AnHj솒 xƫ6/Cy; ҊހҳV!fwN(酮򼕖:OxQIX\E܈l4wt{w &Х6ǀ?]Gr[D!/3ѯõ[=<@)~SX`k0b& eQ:dFϼ y~!~}6VVN DF6?=0Ye?&sRwN꠯:Ե>F+zSGK*&zjSBn$s~÷ayަz_=Jb@AJixŘZ˂Vh|} X{횃ѭ@ c 4:I ;BHj[]p D`kuRe"Y6n ?;%Lg3@?bd@JX# ߷9XsweU< %$tJ.mg hwC C0(ߟ9  ZF^Z}*'a }4|{ ,}  0]\ßS_sx FGO e/NZ#+: pOpd uCn&W ?lu|&z)Ꝫ6 ~lՃXPX;I3~@)K JLT;^I rV\N %n->2`4{6P480D`+,)}(WJ*4-)].,3'j=DFt7 RUm:tW~2#`%Z_'%=/ /ڣQ)PidٛI $~mT l[ Ed >:?U:IP{h_gz [B̸jK;Z BHN PZgSmE^,Qg s$vV"c9 [ͣ~@T\ (I[1<FH >!!9% aziŘ{*]4 5 ~w\lknh 1n=}P :"| A  %BW+3 GT ;kcˬ[c &̞C/\M87{jv,l%- gIkZVV1M#RIAx7=e饝䓻wĝ޸yfk'>I `Zuz@Zi;%쎝r6S\RlV񢬘?&}- ƯvE|<AcX *1m"}-ugƢ;U<tiȈ ?ȅ/ Ѝݞ `FWJwGÔ_3rl'gP/CA: `45Z42[/WS.z-/i+rR)k({BZ*/fd4n85;I;yD9}38,S$˖tѲW3Xc<>jpiճ %8J@wcƬUy'n)e%hQ.W 6躵ț䇨gw܁%hME[S)+iz50;ֵyH%"' +[܅?p NR `+{z,࿶.q}Xqŷ|H3)9Q~/BO92!8&MQoU_Ӣݓ`/EIǖڢ9޸C%q$h ?cT ? Ǜ X^4,E*DR !+8}DϦ0C3iw $6ľy F*Z 3RYmu^<)sV\k'J5W@B (Yigq螺~8:ٺ|+8pX(SLNt g p <]$-"PdSՊb >[n}͓dG`*6km~8߉ܕAO\nU!y $o5486,qVnzV_VQ\ChJ5Bۭ sݿbkXTksWv2:9iF&Ś tD*Z pf?}=[΄nL!הhRBYsbqacp;j0j"<TL8WZ\(3n_ͲR4,3=ZpGŝmwRt~v*qI\|/ y*.RFS!5OMU)PoZ U 8Yc ?K|Gb%ż#@?O >y;}dRV0*[e'OJO}h ?*K,u< JT ck:D58|`щ;ǣh_ Ib{ y V Qa eF c oXH#:%,M/v.w8+j/(?v0'D-&@%Ь#N $3U$VjJ7/Y/VMO PB>e :ՙf}I@t^5) gTyfNԇJnJyxV&iD 3dўTwQb"݈ X!/ca>VǔXQo* -X b?g 5eu&!.[4"7Ҹ8>8j!7555"6Sy6zKL6ߠ5K$4[1/ʸq,H=*)*a*R=+ o+(B+x)j'y$Ȋ#g#{R#[D#,!{58L)8Qn+>,n L X= OPֵGw)UGPFq@&;Ť؟GԄ#Ob+boAP4,p8 t^,th>K SFk%kX1 vQGUK欌h#^=&<j|dRxUf.۵Z&sTMW~$?m#A3a<*]z5xHW.畩2ۇ\ P Ϻ XlJ:b\6&(5;V=>5yh5xbr'mѲ| p D|2H[?fb>CG[Eb8Z'C56DOf7W9ǯ-'{^~Ȩ?%r"(90,59Vwh;N꾡rY6:h-9?ag,Ǣ_xhg>9 = X vа Zj;lei o I) '%|6Bh9JڕJV ^Pܦ6gTc#%NR\>7!TTLw:a'x`^ZP  *FW)o,˹[q p" G?ʍw-ATm>dc`Zprݠ_*v0-d8Cl>\nt뙏9(>LHK{# wrmGgͲ{ܞ6Eߙ@aS/Pb/ L|#мq8<q2Aa;fvn2giIx:co%\^SFAlc 6r1e"b_LsBHn wVPo k '+H_Ā^r;{8]m~+WAtwv0횓 ! ~B Wn+;e!'EZ5ݡDcoTW#NA53/6k^C*v;_msW8V#9BɅ1Lg -5 -x jR\zZe[>H DdcKR 3lXTiKx6ug BZ~'YhF3l鎜Y逴o;uyP` N >)p4)&4m b|wEobv*t3$vn4 푹9NHuyS*9꒦Wx2b? dxC_ Mvm*fdKt|CQu{R'y)|N"%VxP),&^I&EM`(\B_7IKYC(D `+g"kĜsS2s4QrxY fCgx4yvX30wJ?lSYDP*n8KdbOرPP5h sV pk'Rb*9)f&#Mw"!:!Q Aw3<gLHGR&҇)b ;2Yö~8m(5_5 f HS"YE?/)T2z=W|CH 1%WAuIoٗ,lO5ɤS g6j.E6T]!q?Q ;eV *'Q ,D.E..X,J]*lt~(@3'39'Jc(f:*֖+±H,+窦(0%#Pl" X!E"__\KAB]8|p3$?YtFvhD]/5 39ָ  m }Ƥ.3-\:p t=72:_LXuH 'uUY\yE9/p= X/a'[]\Hi|+\L^o!Ffo>4%/x7 Xx&Ly!< cYPZ Lz^E񌂵mfY+w%jBmXR 9hﬔ CV廤13`˳_Юc= ƻ ySv+hZA%-&Y{n?a0s:|K &arČkagr"km?i+.aC 4[=AT9#7< ;KLdn)sޗp %6u٘ n  + !f 2qC VH ]~ZQgWf/_Vin (uD/4U6I7p_Yn)QZ)~O5{o\ |t:;LaBNc IK1 C 2O4 Uz"/FPa8 /FTi3G3OHAZ/:Q\^Z:y*CZ  u9P~Nr4 Q eq gC ̸ x;alQH RN om i E e:'i #&;X`S;hV9}>SjcHV "8SU` I| 3"tƴ7![h5~  AvGrfJ"fOp'"!槧C GdJ"~. d -2xT5ˁ-mA49m r oM,dnMMD*[PKv2b[Nc-1m@ {q5vb"zOƊ2`7 ۊS>$52O)dRZ-rc0x1n| 2100Ϝ.T-']./01F16f0i.FU+\S,'Qur"u`UF_rSLR \ QqY!{]59`|lGUAoJts;]w3mͯ g .4_}A,%;tS=lO+:a=CV,V-ܘIKla-  L ә i  ( ǂ?MT#<ks:6o{hu Hh.,FTVSڀ ~x5է[xt0/b-5К;3o +n vm)2a|;D/K08 yl<5L;)x'v|wt@bc[=[]q+N#êyuTP욘T$ ,V6x OIg)@YL&oEE젉e+rOXsaJ-A6%  ƻNLxcYx(e*bKyBǫ §,dɦxٓ`~)ᅾI*>ⴞ)o8Bxꕋ ּ\>SoFrZ{#0<.L|X.%95>$(ici-5Ϳ_mTZ( S+T\2%?x 1/x,|F($uwf ;F',T]_** n# ?` \ !mq3qKuAU9B> MEt / ćC  U a.֦iDE0WJSjϦY":$r~+%$#i["tD IDqD[1i1JnyЗ " MK!a( fcB ; ho; p F) 2 + 4~ B _K7lU2*<3J[y֐Z{gwM  m!U1 h1V$;=B_6^+a u&P2t$bq(Kam*5**3 )Ab(_,S'(r&t&&' ))&)@)#'/&x$Z#"އj!e9 J0T4b[R=>c߬j5:   S& Z%M31 I s:qe*Z,?pv DiDs!G.5h4 ]L>P"Z Z wn]t9|k)sYkV S#3q[";{@0/",j85s&V^İzר0CC1Q/GW릸&O;:!񋓳`7Jc"%h_g+w6)2@a9!Jȝ=6jv`=+`?4&BUy);=r?T|ﻳ= ?Q+$*ѿ |NI;!Ѵ;Bzb\7p@E4 es jsXwϻji) tQ˨]Kߵ_jR X4 y6$W˩8KS{u-:hƴlgxS> ^ʱ ? U8"R AY >C2t2KIWD`Xv![m-=ɋK g ` ^O4& kA6;/: 1 3D f l$GVsC6E! N^Ǒ q t˾-+gi?yizk ̸{P{L,iM}<dǎb磸伽sXdf"8 em=u."@O_=jyvv"elU^+jJߙ"F͝9|JA~@jSh*@L} s* NCHLao;/ZDQ EWf tb}4i{G=xc  \ 8b{bph !Kx  ,W^DҁWnB"oTN줱bY=$viɄQX:# m\ Ib "j sW|Tzke*eO-0ArG(6_l7} Д5sZ7^P&7Ҹ 8P -# &)c +Q$o-/X0216@231 0l.w-|s/,(+m*B(&&\#K!#H `;Xk~K@ -G6#=aF BH7xv{p!$cyb<2zDRst\?2+ s[)~ΒȢ  R1l0vvSrةܙ ax[A:HH[0:b`YvNI[`xH)F))_! }N$ L Ҝ YZ҃Hj7h B^C<M"=za|+-v$*O#B߰xs;)dc~‰HJf`"ip]=0ssu뽧)FGL8ϡO?]X}?(X{3N&1^"xXyO'_P8遁T/q ,~O9$X:jk )R >@ N*cGbe"]a@lgz(+@|Tb/ _l?ƹ ;xH1Ԇ .z)hJ$B㓬eO㹬Iᨉ8(w'~e BwЩKt-gGpIwv&||t3>'o^L%lei't_ ʇU;iU!_@0SCb=c`};z'r.HcEƤ&?MO0eOVRCXqT/@-r8fCk `Fj}kgѐumOW-RWW Xģ=QBꏃ]M=g;ӻ!?Ӑ?)5鮱vQD8? *\|$ϔyr9xaA/{= _ >.O"ѬZ΄ `!w-4Qw*`t<X ^H}]Q v;E6Wi/Sd 8 1 ! ( }x '–  N|L d SJ&)* Kv{ p 2. %%ο|ht{mGAV ~]NFQy# 1YOb h~]r ,J`uܥ +Z z1(M /D ] %wlRΆfŝ.A_ 7Z:^B}xi4Zo. P^N(%|)F5,J=-j,U*W( *%#q*"`"R"! 0oLS?qjm nN"&#ԅ#}0#F2 Qd_` h )c]gr6} "CxR{{Sw ^mao:`I{Kk3<Xl˷ b@yڡC3p:OZC(GXFR#5N ,T.i O_-MHKiOKrplefcXh "~NI<Jy|hAc2uUA_$YJ`{Zud$|C/(LF$Xk5m`L5\U3r\Lz+(v;ZIY=.`] I,"MK׽۰v5ŕf𠼒x쐔ꋗ}K&돎]황n{uj!eAW/<>:V-uȪd8YG r/=5INc)"ڏ5 "OP@@C/cKL8pcyHUG%|馂 $ ߬9MzIoﱄ~cV@ Kи@7_Q4oVlop3^#_0 X^S1o/+jʟh0 ~ /bzX>Yыfr-򉥽I4sU10sc4Ə{O^ "[<RXl9CZ M dbhu $U:r AL 4  Wnw1kZfu5}L$UVe_(=jռ g&Td"zW&Eg/E^#S7IayݝD 6 X ' ߕ 4dO@ά3Y4웒L&[SMYLjo^mEYvjvmRROKi] vs@k< i" ^jDoɇy~56$Qj Qu&g0L  lcg@bܾ=<[Ab S ;NSQ2"YUj+qE|$R9JWG9Yv~~MfSy B2h 9+ {jt}n4c/_1UDPO  IF%\_zM2FSEBY:^*s ڑNOsMX'{m TCn+j(42XdcR2N6cX ^{ 옥a H'UGJڞx*j 5!rwH"Tu"e "!l!<cCmJ 3 U GHa\G8wVn/#a!Gq Yh\ע [Pm-}R8gJ]I  w rs" Mx )m3 F[D"OG i b ; l ה 6Y l^Uo B 6 3_5AM^V`NiHQ.5&j<Rl( ҧ=coyXܳ e0 !E @ d$ >$8 9_;sH@C  s5& R+Qa&n+DFIN|h> ~;oE݇PW NW nRf$bT"JY\B zJ P^2ƆS2ma%Tq_{#vH{RC#  d} KL` $#'% ŭ2 a 0b5(</ ^@Gb6() )\z)g17\/w@ lZx؉ v 7I-txJ= nw5xq2BCQĜ\ dYLK/'@~WM&Bcw|t0c HS_}.D2\!7aZ|ڪX('bHZ]$ ]KȒqCѾz5 {פeھB+4!s,'L;9/~?mVNM=t#0//&rn‰S Tm4"{Jv]T= foOWFR=?-񢻙L!͕9r=7DrխZX߷{ 8a3N ,q OzbNx }̙m/cHXUz+J?ǀ O Xv K ;t\ kE 9`T~+hzoi*h j@>i 񠖧k@v븗YrWmpV_8 }["\! R*L AlbcmgPb iAr ֗ [ fENzJ(Uʲ]'7\1  ~= pۊJΉZN -F\t_7,{X)VWO 3loGߢP,&pVS@:VZjm !HS%8"1J a$kOQRz6mlPzJYƘ2{7g:?z  nbfqp[p _ yPq5 k a= 巎 o d!fEI!]y /\U 3$  =õ֯Ej  X _  ^  r 6 D g?< Ke ^8J,^.ygwU ?zL <3ot~ V ?=|T Du=!!jXW~Ԃ)M*wAX4zGf$  5a8t0*l-q͘3!Tx .?e % Nc A\YT(u /k븬!l߸/\%'1c)~mLj5 $MqRVSEu#1 C ~ UG+ۅrKI8`=CPC`/)-߼_L쒗o8ֺi5>1U RיDM\wf*MFk? ޛ|2 C-eGL;Cz2y\t0ּ[k`6 9Ht|M+Jp;ءn!C_hoUUצH zNQHS?.Ihz@,fQsI#[~1WB<}.wZVNE̕;q{/ ִ<0v s=|?s}ŧ3t(& "^'1 WiG;Efx5 iv0  Һ/ *N v< {3 mɹ 9 3[ } %E ; G } A _D"`[ pm0͕7ݗX&c*5J6'v嬉J8 U\ނNd!F4 p j&BR묺"%maAl|Ik34Iܞdr`ePb7d6lqD`lj5:˺\#-@s4-_5U'A'c:;je$; T>9#4 #&q  X mN<5 ujh/ R >BJ F| UIJ6 O4 V y8 OS`k\P9-ǘ3D(pH:] ٢ #TRu]R4 D Դ {7<{OO]Oo\@Q/|?"֥(wz&*=KxbT}mWK x dmr[ 81>q $ ݼ] H Tٖ?T(KAKa$6>ϙjC&ϳja U 2#I3O0 -7(J%= & h6|s p"8 _*;So $S(*4< @uFQ vc E. pXIRh|""0B3y~5O=& wǎu:Gh PwQ ~ ]3'PbɓT:r¾N=SةQrډkWAP)_XIz2,'e>+ 9%!E# ߱lWּ[񗽚(tBcp }?t z=W®3QEO ZUyWR_ / ,5ng!ar 4A q Ѥ_+G F:SF9+vY <(~uBd\XV挚Q廸N4K$q}z{E}OiaX@W7CR뱆/➞½ ꆩELG8$(9D=F<]H{ / JՇS!K[jv5pAx'}A!}ȁPRE9*hc MV8l[2y 0:ɚ3(UJuh# ,2.u9="VF^wM(-7_`ёLt%--At\Fd90d.ML%*5:dhBxfRޙ;z8l`t,?=a8A5̈́E[ppCMaACt(Kt_n^Y>l0[}%βL ~iOgД`;q$^WC3)E,t<'1#1X{P9(M(NjT!s7b}n6g](*儯3'Z5P:8Fuѱ#}+GN4kkX5"F4hۻz^RQ-jPDd%= Uf }A o 3) *i 14t >P J& " ] & [_ B ' ξ #/jA  ",f^~?DTB  ;S@NVlގm aPBr Z|y5xOVe׉4#"˫J&&SY? A 0 B ; M L=t" J/=`(UYJnl}&rǷu@`E7kc Ju` Z" & X - o^  =I X  f E K | ~z3LAWbT]r~/qe&iTZRaY$C6DqR f j\ . k H 뭏 WU YbP8x$%E7r$!deO KBsGD!7ǶxmRVPWCث$OrUQXQkCE}uv6SU@Xa6ozs}O iy4N>>u ^@ Ik=Fy5MI?ژ+#>+.A0џ{99~TLd~<ӂ[{4o ZPimsHCͨ@֪\52Bp^(s#1JT y@ ̄m\W, ;A)@,V4$AG +mkWE U`~O;@#D>*wj~eQ>WO`q56b/6syr oDĮm·'0(PF&+’;e}DZ8½$bp6QYTԨ85i}?Nߥg\qb r .1l([QHtSޡLUQ̇VBӒ8؎9(s|)[^10;#/rZmnV01 k.1l~E>]aw)D:hs[AlCPc\eeMIScy 'tGcnG[[9v#?8[r V 2` GR d O C( o D H z 2Q  m -   'X Y ^  =nZz0ShcS. _ .ʿ  qU^NNon A Nl  M ";l+f{|Q}/QG lytx4,9 u0DCNr4NNV}=WQ R % " | =f (k m r2 ^WP à ƅQI}o WT~XCe`Vڹ%}%nE@2YF=9T8$}D,)I uLoZ"݄_y-\n `Ŋ ]6O2V'xic\Q2 ym j^z[4 \w1CUNdAm4-{zz Oep '񹯩D&zb5BWTEFtBR= 7mOy$1&OɭFU-7eZܨx]^{넑!걩;Z68vFۻcUG?=MqI-E"2cf!t9i|E\. 2v2NB&7& dO+q'%lFe. {Ho1g&MZ3ٳ`|YXWkMu7{Ԟ%e"ѪzeSʏު%4'BuFǬ ze JH^3ԍFs-;s5HdnԗtethlCUaI~ l+OeRL81 u6lO&)*yl?[su,!sP"cpg{mVM\A,Ü^`f+<~d$R]Cx$X% XٕsnGt&P{QgOxHA5@x\$T0Cv)rv"_'mfH:[?;'-6,bLx? 6 gF O; 6 d , i |< Q قf Qp@ ; 7 `A 0Z =!D5N"1+dӽ , ߺ OQ5/ԉMu U98 S$o~O. &e{ {i) ] ޕ] ; ^u ѧttj:2 fW3nyBҝ>,6cMˉ`)0l9s/*lx re Sr ~ O v' I0 |y0  C Vh  l.bv]pD& !h."c c/W ~ ~n E - _?   ?b ů FZ  КLHz%  *#ԑh|+(r&q͏1Gt} /-7&EX!h4E(̨Uk,0]f<`~?$o(j,uA+_?){QV~\l8"{ R}6*9X8HKmt\" Cq*@y""hnϯ"97@*4|dZnBb0s$ZIb $3M{_A& n1RQ/2X&]?eyxxNf"YVFT?FΐjbernX&RZ{3  4dw&emegY6,+nЧD?yՒ /grvWxMQPV37ܸ,X4|F9oK(¯^sMO7R4h\=jEA2|LO.gn/l'V|GAVjͨZ#_W? egq ײy Tf 3 ~eE$PKW² ( R c+L/ф8nյ; h p L #DrKA, ) "5d.voHeV2sOjL j{BƆ4jbeF [e $ i L S  $ 7? =9&D@a~&MPis<AtxfTu{wxrm\(=_Ќ0cD/| fH  Uz #. $}= / h L < p eGPi0MUj&U  NPG Z ؆ P ~ P' u n tuRP+ I%X .i b4 ڗ u.9{7zFk _Ð[#r|)ٰ`ԴX9|ɥuY|kŅg7tݍԦa ?1{U*}@A5掴~(D:J5^{pbDUd?rj^Jct6][n9gvE (#GP*1^M^4VBK<ʰUQ3oπk!`adՀ3bTm MQJ-enM_Dr3q$-|5햇2Du EK FR{ *ّ_2+ZId\Dw @vcrT&ksk,z/E:Y7-E'}BҦ{ &dtMY#S.^i#`]UrJBm5qqX]'ov+,.1&Q O4C|e`9 ӷ UB  q̭ % ` ObGqp+q b 2q\ 3[3/5 u u6 SQ 8 S "o  9G 7Eq9S tH4Q^Fcռ ޭ} K G 9 kaX L]8 YO , p ^d z-@_ ycӗTZ-Ŧ̯|UsRհp f2"uX|p<||TƩul=0U 36{ ;x}c)[C"1n>j쭭a}x+ڲ{4? P(Y/|ar(dl[h+]X\5~ϏO?jm17:,Aw=3N[ .JxtVS>3i?ciPuZe{]wSԿ{~hkt[H_tqJeK=w2!&?}K2wI|Eԣy)dfYËFcT4C(vz3e0*5;TF=fiY(0Kjmi޲Lsp h U%gK`ɓiŢ1ގ涾Wg]~H,9Gv#2'oeNHqv2j"2# | t?9mwΫ~ jŔ3lƿDؤuK2#ڞ"!$CE{̩4Bph*Jvw%SŻjr@.NGXf@=EXrOQY3DU>/q`77fD3/I;OT37:uGUT3PjHeZ_{=3faRHMc"/xzExvQFvP :2m%L'm Zy~rJg;45AZh FaQWױw&9E-'q{,v1>B:x:v#+:A/7XX/kJ S V%*Kc:l\3*H";O9 I qkt X~ m. B Z g - D" 8lOaKq,~? 6 [ 仔 ho 4 \ S! (.knURl5U 3 ԰ `,K*D|3}aoD7ĽDU!yt9tM  ^  <:@JhRPa.UZx/WUj\5w\NJmp,SQZQhELW#OH]Z+ V E6+j):ta"Uyp&w3[R[R嵪1s9 - c/hNՔ47yiAn_8^}.#TT yO &:]F""dv+`DoTS1!]lnp=nļlA[bDu,Of0K|D'_CRn0Z0+uhm5dz'~0G(O(BDÅ#IV1ſIG2\xt!'QswJLf2sڴ`3Iތ,|ߦ^Ò-^K.+2ZòNryRgrqfvsEW)O)'L3L3:;Z:9C19;?pCRC<.M94NBU;7=̴^$.s6>v<@.D\G7GIIaWHD8h@;X83x6[6Y7:>0B)GpJKJGsB;5J0-9-)>/3:C[NEYnd2wn vP{P{ }E~&}>}F}3E~S]`VT~yp{Rg]#KUN0JQHGG\M/hAOLS#Xj{ww[:rgvsQ{M['{6W#^O(/,4/6161>2g2U22^22,3$3T352$m0'-1T)H~%"mzrNaHtb e n j y    > N ۓ   d  b  $ p d cRf<Hxd { [@@'4D" Z 4^xATE^R c / v Xs 9\N'|(b'22<i?1n|z8gH[;nn`PU sr  '0GF9֜uu ݠϕS1d=ܩ;KEqd>dn^e"WŇr_0?+b(5[SLq`H&H&:7;845;vFOOZ>l Jf.@8` zWyyبɎ~qn#vqUwv{h6,!Z5BBJIKIQHiHKaO(SS$L^='Jл&09h?$DGJLdMdMKNHC>;99:=A-FJNONJXE><83/j/1K6==G(R^is{iT\i'ۄ~avWlIboYRNK K Kw^CYl;:mn3g %D*V.1334444445C6?6#52[/T+R'R'# !>U/! % } J b b # t %  ` : }   , ] ' 00wDOUO7 #   |!]Q2}qE -xBk@@o{sgg{ KKJ@www oP<8Dch)MM`d`]]dpxxhA Hg~~z0DSSW[[WW[_cc[L8'3;CGKOOSSOKGGC?;;??CKOSSSOGC;73337??KWcozzrgg_WSOOO   $'+/377777777777733/'''$     fenrir-1.5.1/config/sound/default-wav/BrailleOn.wav000066400000000000000000002735201317357605400222310ustar00rootroot00000000000000RIFFHwWAVEfmt (  8qfact]datawޮ4Tt!%_#idHiשz}U7T N =Ld! M+%`hg2^;BTO3MS.U %á /+ Gغ3YTz1#nAdЏ۶fP@pP◸ێ=8n^|s$a8 (Y ՗ľZQ.tou)6W>΀1@`8EB 71P#oDS { Ňn4  W>%d ΠYXm;g y`B$G .g0E ؾ46Sul|-iyS^V;T l.GaK 2CR; ,0,EuT3%='/)vq]& NIb5 s* ځG@%1)   * Qw~7#xտG߼{n' OiILʒ v LM'{Ǔ}ͨ [4 EvwA9tlclm(i/Y^l:%(WU ^M NG*W0P?3.]B* r8|%&5#+'P2z~UME&9ؕHD-ʥxAɦ B$AC #TQqtmc+܎UxW𜠵%g R!l3114K,ګb0W 6=n Q"*""\եδ3lJ #[̈zF:NS<lnXKV;W__1Tp(:P;t껗_XҶA}N,3H|K+ٝ7(avx&``Ca+hlrTlNV'"o$FpeLVgՂ[8@/cM]G["s|m8NF ֟^j.YErp^ jD9-/7_%,2KV{)umw?r5F0z:$ײ ^%>{1@ Fsi go90^?A An ,uE vf׈ ]kj{P8;p"] Eq:o70%3St}7dGx_(#z yuKKL0YU6?=2(Xfo)/ ?,k !hS@L*B1prnLk+~9}̀|1_ My@?LZas  q }G Nv 1EޅdM Y#!eh, .V)&Hqs9 y[/ 6љ(aҏd:$]x;d lijf qޏ &Mrh{y#) |AAzfd #1rjptzJ LAt_@˄I/g Vz`lAm!  R &4 gʞ+?6=R-w  0!>r]U,\y̴JwHtZ@ z/ n8 1-{~y%6p`5㶆&C Z%"E8(*{%`#$Ch&P$`&yEE"J"e%f(2)A%t~K]#d|KyX z^md~ _<hu4lNQQ{+~-h8;ʹ x6@3JCFBmtsY n &~ͥb@ w 5 n@~YHRosS6MgTFk|HW{ SuM^,<R(4q} " Y[    v?QWԪu]:u ,e' uEFRJ56m 8Iy W陮q{+bu B,9Lia-ꋌ6V0$j~4%rN|r~}8U|u^ //4 Iwccńq ~C@0&a[0pRYI'`W)7v`P=Lg2^ Of‡󈘉É{͇2V3+yKc !_ ։s G Ls. 2j?( ۺ[Ҷ9 ZBxTU: ؂: s4/ Z ${-n,٬|2 ;opppkN.*,ɠK = <ct|rh>pǕűPS4R 8_ > fظ ,9'9_ hZ[A/<(z[* cqg58 bn"Ӷ&<7'l$:$6f%7%̜a"K-m !FF#%<,(I@'+x##`<{'"7O\^|- gd F 8>#U#2 Nr4)Z2A Ca%Rw(Z'naG`K`{U1(U Q,ݮ+* w׶A OKʸ~}W> 'g+nc}QOw  0+6.35PM,l[~ AI#Nw dE/GiS1HuIذ]WSJgۓ, " |7(t]&=~_e[g@򩷑Ӂ_zq)ޜRo/*қ {UՄ  \sZB8w T1l, f S!ƕb}n\? g8 vm8p aLgt= haT?ƹ  ( R? |Tb   6xaKhkd 'caj|c{ZQ!2 8ed}?Qa}'D y A Y~THcoPN!óI@&cQ{\ 1aJGtwuNƇ˹ @`J\1h V"#i"|$0$#ڞ ų !e![A"W\5$%P<&{$ ",L  W~m823KNan^7 l3  d[WW\b8Lyﳒ0)Ӯ[ts{/$nY3~ "tM5DV:L4UYQΥgHPM",C7 ;Tߘb-? RbIl^ h$ v}Fh<A!F~*un2ycI¶,~ w .  M f=Ic,`i(m-.7N(TSp4*sPWZ9T8ꛇ']]qDz곏FZ{N|y{xu휾ˌQO^U r+b̧2..`2k#q%b䝉 \CY٧ړ 閴& ;.u"ƏG't5 F >E@.[&Q:l<?+`Ohh~ neUMD>lr4{0u!M^V*>,Q΁]76-D7x'GA Og#h'~rznO'{}R*趒|$SX.d<"ކ":xHW/,!O-|8$ 5+ĖYGPC ڍ ; [ bF|Xf]1 [Q˸Yݿ,yiݫ,3bHK8PF^7 ]*vXER@ުe'ҊSpxU;n3!qg31|Y5ihqpr E c_~bDb V$Pk3:9޽ob)tN(Mk g wcx  +\ y]¿Q,J9b  Om -8 }kph*!rbS- J e Ac؛ HG&aF'OBA bt][:h + - }0 ե 2za؃ m yni1W k  *=< Y 46?"h/q K6KӀpLd.ﱽ"4> W;nӐh hV-jIEW{s 7s ~d`o9JszfUp\/j,Ǔ Nw.FKLqkˈ e9`̨I!q"yu"#H$&#p! hl@!6}!I#$2.%$)$i!=INWRD.߻[~(o878%X$罈'l1 =7 Fu6K?GP~[7cAsp\YTW Xǃ>T e'tV#؀?-4Z!T ־bDX O!zbk9}MU%[j,#k|L6&ݥ 綈>s.ƕU)[kTzyHQvi ~ajȈg}~{TdJ[V2F)Ɗ%7Xl3׆a1mi Յ !`]6F\$ uq alHĮN;*Mv{\GQsÝ秓iZ^ӱ&AO T(:n߭Q[w8hLw"&K8CzQJ诋v Q}uk)ZFTYƑ i( "黟fBTաD L.4R+`¸1LX ޮlVU2 8[sPg)^Cc-sy "ُ ~ IJ=Ufþ(#pqz3Jq,f 6FasQkg)߹Xw,:K )1ΛPy B #<Ub5  9 !. f* ,@">UYZVt &2;! 3h=s KFvބ>;xYWeV,=}!4LEUI̔]܀b 7a/! ߤ#ОLү < 0pp!e6L"2j/|G|rh_)Y]s5a>jlwlK' }=x >|K&c  '  |  8 ugkYUT#T (-LcC>] :L? y*V ?Re0yN1 `p%@7?)>CDk~츹v7 aMd{J%jՇY2C"k_*ԡ)}c"H8VY$ )ܕD {KGgYqjsc)i:aLד qѓDKEZ^ze \ܙJ% GI R/88iwpZ7pel$ P "'G3$K95f~/mhP'^$fH`^My2ܪvn4@PT lu2WEGN["A3+A#;q%! !!(W3"3Wg4K'/!3&'"`i%y'Ɉ,`)A>QJ@&lX ~w$0o) BaX>> b &G#(k߱ [9%kjxƑ*0,Z7Y.B7 " Cv eƷ\vY !ul !<h M0%;+}ٵ".v $*H-F237&946a07EB'&˄*+' #!V/6יK"8QhR %x򷹼r7llۿ֞`G&;Kh=]ahniZL|UMk)c~aF`͟NڈPM{20\$bCi6 EX N+:kD-lJOnύe"a~qGN#dvU}#h7{wk~zP |Ə4>MOX@b N Q i?~_˂ iQ00G6%=\S(|KHh pDH~C[ׅu!鋤>AV5ڷ/Uѹܪѳ,ܠ<%u09vI甚l3n,􃹘ƃuW  άߩZHt{XߔfB7#cى$J<"?SW"x㽢'ݑh/H,օG }VTp6m&f u7Iz ޗ }L ~ \++؁_%JM 4^N6{ƈo}\7$Ϙ`yF뎄P9-KDc}8%Hq ħ :m#p`|ߥ  ~%w%>"r[„0k ?8% !^K( %q C D)|D~\qб&.*n)KQ'2L(X/Oa3D3Z./00,.2)/_4ee3F/N&(5< FWHXfI۴  )8ek 3"|H Vc;6y:Z<:qb:5~k3)k)`-D-9 M%% pվB7ס lp "QBٗ >,5g 5~:Tﴗk`RET/cyf~eY nt#+'/. f+* 2'!+j(9(H3(u##@&"G&H$<}!U,% 5%D$G+ ?)V oѠ(xZl=IdarѨQirR8Bk/cC#eُI `Wf#4㜩"IppD?T̞BH&LEej[b}E+ea;E"@{`3ӑ-IEG2Z$f T švqj@*To' ,M*t # fg4l/O8A EjN,8#%gj$n{bd9>+!^[o M!cVF/"erc~QCײB zc_wC!_B.mP=B%?m"#;&P ZsldMZhay /Bĉ{DQ,v <11'6i 3 WmWN~ ;Y{7`ӤO"vH4. 1d7!R"#& Mr=48 p91r~:ei:1! ;tz&I#.a%w_ B(aK#- *ma-]/IM/zp+.&&'?&y&3'" ^86}XӸDN6ˆ Q x\$"nW] 7'2vO44@ y i4 " @ & R}f N0{BW ^ @E ŞoR9 {ݐ{2) ~Z *G @]ZǴ>̥yf cMouC0J) PA! R#)*Y-ܸ_3.:6.5^j2`yl,(/~v*K*B&ۄ"<[B x(jqX &so艀pyt X?ܱx )]l,vmJ;W ӊrO^𥽍\x{\w4$6؇<~5TwV孑Yycj蒥?{7@B$+ےZo/AbR]얦 齘$ݚC:2;e*Mr|RYvCus ;Iߦ!5;٩0fX٣pZ3+MM$M h\ _kC28\ɠt$Uis!+G F < ^ʠ3Xv;Sivl xX} PS sWrHO'N;]+tQ8kF$X\·w{)ًGNni>/+ u$ ZyT T xq Iz 1Lk;6D [Ikn/h=ag(|QiD'N[f)'rhOVӈE&cd??@G ˟X"8p$g%E Us>" f# !l.pHRx?A"QYVT8j (;΍=)$_`&s &'&7+@1x2V.rX+Tu-p5j-? -T/$&3/)#1 ,k "tV Cgu3g=gMɮU1sJK BY\iCy~G@vw ,%dM 7X8B{ݸ1,w`EϤ `x \'@i 9q Ϳ }S=MuR sNYT?[ *jG#T|RΣRa]S-v#&P(Q'{(\|*VI(8%@$ T%G"#$O t$ȅ!F t"8"++'ze ;M _KST|u"IaGXOGPN&eA6DYCGD'#a_sh|亼L0wa`.-uifӕE">KH&.RG/!T 'qZiQ/򶵍dSY9S'Ё)sj\ 3'R 8;Jc.[$*[ QxdrMaE Zrpw ō=ݔtJ)[\@l+zolM@ņT /`0p&88aL!^|TqWuVY:U앋 H~ѣPCdi'"/ r'LA4=B <ľüx^0z(ĺ?aCY0av,+!ˢԃ#N]^~絺!JYew\ҫfاMZ⸧CFK -L@ *^8qA\rti9<*9uK{> f&$ Evd׽t} l  de oѷOrrд =6P B kֽR#(n 6 . Y K w` ΃ 'fh41^-R,;B :rr`^Zt _lv1V/G? ~Wi"ɰ^;gg;~ u6OvwzqZC EϨW?q"ntRvmV@ؕIπu}HtG noov,Aeqgv% n$ IJ# 7g j AA}'S{kioYy],1Ŷ'44" >loOR p|?'M ?J9n<e25!;!݂/9$J)Z5,zX,+ţ(&F%2*_$+$3%%K" 2ք d>2w "<v y >z-ݭjQˤ<2e5 #wv{NyҪ`6{, 1G;pM+p)*J}#ֿx e[R)'<bEmEp쾄Hi.ޘܸ+4Z^khu [Oo{֜%c<b>⺿ {s~&?q/Vsn_u.4.T+&iSG( ofmAC8Ojj h@Y|9}|&x'f~%*ݷpݢa* *rឬ+:~C\fa5@쵊k9nX캈Pi qE]Qͪʌ Nd|8=l ڂޜ IOX~ߋܝ߳SsFףBU8ڌ:j7n $Uzx X ܐ\ɼl K ۍ&; `M(98_M*/ f.SnY}z2۠"r಄~>&=اz {?7%Mcf1U#Q]뮛,DJg91C@k᮳I=O J"wږm:߉.^%l' ( )  qi'Co} @WlL丅#^Ai \eIs^pZԝ!| 9 WGJW^Mr,8:,Qg8 ?ڶfw#,"Ӟ04)kC '89p߮+v,D 0XL  u!1ZbX%`7V>Ьe<1,S''022pݝ=ݶ3/Hj2"L!Ut6++ad97;~u~=C]PEwnU<~;2Gd`4 u j5ԃzp9 *D Es|\JVE `AIx셽  ~a!ԇ o8 bp|, ( AZf 0O. p3*J-/))Ȩ0-6׭N8-'v1`=u.@g GiGќ'KHbC ?6@C(!p LD] w=%XL,[1n,bZ0&Ř*{.=ty-^R0ch10Q,;=#YWCC\R L~E%?"S5++>/'1>uf]bȐCRƷy$Do$3ZR+׉tyTd&S mRRT@È3VvJuAd]\u|NJmR&O v 9y n q ʭd xAc+,,% X - e_D(9 E2G( /%UtVJ {E28R9#[lV%[8'Lql`Siⲟꟛ}G_0jcOҵHPH,fȀ{ ? 4w3s=x ڵ .En;t?J25#pKXr?Ms3߾@h08&+qvcY%dmRvg+ mfMz502C([xYSO'F.yp{+Q)/_'L/@\2`wo.BW12 0\"1p !*aL #6 `FrSV -F"-\.4f9Ӭ8ȏ:S1@,Ku@<<7O5BKLWO;OMlJF>a8(l9h/=5ӑ]+҇"x"E#)+d`,-8A+d%{ EU<䠻QcTޥQE/YXνRd_jTot|f x$}rF@*ݱ.E;`q9[,2bU~MxH{;plXYۆ47o,2N:ޚcB2=Ls 7I>+="S&&S/ר] O3N*4 i -ӤM$Co*{E % ;&뷑 [rϢ=@Ȑ\}290Oc>9árڈf~Ef-N~|n`rYHŹ0t&o?`Kݿ(u 2x+ j򶳃I\\GGj x]xcE|P1$ٰ)kbf2 S\V/ߞ:Y6M8Ϸ U{yaBDz- cb4 cOsΪ4T0\M,Z0z1l E:8^&.0ėc-JGy `"P"lKu j!=`Ii|~J;.Fڂ4 7Pɛ*1Yk垽m޹X_1E%YD㨐Pf[~7iU]MtV s Cb94(c. H¦0jr\(nb@꠾SaJs1%KG[`lL썙gx e-Gy(9g+zZfX'0^'PVCdVZU7>%m)*!RͻMUx! e ^#==@ЇP O~+ O XpUJ$z2:v571U$N!'Dy0n68Q*Mq"G&"!+!} 6&(~vvY6|'Me=z s x-{}v*%ŵYup: ه5-(p <c-m E* {϶Q3 GXPtS oH  3(z ? '4 J=n%_&َ+:6*J)")504i4+*Fy\/i5z =EBEzPEA:=U-6:oi7!S?<@B77V*0'L+.伀4hI:8;92 8sJ1*M'T&{k W  َ@_!B.Gpͱ0 Fzig7)޻F!7ժP^f{pi˵~RƑD@̛:  xh\؈E`lE L>VP0A33i7$<@沺ݲFg2txٚ۔'/qg@7)󸐮_wQ=r8fGf~0ɘzx7GwD// BBS܂c[A+8Z5 7VrZad?} IM/.tczeQ~PIlt.L/cvq ;j)9\VM/+^}qasoX@y|N jMEMgaV =rA+Gؒ" 1:ГqW`Ma   w7\P)| &KgkgH"~P(j)&QS$'p&W*>.0*GK$ڠ>0@W^YLS~C!WX*].l+r.}!^`s, Ln.DÂFy ^3:]:~ !>Huo.xj{pݚ̟bKKCʾɢNj|ɋ4^ J:һ]5Ħ㚵b TiA-^\AMUݷJ5$ĩjBSŸZJޏ*"WIx|'dyb V2?T{yrQcs-y oiږ\/!I"y&i::V[0ٰ[ϩ=dO?v O+r5/ OWdj:5p:E(`d IKoBڿ5`q*= &D f, l8̖^x>6Gb7O`|퍁*G"cS(O+F<9ѹ_J kꮶ'"D軓/ZC2=RC%vF\Bg럡3[%0uCyp3!0jUqb#Bp4)c݆O7,U `z{A]J QF>g^#PtvzlR>}l/{Z^L^L_ \df%&=R4Z?/lKjZ3#Ft/X,p{]tl]MO;=W)v'fHFVQm 98 &MtZj!:%Ze0jwrXӞ32U $Agiz4M]" Z~@M3Amt mR tX"4C8{+5ğ'78)8dTFipQG7^Ҽ AH ^C&)iV]@t/ gf^/]Tm tb !S\oѧufYfN<8LzqG &ѼwNN,9}.c C!<ƒ2; A[y΁D (G1 /Dz# 7takB!"+u k(He%R&C I ԿC2q8Sk c10h d'>a$Dx8CpF0J NZwp]sRlFb)m0NT4a00L*! S* (/3!3+} %{!ZMeJa$A'$Fo &U5PA^JcԚx&\|>_X{? y S cýQ|f,@6gD 4#! c _<4 a| ]Z 0>` '+וn*Z&}&ol*--8,-YN/+0Z5v<^@O=w8L23Sn5j6s0422!03/q//w3hn75t7C0&H0)[$Bpv['d5U+{Y7f}T`z,ϭsXmD`9Iًh{FhF0ҀvΫxҒSAhp3xxZ$g!y0`ҏ=nvIZ`\I\6h | 栶7'a㋬_z 2`p^"X>fm+DƘ!q72觕>m{m,]|gyEQMD]EV,@ b*%1GBw74\}XZu̢ 52/:t/ f5n[ ]X|M5;9e\~U2Ǝ#%$n"I)$u2~ %*ʳn8XTAU5Α5l:ץ~M%>Y| #)5U>ꘂDdp}/F^8mW?&Jdd`$  ȱ9n1%`pԤT@K Vt v$,Vlx ]ֱ 7gz^k.4*$$#n6q$o%4$;'^*L(+U.''!yv3făES[~3`+w"5*u-{h*@F"˼8( - ). Gooxd?B0p_Tb(%qNM;JI . &K s>q]"r"mnqX +Y v$!n3E >bQ?.ZX(6`"NZKZN 3?yJ= Bd%Oшpa:)GzY? X_7js#wfR+l=8q̇#"ớF4 rGqy O[Q%مP۲,B. -0xp\jg8bh"{s <՚jZMyQYz_L n9 ]ԦLEb-Mu(v("e~9 Nq{ ~!50oU שׁp 1Uѐ#x0X5 . Tީ~Nqk8;64žc T*4J ,B<{-{ sI*2,%iig)UeR[߫-=6p7L>KG[6i>讛op /9'_KB݌ݥ /iEnGU q*k9[V9쑄2b~"\;ʸa&HTK!,AR{}q,T#l*_Q+o~쒹"}*.o6wqrUpzG>?뵃zdunZ &[/3mc*;+W9D ?~9( ^Jll=`[% x @OQ%`U 55dM#&1-IZ+ *w$I$Q);0 hyZċ 8<B"H !t{%] ;2V$ $+hZ 7")j!5Ϩ; ?J[L{MfCGS]6 "V+(2bx"p8V<1<8^4%%A5/' BXonC+'@^,@߃DLu*<#~A򈗒Nxy'(ON<'<Fq3 ɿS BRh^Iz 0yZ2  Qiթ Nݒ 䘁ե yܦP\yi&|#ns N|- r59:TX!'*) 9~262mc-f 6gX=0y)x/0&CS+71D52?+>H88nm~ W~r'!{ !3 &J-:vđ hcu7Úڏh+='@˗Ǿ^'$}΃ƻtA韽.$|>i͕߹l [\D<@݃syr۶f`GVp3r\0;8 :M/=7E(AZ-qmoxWJ6*1t/0e3Qz;8 -4L筠يL8|Q!=B!Ž ]vƉyզ@n9㨋Q$G1*\ ÔdJ֬ЕBJf;؛;'PQՔU0umM OZ71@=mhު6R !Ax&qHFu "?Wy:{uӰNIg^tߧ5I馷y_ ~jb˙RPu7@=Dfw Ju&O؏ ~IJ^ SNK )7_k,EUO7z) DJx A b&lE8՝j~r,{p"9 f4N b x ( nU"_*H(.f,)DB ۅ"A*Vc+M/10xڙ*5$02F/?I&| &RŲ@<Y!i .y2I|G'RG[,Ҏ31-:(+n/Y+d% 6|=/GcH);=qU_p!h\NdB37NݡRuOt%{C| zq$y% rVq3dBWڞMΕ+D1grXOAM-(PR ȍF A  V4 [ :fak ފ  n a3~+1k}n x 1(g wxb klm>- k K #\&VU)b,L_IMeK+V#BXgNv!u]S vt H3济h`{@ .ւ\4@70 Y)r>d G=Q\j@?e='?_.a$5sbYi~hAZv%ǐ12Tf _t70n  N.C+t2o&D'] @ B:cAhKbvlcu$E3&㔂AR>m~Ae YV"MzQ8Ǽ'xE 'za6;eIGmfCy¨t┓~2i%s4I1+D#Zd E ~-F}+RVKib腔{`gd'Ȥ$> F +EߵC璯u^Ocp-!Zn`dBy8{$u, 'ZX ǑpO^evwqã!b/7~^ܭ"bR.N@S\J\\MCGe=6U.Wf[^j {a( !QS5g6 |Wo<@Zga? S DGM'5%  d?Q6 Q8! ,^G!}#w#"$ t`?; BŜj "r) b#ѳ"„$St$`N!0$ND *0 6!+8/4!o( Ձ-\,Mk/Wͨ-b*w#356YlcXr wQ,sf ;CRN䭩]@ Xǒy/1/4P{x[~63d&_нvuԞhc)o8TeL_ 7 "rE NX(xT K;u6 ^@MKCV#yQ (G%X?,ȫ/ d$3P024Xw/"-\,(0/9@5 '/J$5=$~Cs`AJ:3#}8Q8[.Py/17/5#3tBP3 5آ<e+'$ \b i *{f ey鹻*3+Hj턶h#/zS˕;TLh);_}D̑R0o|WW7=弜)Hf"402щ9uGr,(p]`<h6e'K @Hʂt|OqL4 ^uaUDt9%$:y`cAN=\ e 4(jR2h93 Kf%P,Ck͸ t|j޳/ `?FT*XIDRp 'h=No(s˝2z^!TVEzMpo 1Ym3W!#JJa]'4<'iv{Ho^ΔۭcFّΏr)ԇVǩhad<]ZlGX10^s( NL D؎K2T}] vIO#s`)&`{ _LyӒ$f [m!KT_5Zz>ep' 3qG&\*/'k9?|‧zjx0`5lu c*hR* 盛Q57Alu.aXPZ 0 4U5qǸݤ  hQ׎G(ؑ_?ۏmqd9kݡe/}Ky+馤~ u<$*l3\<Cq\S>k.2H%r ډgqτm斍NUdM@]Q, 1 ؈Qc<ΝdOcX&*AKZap Q"6U T ;ta"$A",suq<ꆱCpxRk߼hO7!KM4\  I{)>_.H . bUX*$DžL,{_//+.>'mO$H"rxXx~4YkgBPi{8\ŤBFn݇3_#c'Ex*#.Jk,Z;0w9*D Cɽ8h5Ԭ9<~,@n(G)&QXZʹS9J HlE]@;)DV"h+w.Ζ1 2g4P_4-YA#fklN굀DI}뒪~ uDZ\d͈I@Q[+3 sTZ +g u H5F.0U *Y Z $. :a * Z .߬8rCrbh[=WuQfqIxYfz ӳhjs |[MЫJPm?y ~T򪺣+ آј3\&~C`~ 3 mI,ll7.E)4wM9+deG.sf7F㢋dO׋ {/+7FCj5F Xcy2}8)+I;Y $h ~k T;- HC h|M Q vp#^n1>MpJ%Er6fii*=#^ye٦H_]9p=Doju!W`aBN."ǍB:?-8RWJ8wVJվ]KVN^Kh}={Ӗ( z%O1z "I?nr].A2;( YWM\!IЊxtݜ3;/ŕ8Hj^g1(WTIŊ~DZ\ԉT߇/Jç2^paSgUiL舸` ye犼[?80 b8CMf^MP[D %Z߈RE7! fa [w0DZ2D[E${lvy/+s2!7rcׅCQ0QUn -߬}O 9$?*qq-q*?l#6i3-ط:ʸ i@ h(D+0P2 +--#HgYC !W!s@OIj0!TX# E*x2q79_5l+B6k+  )Z y6ΦI.:| BU|$iL_bW h{[  iXa8j? .)D8Ic~ }RѯB%w'?(dʕ'@#"9h"VZ1w")ݒ)Aނ0Es3$6 <ʣ@BB<52-udF)+[y1 37a930s/]-%Ё&6kg ,   ~K3 \b/e/ ɢH'P|;JY8\ |j7^PEH^Y 2`2!Mu{9-w.Lݎٯ؂.=ܬ& CT !靭2d列2Qi7Ͻ8w|@ 7NO}|Ȃ v1% ++J>an@UHɀkM=ZվhAbη7jW1xD&x 2k6잝`mHJVnD1lZ<Dʀ>ȗ , HN麆̉疲EM]h":6J4S)W#(d^t]-Y~0#WxU* l.Pހ P㵅'ޥeޢŭ^=`og G5^uߖtX=dDk@MxS(tv,41aʪ(!M' { 2r^z6* k;H 9c z0R}7 6*O.{_X 8t.;kc5ɵ c0;& .R" k"$!MT D$x**h-*a5!z#ǎD4! "BP6$cC*kђ86:=4mn$rQ+"W7>ͤ2))Q "%r-NQX8&cU/ui`~RDY/sOB3dV 7ƛR#N3kѿa9 68/3^;(0םtDBުwąKO~o914dO~ǠɉFx}&Y;.{l⥐((|]dB̔ B gՇ,ȒÖ`\)+\Ȩmd:#Jg=* ]`ۗGYG1;!kdfj`n9r}2 SڗHDQF ̾X!W q(lgq>X팠djGIsR"b*.C55G$"Xl$ƻ$'Dv[[!¡'u MTym /jP,ZT t ? A_9USbP+4VaS!؀W4!z `Jq4q 5 bQCy_^q3N VrD %HM>8 )4lZ^^|v2u"U^n i,d3I(%W6X5̻:h8c7 0 v5D.5N2+ 1].b:7%7v+=6# $ dK R;; U7̦fͰ^y:nCqsu~g}c;$Y3FQ5T >NvZx wX?өo!Cur Zr{uEG#C79TdY[5;"/鞼gr a;bU|&Z9m:^7; !'dfYzCZ .= Ao):R!#[,527}73[:4.Ej} 2vQh{ /%㣩 Ol0RH|Rc:*ej+f"L*~ejthp6 ݲB.4޽0ɨ/m!9%_[ Ćwi~l^%VXHR]#v(,.xoҡ`ػ37׾C |ݦ☆Ѻ $Iz꿀o-zb^q)>NP쉾D0 WR=<>OxU Ѭ<xF%4 2T^Ob TcS< .  'ܭX_lUO>a^dNK GC~FO<''\c`siz1j,rD wM"7'Ŕ^dѾ(ӏlakg|.nn?q%9h>&O6 jmˋ볈(;qkhw16fI ՇTc&h D# "tQCZ?~wKBEbq\G#" =V+שLWc= \2܊AW ŽJ*J  'V)Ue$>y^/G]:!E q;\iyDS'C2zo8w ߰hQz / W7D/e e(2,ĆL3\//.0v\)%(""9$!&xջ E< m"^^,U-!LƇ$F& Qg!kF2c!g,;B rgO m ʔ/ xRqoJQ/?=x+!DM7 + ;7/T^I l* kz"X.஧EsY'IgC0ەmJ`w+ K#Mә⡤nFf 2gA㈴Cj.~|%\A~&OQz3 3ع[,( /ln º1Or߼ULPT^+7/?^cL4/AGIVCӷD!e%˾-,^l\Z\ﺩx3ڎփiN*jAKA?'4[(N z`ag"A 0$gĶ { 1 g w; 5U6TtE,,t>u %4%h;B\y{$Z7+$c E) ;$# :p!:QIX]m_OP-p'u0-N)%.$# (uF.* .{ u!4](AMcRMSALmM?4Й3(%j 7b jY H Dȥ w,,@E'U|KXP_F3|z4ePl3ҧ_'1kg;dxa& ڙn~f n+ց7Z$\Б&zs^*A;#aR!w14#|DD$6]saRQ)>Α=/`ϔu\MT z#Ao\9yu(So,~_f"p0"'RZ#<%}E*Ҹ.2I..-|*'Xv$H&Z&!GTuck;SX lX{pG5F]N !)A +R'%HW{:g<>`{/48.J쐞鏽0Γu?P. -&\y"\zLzj w) 8\v]&T'E@p$"A wI^;X$G|,$! \Cx5 RpEITMN%16d4, Z. '+q}KN3 \qB {LMw1D;jA!/vICߨߺݥݰNG>mAfT#9Gm4$@l}ࢨMؽu(Նjb@ٟcbc i&".t{[+Ričtl`?@j׍ƕsZ{1n<>2fEU[{d` &Zyl|IYé ,r`M-/1܋c;_ϓ B9B2.XBʮt$MPF9pI+wᴒ+?˩ݣi>N`uz@mRcF/#p Nzږ͘XEbbO!c]g8H㡊,{צⰳfsn.Wt-ߗ$)[]V﬒F䚸[g 8 L,!-m:D1N g vn)m5W(謫;(6h7qr}ܺzPq7P8=0s Q < ֱMZ5JzGDMf(&ëx:y9Y$+,++a,zK02w/-G(fF2Y7 8&,  : MpG*Z1LZzk1+taU%Z`Bp6 :^UT&\%d;̀~$2,O"mFM=+ ƷkUM3J\8V 9HgEMjx Cl> 6A`qu-$Ut9W0c='=_YţW>c@~QzH6? s5`G Q+72IcE-l ZlH0aSi$ 'o_+W'X$# ܜMN($p$"%"vk;X_."k",7) |kg&XBM!.#ɹ#'2"W\ywɈ&|8 `g w /e Í v5z냛n8Vi@ Hڊ;˖%lk;zX|\S#qTZuk~P< }$TabSf6jJե3Vy胺3c _; j蓮B\4׵RT֫L {|)ȵpIv$j>Pq#7D?l]0N (p2}BQӘԪYՙwU:3v`Sm&5SJiX>Pӳ-,(ψ4Ƕ+S򢳐HQM@rD rVLHKjXrHn֓,bfYFk"ZtzҬevڍ+y-*b\. VT%ϓ_-uD^ QMҞ!4!yg 4j q? HHW )ƺ0CK8w>6T!X#UIdB?41O-5L{c$ec2(B,a(J@~}DL % /m- $(ga$*p/C;#e'Y)s0;DN{R0QM?. RxYn#.Z)[ׁ S/`|㘹^ 񳡆x#j\A&"crW[afևϪoy|NҔM%\ɎW7Ԍ4TsDA檍?߆٠~ϟ;u6To͓IŪ1:&um:A ;b䦴`[PnHEͭ[zC /?༄`~,E~45_"^C?_*@WyfU)IX!Gث? jب1 'D$lKCPUܟsC'e~@ l{ dhS!uS& 1*.` X|% f > 5xA1#2al };b ^; }秩 f! ʈJ Dt xV} *%w 2d t$OI B& z b XиDʹ1eS  8̺SSgrcgJ)Uex p #rwY#-Yb0ka H(?#Jqڠ`&I.^ґ/l*~!bB 1kڕg Z_vK |  F^f\&{#: * {+!`$FKw`hZX*#%Fe : Rn\#FEy)F!T :9Y] h(tFI$_7f=)I4uEfzQŠ A sk_锲IjEx)ZB8|{2. E+fFwf֋P2Ay߄(LVO0'&2 -+uK8Of/,zoWTA: lnj/e n <2tAAf79ؖgx_ˍP+ՃergqHkZ A q) B銢mh~.LFhF~uu,^7 =ev"gCd}M*lojGeT;{h9fᱻْSK%df$H~[ &J ]~4*K,NxʐmBVf]]Afxh[!CQZ15"1Ys혥}w kWbf`&^=#hBR}C!uxQ#s購_+^7|KP/ET{_$&4bR<դ.ax:n q0 NR|]ɛJ5s;-h6` BEcӠ ޵0γ6D#]괧 =ַi[>,_"75[jZ#;a5S߹ F fcf1!c,ET _|iBym@g;6q1t/ 1$5Q4I3؛0q1Ž343S$66RtzT H)@ = ۿ8J /sZ.)a < u6T Rp0 fBo#MMtO&cv4c 5G|aM^*t ! ef?\dmrE"XUb[Bsfb ;~ۦPj\r1N3=AցI vd?JM  :{ <r%;" 3-| 4 |$ ó Id {KFkg{ s * kbR=EOMQ E& 5 P W eR`:04 Vv9ܙ .-&B/fsO!fHvlo " '$qa-z= T51_N$ i2,Dv5($s-{T, jt$56kGN&""s1bGv`[:[uRV  Nק7,Xolh 'ڧ!"2#WbJm92{Dh zU-ZrT ,{KH6zG!c#C$%s!h9{ؕ0{@)Cf!yyvhj %uͶMexg51!fS'!d8 ⤩۶Əߪ;PsbmxY>Al}Xug%Ls٤n^4t }^ZۨgE_5TKFרBU"NRjXuU$12*].Y"La&~ĥ#ϮO=)xa QCQӝNeVb^8& }( Sߡo ]"ެ-'_~,vhM"^LU}aGK':nIa # ?*O<ytP :yS tn iIL?6J:7G!͂$IUu &J5i#M%VI$ :Ȣ9CD =T ǚ&^4e'-C(V(F;ed ''!㠫kɾ[$7P;`('JjPK G4;rtm !l%x9 yT2fQM7[nYMjP zOv^ǜزceLat_yJ]f{H @踱FpkIBU8Zʳ(bf9SX C+ ϱZ  w; _ X %7]qYɣV`7:* }[ J_y-= 2(E ;j؞ (SUN=n(qg:  C\ VO6Za8ip+dDHvQ &,A|E[T *Uo^lGzp?̳ (BWO}X  '|  ( Bx|@d*8HL2jk'a 3A'lI I)p /h3XO[6njFDPhsqDjmi MvSY]< ~':-mK П(myrrwŋҖ 7 ae : H|12%P ݌jr :NrtB%X +~4Zy_RaRܩpnQ>'l}`vϻ咔mǤ&Yk7m~֑]f$[4A޹V`\`8;i21ɥ%^2_ŵy![$Nٟ6G?}<ܕAy#h޵GBjuuloNs?h3AX ]듩鵺b6>XVbٍM4|Lz ͐@tWЯ/6rP%OT-t47:uhQQ5 --;dڍRq֐SQs|g xT;eG.Z䈣NUNzk<)DcM0~W = "9E1  V [ r Y0fD42E@#,$%"^g|z!;EsΡi. g / )E f ? `o$[ӊ \ZXن6e%2)xol, .-Ld*BL(Xq) 0JK9y/BlnPFLD}=46*.,3/(H1/D*>C)',dZ186Q9:˨::99j7i50*dJ#-7dl(.p & i2X lvGa\ܝd+ݞO(i8s䶪 ulXBVQ"8)֪) 'ﻨqn mtH՛{}NyA9$݄j-ܣ`XΒm@2V_]qJ9ޯehݦpޛcg2;^: ; k՜M9wb$0PHa J =o;Zmn*G8(ؘ W]MV b D &$ `nAmE5'0սea@:t޳zvuJpV=(  zg'{h jfe  1}5Jlg' n4[J ATC#\vԀdjRN8#"i!iZOfk`!qW9B'cg]0H9K? N7j$2%"LVB5M(h<+rTi~%@wbnۂk. J; @ /+ЃGOId۰1D/Tb @)\q*0 ^U 9 +ofd t<fHbbYpw^~%7))) %lk U Z 2@1kE=)sb@"BXk3UBBݗ ٶR=600M<ÅDE}i>7 Ek 1]c !v?hQvҫ:t#Y 1) s|45CܾyiaeXM6"M^I2b`#u`!2oy׼(bgNɫgi-A^ 1W}"N A h  } O%WA.( 2 9 3 Kb%5f\qke?/(l>q{AV_퍠nX|X/\ c4WSr9~W1 ZB] 2 [^ znՙni,\dΎMA ԂYN4+Vy0tNI!##K8 bj'FJ( rlyCi{Y޼ޥAL꠳k/s?u'g39Z~+/0]$lj+QּjmcAT*Bi0&m@"ޯx3~U$( E)a v_ %r3~OHw~ ~FrQO뇆*\n^ov("hL "̂ss$ E[ +. #l8 5T M XN %gK{ mOQffh }Q+! B^#e{#zʪ'ϼ o'<` /- + d[x,t# r '  <0KY)aߎSyR S ] h .^ 7r@Qˠҭ\* Tu =T4 _w4E $`DgWZt]J Xv L)  lXȂ,m!D IOեKMCsAI @a9 @ e :^[AA: a ߣ c\cgK ,46$K1y<L r u< S rw F 3  Hݡc$S4ZKRe u mDz [7Y    % (k 'y W 38 w\Q`=4#!g p %HKihWJ?}阊4?OeJqx T#bf8P#=VrG(.X"B)g}rW~&^wյ3 g7 &eR&*)@Epqԇ;KvwqL!3QVE-Gt5IXT>}zjn 1v%ɛ7mwSO9$;UQX`(oߢGG%"o[R3+~9=n_nsnD$AS$IS/V[BUze ͹U7-dǭ3i$Xct5&ZL]>c)]aWN+uJ黑N삃+KURCWݝXV % [ -3 tY ɍ | Rk1RT2@/JEK,6;Ώl& 1 |K'.1`RCb" AC T!#1*D.20B/Z.'.h-+8C+-ێ2092@OB=)AP=8+4,0Y,̞&2*  V ( l#)-)/ 0ɮ/i2,'~[":"9q)G /`N'Bj(0vsg<05<䕭dx:ڲyIҁ5M,~x Jmz{幓?q*:!v'Y/`ttNHۮ*Tع0MqـTRXܾ.2߹yݜj} t,|h}UTEd-H Er x[ }dm 7 s ~ : a: a Δ ) iq |j _P Ft g  "3DpvQ "13E]>9GO~7$m;|^+R@4o7@1g{H#bȀ@ ;掄l{Rj,&c!jw!/fMzTV֮ > uo E?;Z:$pt Zc ȩZ0zSc?Dx)U [r,PRh氨T>2f/ UBFJv]< K9Os)| Z'Ik꼤&D2c+Lv8E,O3YtZzΣu*C֐ Ƃ $M(arD9d6\0FS0I|p>8QJQ9t7Dx4B.cBޛm!*҇jb=(A\Mj@!UN}b`32+VsbIx %́sRT r $~cޏ V+=kM ^ Qyb<7b !ąbÀtH{)!Lr4!FPt 5Gtc grqà ?3qmvPm® հ6Z3djوbG2o ̕؈LOIaqnT.]0yZf_;PdV^aM3=,G^VH7)l߉@1]N : \kYUrv ˻@"Cc^X|wG3u ^ R/ wL `J)wk[_5QY7  W J l .#bH8 na ^C|EӕDeJyDr\8G k` jczLi:Vg( s0V$UnﯾLCs/V)%+l)y: B큃S-6ͪGu ?S^s{@\,j Wt[t{AhŬg4790qz*IhǾ*Lw|K^I69X=c{ <. : U_ x" Wwkmm'lNV}D~A-~] 5jiZ"U7u榳 XOBX790?iΛ [ :Yq NDZÅs_N \  b9[;࿔1 <)h5%n ~R 8Nh P K5 tj X|?#"-&'G<'&D&a'΄(~*K+7.1&y2_/'bے3XwN$WN l5 l= ͹΍Ho'=(x tǻqa\*ZҲeYN٠)4ZE "{`YE"/;諐c厫\R>Ja ֿױە" C=slay E՟Bfp~?v+fk7г2ǪR ވoàݵ12YDCe[?2zB퀼(.V]+EJ٧7@!N \[N[_vϱfl>a;m6Su<sMnc:q}y 2 T{+Ux }1Z/f$ /M Bkt+s:6^bKerb1 MBa *  Jj dlpb ݝO 7xQ|K< OF]JWN ^[\" =A | *V ߳ q<~)|7:><)U` ) v/z%)q4Q y[CʹB6OͳEԊ!)}z$4޵Б0q(e*%̪||R*{lQGK9dJv %wLV/^{Í2-wq  46V 6xcr=DC +F twhlR@SI BGO7 zKBL+ 3 2c X_?p7ZːF/x i>̦i )U p Cy  I  יC@>5UEgy}Q;[#ui;*R\\ Yt - 7* h6g.{ @AiLs?n9 ANY/|Uw)$vlW[PӮ75Da~XQ9/j|E]! I8r zPbSDZPzl1cLeXmgo1l0x[ &oJF7 d P3 hSZxȋ"F!ȇt v7)ϳ'u\M혙 ϙ E$wq$! p fn aǩG|h;Q G(A-{:)LJ*a d.z/yà5I8 |Kϻj#E(xnBW3iи(6X bݏ`?.& Cb>H 7KE"3axI!U 9{'#,!:".!>؁MFUa"Ys2 `(H ׹W  \A e 0 AcsCU ^[kW\g)@.$wVqOe;W9 Q -6p&@  9h   +N?# =/0*vI7 iG&BۄЮ6<4 )c#W|_q!5>^$zɈ>M;ʱfc/m2F_g@j / j]Gu A=%vZ3Dٯ=oh[zR "/OG Y'jJ}~z  C"j`З 1&x)L,KJ+bS SXTғԿ_&|m%FiBmh] gmC|`% T]1 \ ]FvQLrc'TCqDHLz Vc _dO Tk"k|0v">p1ޤˆ]'r&8zj,lXV" KPc-21B s<>JX b Uu OcF5Aj&&"KR;~A|zl9cݧ}&>+pvozF3Rni! g efdTQc `Td+ b47i Tc;yv@vsxm5PM2Q:yFZy-B9}w'M䒸-ް:Y%ꙐV?ԢI'y#rV rϱKNeKRladlr O h t wi OF:iۻσBbY[lGT6E*biQr n_!&ū))'=$!F]u?=ly[p͍mlt~}"=HQ~GB,deG:msm+*[ ;pvQ: S Q2 t > . HL_-cҬe$P M݄e5r} :L%㟠 TW  1V VD v `q %8֕C9s  !>{=6 Ic8=Ke*wt -J$;lR /1M7@GIKkdOx|{ɦ;eރ \ ^RY,IRXA ) 0~@" E R|)$<#;LC+WCdL{x ĊO#u<)N(&yu{ l iMK 3OUm,XV~Z79g'oM 2'JG㟱v. 깫yisZv'JJ|lmzsQa\J|M{>~A.)@vM5IQ>j)Tg)l!VXV+ S UGVOKLKt뷔B&Ngdo`Pyײ'Xdl\t\uLLC*i V2+ >qxѲY:i7: S *fn(/ B 0p 4 ^ M @:\S'OG47/-Ppl* 4Gశ$! 6 3 sG sGG.tVqqyȯ.+3OÃn9 Ǜ q}nP {Ϫ _:  i}Gfڃ Xf3ZGp΅Jq (5_z:ߺώ<^Y5s#{=/Ș)45oa_U -ԉ* Y rd+n'5sS qTZ kV|H+XV>~h)HJSO'a!:[gNu7cܡv)& mVF.AU ~@egr SD=0WۼgV_qj@ RM vD5II˳R *X m=mcil 8*;(NjY`)!!$Kft3\'(a+wmr @!eAq T=IQhXpjZaRWX"ȾUTs1d.a +Fw+|;1粙,TX|Q %Ýlnei>7RlJ,-m  }v v ;uĸDR6]Lh K42kq- 32/ 7Jr>ኃâsDs^a:YDROt4*:g%}υۮ|AU;qÄw  Q 9)0mw] }z;&±jZʐuPOVOd ũ3s;6=VaymO Ȭ9 k `@ t{r b!&PQF H $L'38|n{YdN:sx) , z7):RvD م/1<@c !]s v8.V~5) j s 4 [B=$eErKeȁ tBđ] !,VKȧ? i1a:'s#gQl==9ڋqTZs>)FJ;'~y塼Q? F9& @"uJ![y <# B8B%p蒆䥑ru'OH)&s޳sg&6 YRS2T ڏO]Ox8@C [ DdN C `^a|g_(T`V*C_E: (%EH! G{ : f}3q-z|wZ?8KhQ*vJV)VC`g9# 9 ' 4Yw Z+4c(AeC14O j ^ 7 }ߴwŖf_:PE0}.DD""va  Dku\gZ pӁ߭hW 'ߐ|=8yΞbhD 8*@lMbTSQ4B`mMFPb#tTX&fJJ *76`tG59uN4[rWkIa6 B%ol-8+rG a P-N>  # ۦ 4499|, |G,7r<_05Bvedߛ*LsID l4o365} n;k 3| : CS 31@CzpH i ^]Juh=f)[…dۊqǙ>W^Cf _Ag+7YP*%K#~%x!TKUJdf8GոD6kI;JCaϧm S,jj"Mvހ ZW u Ddm+]47FL{|K O[E_c#v]9?F8r~T@cȫd?AW7TU~}ΉM;MY~o~)/1FГ #n^}w}6QT f > >[3wO~&a%Xe0<&r&_C|EqB8ehT&n4?9,~  wW²Rj;s=l.!K 6 )  7 y   72,D x W= C*49z,(CƝU?'+ vYI?qq_@+y>B1 DOh@y+E `J 1x&r 5P,T+?)0]լts{^An$$6!s]u`tiGgQos - ,Z vQ9 Y j= ;dU';LC 9HZ=Zٶk=Ffx'F-ʩcd*fxu+^N朗|lIQ G8/ Q4 6كpT ֵ 9A 8-IJl}adTCC /)~ (v> YL{,Cwiɥ QQ`/X²|1' Y  Eo-}I;Wn:9 ::HtsԌq 5FB) 1ЭTK;f/ձ0ށFo};RQ L A9 UU :  &ƉU,L"DQ*s9h" nE:^p !z>LI .)|$t714!8vA _1T >DoA@hN  91 zpM^'6 TC_qoVkOwxg4snM&6O Ep m- D / ? k%K3:dJ*fSJ =K V v 2fb-Q­/7|P[3&vN$y o$#A @Sr|k 6 F@ Tߤ]Q Bgy Gb G>" 18$\uzG/B(aBdkw QTb~^]^,W~YDt4q+6o+h: .u GgZm%LkHN x T|#00l;p!W$C\ƅ!1>̚9t6'a h#\9@Bو!\Ļ3hR7kc!X{n5SSx7'tg %pG' G {1n, ϐj  |H O%YaD.vDytY_g> c#:F$w"_m|X gK~+F4*h4Gˏݬ&?(>1Dȉ|,ൕ- / o GpIGHh3$-;}yGp:?I"秢PO㚹/Sl1 ="N![7DtaY urc U.w Tr wKU\_&Bꑨ` t3 R& ugW BGG"R9e3g?/#+u.i=J.|QFsGyTld$}F(  J MYv   F U C  4Q ND"_vvR zlW6[KJ0P'XZRZKS<6}%ac75"^hѱCXI +C"GlVG  2\E~R)s㗭'(PA.M#Nf8OI~/m]wN$ dsC3ߒj z Kt ^ VX S Ao y XR6&D~ 6e]Kh?4uD@}Q=V m3qv2xR@ 3%(j^! BѪV&FT a`W~˷ $KJ`*litU*rZ?#@G︦f"vjUs*hlhe.i]P]7?/3b]pDmI<[oP ]u=Xfp>O˹4ަq 9C fj4L<|P"|^+pƼM{ϫ6 U..q<TY;^A>E4iaכGٷWm=(A $T@ FWbuH*+a)-r:Բ?9N IFjVYwy :lCr[~+- MHr =تEb  ~^4#:TrƝ~ʿv96qH%dy e(^ZBL[I h?_}bqO1Uk~V u@|cOKЦUm-@7e) gy$0vף5oڴ4 M ^y  & ġ ̯ N{ *M '&{/5QL ^e\٪EhZl%pq4`!?a ,Fd&-# ^Q8aJ-U\6qj~o=PUvz\W,n$"!,q ˱'0]{i Yn$x*_Fig_Ts*y'E3W"+B7Ji[oZxJ4&Zs,p5$/>S#~fJ SI h   g oF-!wO4 h͔bh$Up~" |-䛈E٥ BY=<>Q{gd1: *Y}eK]Dl@4t0~In/ZKӼSߕLO_ ׉l S(`Wt%L|t+:/ hvW^{8b/Myg!bQ:ʩWVw(Z>Ԍ" ^oY=mmMQm}"unJ5 KGj2{~IIJmӐepUq|^>(yM4Cče#V(Q*}ug !|շ|!X/}xa%4HAA;9,+=fXEIwI^_/,!ˌ  x ' p 6 z H_SH9)]*~_X3[|( A@b_@ud\(` c զ?r6v ÂVw9 'D'Mȯ-%P-w L 0@d⥸ix-Mj AV[ן$ y+lhF,Tw8"לQw$d =3\lq\ir2>@l5|".ecMB;ubjVJr>M H0v_$2TvUyIoOc4saE-~8|m&0gW{C×[Lb H:WdBl&T).&jz0&;Tji P Y6 Ε JDN i%N ѱ y,LDElD4gaU)Z_BaCA4! *b/Lu?<.۩=Vy=1n"܅!T3Ttf0E-a3bnA菄ъ3SfuYHp] )5/ hHA T#a+ p S 0RxAg[F5dQ8h= <Ojbi` R  q%zz8#tN?_ NY*st@Uj(ThWT63rʾf3"fd_PV A5tTD|n?ZU #Ta)yGoPj<;Wmf@pv)=71 C M  n {Ԭ s +8ksSjqq{4)o/FLRaW C>8ʍ3H.u}簤]΁A,p2[cݕrdW4 i9v83$`^7mj }n ]?!].Z K//47|K: ˍP r'*wU6ta܂PަNF}oh ٜFf=r_k+G pӍCޥԠ/dS!ޓF u iQ;9vMPk@{gˑ'-҈u\]/f2s \<)&J ~S#5QWmqQV0 BAw8M^gzp/*5m K A 2 "߷  SHfO(ϔ0 ``O5C\&-Vz {1m-Q6ƍP1Mc& ޛTԽ ǒ%AQ.@?{l }q>7M5@f7AxL#{9 $Z 4+Bd%$ z_ 4*ii i9$_ v4 gy%]qx 󉍎/ٽ vY9?Vי.f UR늈/<5+T˻N)LԳ6ImS-s^cF[Kưl c[XI ]Gh|ݪb1?Jg& X l*4&]|RytWƸx`2)}$Ub"   % #1 2 ( ` IuUظ_r6!}=ED!T!!:x)Q;SV{^j!  -LPdd>g[D!?uFM>Z^ =_KIG<%Wn+|GB Op ݊ ;z]*f L _U!2fQ^^ao Nl [\{>EbĬ|NO#eNC>W}5m)̇X:`q) Ttqߙ {tdS=bnVB) fn}e3':X4:gY~1Ř"iu < (bݤi=] | c (| 2N   Zbo?% XͰ2E,elaنKBaLh`6r?Rm O N@Ol=~.vzzZqoᚹ?y up*ue`)mBLo gq!4%9r  Z <$vw-*f eYf}#+WFeדm t8eAXLp򧪲6-CrI;SR>Y B3B96*j W X*md O̍SӧdŹ!ܿXxwn@oR/VN@L$\:atݗz!/1m*$8~m!]6$;9b83"s  ` d ZSU+W­P  T9 KӜss%J %Qʠo.H0<#eg|P] '_8hu#8bch!2r3xg Bv4VKV Nb{>a 4,7C*= I 3Yb:AZakI䠹kuiv$cёi8cBH$f8!"<hHҿx%n  9{"OSD3' $n2s (TW7]JyaoQRj`:rDWb|xghH7FGD9 7"|*F76JT, `^j߇SD(?q1WN%a21d!.rNz?thwg7M% c.ZO9& NNBemZOQc lg nL { \ пø>+@R =l Z8ef޼qwxG-0!7m?N~d0hr3mFt#f: bk͸]tL7N-0 d Fs k jQ"7 p 9`t j:oh MZl =1 V83z"kZw=0%kn 4mR@ˇZd_OS$1ɏ@U bv)DѢ[_RK7I689npҖBW{Li2S`H(d|h|`{RF9   +6iP )Ugœ>o[ψ>[z!LX?Krc_S||G J a ^g : !N:t5s^J̣Dh/^SmD5L73,Cv/Fګk9M[g(Qn2iY4)ʣRQWJ9o!-ʜMX+W#I!] ! "7V  &G g 0 W@J,ѓ*14''oDJqXcn+%VDɺEDuO~1DՎ=*C|$x1 栍 O/xgg*cq[zNme݈PYNZMQ| h Inv-Ac?|kVԏoPff>=ų̛tyAX-ȧ$Hj  _ 3 2ZkR)~;m{4W̚N.N<< 5j 28)n* #"!Juo:(vd S ;v }GC0CO%~q^57%D z  ! (h & ; C .9UmpKKLt!MXGT=Tk\2u[σ|@[ 󇗥M>G6=6?s12UIbZ}!]is(@&NXGHX}W&bhʟP6z]FD<ly+r3s DVdtq4^ ?F$viϥ̧0z-M,6[6Ƽb((I]\FzrpFkT?Y#[@XÐftcCM(VP#06B)>ٹ1n6%%NK:,ߏFǵas?i=/ a{ѲuX*SۇF -#EΓ}$JWP:f}5 4$20- -iV~BWKaҤݺz?SAHR wdlh}%s^مJeyOZGHmN$gPnF'. V~ \1zanyibq#DT#$̚'vt ;d,_VTc~} GzhaAE N,Ǽ5Q̇{cu)!u}躳r />=KkeUYW7O@CT5@(0h{B) D,v3i("&,*ڴۚ m=v.G&'ӫe88oFPc(ZR~!%siqe}L|" hN("w#N&#|MM$44 .] @ N D fbhbsS9f x߸1L^Ev 7C( } }_R]\!%>\g%012A] = ҩ c]Q˽ @{{wN R%*C]'ܧ(j;c4%(;|$p=3HB"@'-B^B#%$g!!!;i 1 4 | um~|4|BY99{Hr/3 U^ B B \Id0gl ed.J?0>>v^`Qe_)I27:@EE[GjG?{E]A <I_4(+z <7* I\}ٞդǏطj<ʻݸ:3O#'1&ѤGܫ/]Yባ ʕ"G3-N5fO=BȭjFGVGۻD*9?g9&*1'}'(hk\*rl9U4oǜ]6TY&L sķT{Bߛ6GBPg%^/?#8H>TC G`G0MFCr>7.z%ZHT6=k5(~&=ÓڽQvb+l{~FMũ7֤~-2ѭ_s^ڎe'OI1?9z??ڇDDGG2FCd=*6- #e &XI GYӸqc9z~ɹBzLj5Nͻz, .HalM=c'gB?1g9?D1SIG#G FFC= 6/-#2. Yվ&uݏ_`)'{+pú p:#K1[)4y# 6KLS#5& R08%H?T&D:JGG{FFC%>7\o%Vc~O}@/̈ij}GuS:ܰ+OýXa=A^VVCI, d\oL$(5.6=W&CZ}FGNG!D d@c9% 1//(c5VTJ1ސCXE:؞KoƉm/uR{Ÿ@ VK7+& T=рj ۔ zgxno Q\ *3w; hAEGe G8EB\< 4,;!"2 ^,,󦜉5"p6–Q9.*:#^%U0Y hNLc;̱.,K%/7VL>C(FcKGGJD~!? 9_0k{'-rKԳjg⣢/a4̸ ESTy]\]ȇøб dggS2ErZm Q-6]w.)2:@| E$vGnGXFB;~=q6-$;, nc2!j٪̳|[hӆ4^/*pqGOf8)A'~o vR!:P,4.&8*0:2&'ҫ;4n62>qд^ȿ1/侼V~+<ۺGt[WP&w }G!h+:4^;;c"A<)5E [|GG^xF%34C/I2>7A/$;&-6zJ^Rߌе ȗEvvpladؖ+oč$ԑQ)7C)pN1k7z y:?8V!-+i3;+; @EYjGlGFuC d>>83)0mO&x5$ɌTMX] ѴȺU< g$dzX]2ʾlyݪ }M h_k)WE29{?gaDXyGG3Ge(FD7?9 2],)j? I #Qd1QWTӰaoVF|zf"U_@ hgj[.|0thWE12>&:p/9n73>cCWFG@GzEsA"j< 5+,~$#Q GUkB*xt<Ϋu wS転h@˸\vŊA:e'eaFzg 6q!+3:@DUSGGFC ,?h8@1SW(kat 4*r,R@JӚdTрj9||弒0XȂ<б&S;`r%\ݼ3شAV %eL.Ig6@%=n]BFE۽GaGFP~B@T=6o.Yv]%u8*f+gkN'+0%ȹ*$)VkI2H"oQ%F!bB;,}Y.YU!k'>07E>)CNdFG@G-!EͽALZU<["o56-#m,{}F)L@Iϴƅ3c—zr^ ûKBR^Hܺ~8U񙵈nTqAm'I[0"28Zt>GCpsFG0Gܯ|EA /N<n5>-4# _#u"S5|E3kNu"ݩij#/b_QP[ Wz<6Nlc!GBh /Oq`DT&ʘX/:57%2=~BhdFDGGiEAbBЕ?=6h.%k]қ \FDyJƯQO{Ͻi8Y?SA*g! =a\Ѓ; Nwl{9vZۆc#,5|;)mAIE'xGQG/FMCt ?98}e1_(%.RǓǞ -~+S_ NeyQԓ.cٸO̿(-|:>մoS%6d I DJ(ē1v$ 94"?ŨCF@GQxGqLEwAwI@+ (_Jsdi=k*#Qh,4;y;bW A?EO+UGG;FY DU?9(2 *C Pal, YVԧp9֫pNNsHbMZY/9^dԭiºiV}mf9fTHenL%I..6E8n61 A(Of dB;ngDվDͦ/q7ݤ8=41T(D7 'o4.cߖ@ֻ \R y<f<@ׯ򢴺i!y6yt2cҰ>bD:?ɀW&#$VB-S85 ;<-AXHESqG4nGF uC%?>9З27*" . JH>[ՍElᅜNǤ j.d>G1cI 4sLص*⮼_~GgB ȁ!W?+IC3RP:@,BDFTGYG$ExAAW;,<45?E-L$~(Ni%שּ?\x(Ү ʫüغ30 /yŻwZŒxԙ!:!ۗf`D//&tt/7i=]BFEGBGrF*lC> 871!.)|53 b2Z x7Ӄ r?ߵ/QDODOHȳ%9Qo 6܄kTv # W)'g*2NV9 N6?mC@^FG*G xE 31B5=6e4?/F'& nD@;~t鮷G#`;գ ͜FJ;{-귎P+5qB"b9ڨJ@ |aBVe Y]0"C+u]3FQ:r? ,D_FGpG&SEBA< 6s[.R)%/̦F˅a}&fݣ\ѻ$?' UK^6LHgԼٍ85v㸘P}w1g 23"*+V'3&t:0?DmFGKdGE31A)<6.+_&saIƓo2i{kp30Kk1e a;ʠH| "#;LI8w$"a 'D@ y;);\1ܱ8@>0CaEF8GG"FBU>jT8&1( ӦE Ĥ.x:wQjYv0.]lN.mJL7]|cZ_r2:yO: U$*c;ح%M.ph5Y| Cww/FٲGGHF?Cȃ>8y10Y) y /AIپh^]v{xк0^nq@eQ;6/weB\C"#+]339?CɞFRG}*GExBfL=\70b([Dd{= 4 C@RryweO$¤ ci \hﺣZŔQ˷efܿ:M9jMr"{C+$ *3!I9O?CpFНGژGEcBv >8k0(uc m߷r̶^;Z3Ѹ {xغjŮ (⸹Q>; |;ġɫӦ;Ґ6[h+9~=z )\F #)61?8年>II Cl!FG3_GmFC=? |9Z2g*4"/e7*+0e{u(܀H ˎF7ֿՙͻQ1>Aßq7P$ͤ [º[%MϲגS_ꐙ}2Z9 h0[&.16c~GE  +à !/)'K198‚>EPB-F/GGHFC,כ?ϼ!:!cu31+ʐ#Vt!\2V$2-do~Dt}e[1r4xy4RWHn:y$=͕ :&W*5]m]"t +=39el?CˍsFG(G^4FD9CH>H=9F&q2t*#!Ӧ:txW3/ 8KU{iV^"~)0?>y˹ü2#'|͡HHݓLL碈&M/4[ "ab+39G?7Ca^FG{MGSFt+pC0?492veB+l"aa)^x?vL ?V FOƂ0IؼZڹF1#s]-}DC?/=~@n ''6gŇ a 6})Aa1G8 >tÔBX{EgG;qGFwG]D䜀@Y;,5Km-~uN%@Lv<}Jg\Vw*p( bɸi?> ƺ,mɸ:~iemvl_lI vv282 E$%[-F5;9@#rDDwFGF;GxEZBL>~Y8q12) !? ;bjh!\/Jff)$My= )IV9QIeO̪\ۗ^FB~' ڴv ("sr06j7K=As^XE\G G-GMlDшpA9<ؗ6/h}'HuO IyijՆۡIf#RSViL '06Լ+Xʇ.͂7g7aT9SS=A xS )i)2318=1OB7EOAuGYvG{GD3A T<J62/μ/'ks L POxm -e6s} aSh#|B7vĹƬE2.ٮɅ,Ȃkq,Y ԅh(LED017=ھA*ENBGGPGGEA.H=x7e.0f(N3 Y re{EAPj2q3؇0w|o)X7 G5=~v4Zyd(UM@ qBu%-4  ;G%@(DڞFYWGuGc@Fm mCrQ?:ϗ33,n#f" :znyp4RP_ofN"޾FN wd =;UׯP8 ̈́taPhCaC: bEͼb Ų(0 +o743=)}A/E@GVGYG2_EBʑ=07_'1u):!E;ng(xo)޴+։>[ Ž @ʜ)v>ȸrOCµ|]p$p˜!xz1H$F!F*e1o8}=JgBnEoG_G*GHM EA`<47g0B(*? 0 S&&rT猔ު[՟%<欠A®6czŖ6G˸2`@ hȽNG\S^(4NhT]!B)8[F17= BPE65NGRGgSG[EB= 8b`j1O)/R!_͢f{A(&>,gQ:qw#þ_%^< C~͛BoN$PqȽ)dXﱖZl8 pSt$'.b^53;@VDFGG9F 0uCu?PN:4?,,{$lJ ; (D;fSڸ!*NMIùHu;F?rT`ӾqŬŏ>M|z(g,hN#+M(3u9n>4BxEG8GGDA=]F|7+0h)2!\e·)Ef/C;Y8ػj.;òX"+4VGFm]RexXȮh"dg4ڸ\=whJ#^N+ڌ28m>>k}BE/fGQ{GzIGjVEC7*BmP=he81|*"y-j)^M`'#ǭyZD#NB{:J#$78I)@ )5 byo2Ek I(j0ݾ62n<A^͍D?FGz3GXBF'3C3?+:I4-m(&.=Xǥ I1LWJD戋ݫMIULJ\wuۺӸ+|.'O\w.qU1MGP)Zr*q2 .#+2<8ȀB>]uBĴEw\GG&[G4EsrBk?>8и2H+ #9])DF@ $&ΦcR :>6p[->B6NM=਺3ǽ!X=x()v]E-( D^/@f$zj,Rl3X"9Bq>xBEGsGGEG3ZEH@Bp> 8y2\+L#Zt$-I0`.ӫg)B&#Яobpߟ&4$!vYxs o\ێcJfW%B{ 0,X#MG.+9I289=BB;ET3G G1GAEK C?F:40-[%OJvV2n #.!`xu+^պ@ʜw*ѕV.Y [SMGX'E./=5C;t<@NCX4gF0-GGF˜Da"=ApVrJv2t\inayݑ~R#`| lVX;*!)0V7GFVCDp@I<6i0f>)ig!=1+[낼T',ǏӓOƳ$@5&Jyz*μqXv?d_DEaӛ 5,'^.5(:՘?`ZC;kF|G G3G@KE¤FBl1>9YY3XJ,e$O 9, _;_C甘ۃWgfĬ䏹D`Af94lrװ¼Kfοka䬏kiDT"d2vwze ]4&WI Yh(/6@;N1@bC&/FPGCG-,G0xIEQTBX>f9f3,қ%Y3H\Wh w*Q3<54>}˸`z+_9L#nmTpŧ2>*ߊ|M$fդE \\Q$fѷ+?r2f8}=IADQpF8SG G!gFUD A6$< }77i1G*#7$c S,7u~8:Ml/k8j_`]dRq+b־=L ː7Q&ds&N_ .X)q_ QLGH!%j,r3E8=)A]DBF]AG߲GFxa'9k[g3,\%$"F ;’ 8CcڗnӪVHǒ~-G(Nx{3@Z3M[08%Eډ#Vcy]3$(&1- 49O>vbBpCEGGGKGeZgF8D@,w<*M70*S1*l?M#Jv-8j }|OreHzR豍Iѯ-(h3ŷ)=bD/˸V klX51mxoé#6>0ܺvz'6]^ѹD'E=.z4:1>-B]ESc,GG(HG;_F D$@<|wR9b3Ya-#d& "3}.Ɗl䵚\Q{F0?oꌿ1͹hfrT>: [Dfʑ=~ӴAדĘ h@RoUb.Ј+ w'.4]:m> B\fEb,G GGrF2D@<7H\2h+j$y%ަ G,V,+3oEjPNRW=z #Ȼ"]L !ѸYN\ibE;ʀ ״ߥ戈$Yp?T3:> '.4h@:>BMEGGvOGyFhDTULA8G=%i8'V2sh,Vp%N&.  qK!EOFkuGC$n(ɍī̿alwVځv6mkyz޿K%>N0hRܪTQNɌd  F%d,9,q258Fx=7A BDrvF%GHGt7GlE+B D?A:15E/k(!!m 7 Hz(Č~pI{+cz3Tz=yAZf#\wMcQ5g<Ⱥ$k9 q3KEׁގѩ\D%ɶxS&-k3LU9$>ڱA.DFGGNF%Ew\B>':B^4l.*(L >UAZ$ ywM:t3$~6٣tʯOɌ\.®eT\ثP7"Rlپhpo4 ve8Oд6o0Vg!H@!D%X$,Rq2n85=a*A0AD oF䠬GKGsIGETC?d;̃P6Y0#S*k#~^~ qmD'ȱr+԰}iû3m<}Hqι'JUp-,jKJ!;餯k1C} >ݓ VkƎ!KV( w/fX5Æ:> B:E_GzGNGFPZD)B!C9]{4 .2m' MpZ %6m>NGKLq'+Ƕ 3Mo'cRa䅼пy %xu[B9&~H .R."Y()n/ml5 :>aO~Bo\1EIF7GOGCFSD~F5Bד>W#:4+[/O( !-Pi h =FQY*꾔~vc@ۂb{wEK*[G¿̛+^҅ ˻5Ծ+ZZn\aٲ|`*kM<hPgց&^-a'30<83q2=fA DzOFGGoG EyCs@o'^3.4P9<=Q!AroxD@FG'&G>TG@EThC)*@,P<S7J51`+%x(sܿsoOXx0In`ی–gǻ1fOc&{~>Aa'_OÑ]n^.Z9+\0LHOIs^%ڇ,;2T7^iw9&a4r*/(D"+*ѿR3 Ls#B6:Pi?pч˳|GqyinljX}`z ȹI3ھ8Ƅ[Yri`ިo_7S͝` (\?-j"Q)x9/49R>ЯA|DoI{FG_G*utGFlCs(@ٓ4=W8]3-f'_ eQk D&4'by?ݵFs:fNQ7a](͆ϹھQ8 *R 9P5KF/B)3"!i_;A 13F)@) p(8)ӌe6șѿG6\SZиA#,oϺSp@u4HHs7ះa$I4^ W!I<E$*yr05:>!B}DFҕABQDSFWGmGʦGkanFPyDz AM>(:;w^5@Z/*ݯ#CakxHea Z I[J\-)ϔɵ0^'N!ѽ6s]LMֿcݹʾqXdrPPT#G,~.ȃe*d {~؄Q]%N֘+mY16+;5*"?fB]DBFGKGeGxh FC?A2=(H9Wk4.7 )Q"]H  Ŋ ? o% zqc@ث { rƽ3%_O7镆̹g7ջ%y< `ˊ\%9M<ㅪ>u|O p0[4mle $0Q* 0j5!:n7>ARpWDPFׇG|5GtGFDBB>:X86ׁ1R+$%*'ī50 ֶ6Ro.2v(QT79Uhf:nc~r*GL/θ-}$9KN>Whټ,fÜLJ_Xț1\{v`"c`$ +OC %+-[1sz6;p>s1BD]FAGeGGՊGn.ZFkD+yAk>b2k: 5- 0A:*$&>eM0 xNi-#^sֽwac`c/|v#)oR˸̭=؊j9LN Y )Ѷfփ:݁DDS@s6,̑#u))z/ s4er9= ACjEeMG5GoDGF%_E C@ f<6W8V>3c-' ֲ!<b* ]~߯6eW\l4r1HV@ʏ5Uk} _6Z_FgF̻?O G)&_kޞ*e/޾t7$+$*2*/H 59~=n"AyCtE#NGGCGF=qEW/C܁>@4<;r83$^. ( l"%:<d+<rL{L䐅ݧ=2, _4=àxtdp /︬q%>Rebz*1N!\vMdM p#tG 3cNt !y Llf #i'.,zP2J37G!;\F?aBۮDF GGYEGGFSD>B?Y;7ێ2Ƶ,&' $|MO 1bړk7=GJ۝սOH(13,b·%;^AոT 9T͸}3+JK Bp#ouЩ > ᱎZkMoaګ so ?&μ,? 1(k6Д:≯AA_DpBF3vGGM:GMuFhDEC'@y{<\e8ܶ3D .w(:"jzh/ ?)tV~Zґ͈Wm`IW+kBQNCQzLS\?qc ky?x~F(f oq~!'3B-Qτ2OJ7;{g4?JDBͲD;+xFGaGGEFŏEB?/O<-083a.(."4[:"N;4M%2!o-17^`슘Sߪ9<P8)Ten|X26U˹MO 13ᎄ3vsm[3I_P02\ a'2m9 |N\GA$}*A-0!5읔9P}=@LCcE.GR(G~G[GFm5D䃫A>:R}6炱1zo,&H bZ R$2FCUfF}1%{+\Ҿ 6*(_R`s 1Zn.z@"+.ܼ.^îǹ˱l}(س۱U?Hܪv.7W Ǡ]]&tF$X*cx/mlo48OAKhH[~ "ڧoǞg3k};lFzB4dl 01w[qֽWfijÁȢJ͈.҈!ՁeNTl5?50# d͋Y`Z%e(+;J0("5ޫ~9V=Y_@-WC_qEUFGGNGnFPD]`BB:r?=;}7 a3QɽA=2D F|eKGG{WGS}>GةE%D&7A>:^6s82.-Կ'vC!ftnWpvR;"nUƊ" 4۱O,\ N]-N ].`cOGx!)RmmZ6nƾtl] I|gڰ a:%i -.Y,r ZC&-+i0T59b=zl@WCLhEFμG"GGӜFEOB(_@2<8q4_/**%P,1,U^ { m}(kxC2\&MFcv$TA+^b¸88n.XGC d^~rտƍ&˥?ݰ%v:CS߬# 4J42Y  < _%M+c05"L9W =G@ BEF6pGGUG9FrEXlC@= FTH˗"(I-m(2t6:Yv>Վ AIC}EFzG9G勩GcFiQECPCC@~+=eJ):l%6sY1*,D'E)"<}av2`|1ko h"{ay 1`"-aP:CG%Ϊ NBrmE7!c=ml$4:f=PxC^Kbȳl9&`5BN0,&l!4o@_ .Zl1c{Z%ulʹO$H(Ϋ8ʒ K ֿb|9# ժRY O"RøRRpХZExǺ:57|Wڿm:<$I"):sZ ƽchflp"u',#Ģ15ѻ9dp=.3y@YNC; EFG.GVG1,GEN$:862;.AU), $7hV|* `Bޡ~wx!L&u'j"ʔ}@omǿ@<.桹#R/E$?P޿ mZƱ<ʏ҂t$ӤؔYXtLn~9oVgU (ݐNF9#(-yZ26WfT:l=J@8C; EEF ~GGGKGQ2FcDwNB ?q>[u;_(844/><+ȹH& %!؞d1J QUQkT8ewJԝTz;.^ tMyi1r2֭g+h7vo亖4ͼM#,,C;ū8 #"H4z s3VJX@$tS>nBÅD${K)r.B216:=8@jCDVkFyhG9hGGnrG|F Ec"Cem@%|=f:n73.4? *#/%aTDG6p ZuJeK%{9֌.Q͸Ϲ۵撻rؿb(`:Թ_:'O fhL?YYB2Zwǽ^n&tG\ފŪ(d.C l QB"7'k+e&f0OӒ4f8t;->&A߽C~E@F6GJGG͌>G.-F#D@ZB$=@md=%$:62;3.hJ)4$9jp2@ph7I !zOjy`?W"gs<]ΫPɞkL`}ݽ8ʻ.p(6qD0>Y=:&T5l)hcƉ) uJtcTEL&rYD/t)FŶz0K#f (E-@ߜ15yN9n<̆?VcBOOD4EpFGGG(G=FnDmB @ǾZǺnhሸqʺʾimu)p˓3i Y e՗`#G m?(!T#DsZ+_$ ))JԱ-15Z y9D)e{C,)JJq J9`ȤS N'}tRa0Lǒ*eZ  Nl2#iy(,eQ41X"58@;8p8p:481R,ws(h#'v1 Ф-[kL7-@J{cZCھCї QcU; O[TIǢmraA܎?pa:k;#EX %.FyRH7O@M/t ucPo-#B9-¡4HͻƓG<$eà 1faě73=âDƥۜɕaAA-jZՅuٖaޥt/9%M;/l򜊰{RߡJ a0( ǚ%*z.:.+2R 5I79hG<?hAHqCcEgF?QGD.GG G.G F`HDB@z:>g;A8D41-(Na$% ?`$ Mp+2oLrnShOonP׵,iԀ&=3 WɏƝuH)6spi插 t@X*d҈aU|@Ĺ-`lb<Ӿ9Dx)۵M 2^V `!)Xzא $J*';fG6K!|F&17*o.26U f9U/d< ?+iAyiCUEXFΛCG1GCGG?@1G~=FD->Co7A>^ (<&y&9|5C2R5l.V*g &!5< nkC7MqOxz;78ݫ5͞%2`_.O^*ͯ&&oӾ!,[tj9T cي /xlRBo-be #پDUp6L͍ơpѷ]W̾wѼ a+]ܹ清IZ ˓::a~Uؽ7su›9,G5˚/H /IIߝGQ\NZowS˻ C=-N#'0+h/436b9B<$?adASC0D5Fo$G!G G_2G+jG7Fr{E $De6B@=U:nJ7h4B&1c-Ϡi)<% ]`݀B$!q7 \BIPq_{M̪D4uZo&!CVۘѯ/ʹx/HB]+d/\;A42Cy VC=Uݼpoξ l"̫xIPN ԃ'g) \d[}\egTk=S .+~PJL2#Pf'k+;/2X/6I9+; <>-@BpɏD} E8F11G3GGRGF EJDCxD&A>( g@st) .M.Ss|–gqD^)ݽǛ٫Ռч#5Q÷ÿ鸽5ҴBoa^*YQӂ3󴸍Zv$;duSH6fu˞0ehoB'V$^G e>^_0Z\ w/KE~  M#Sj'`Y+z/U2@M5c8cb;2S>@BY=DE FQmG9GGG?GZiFCExC( B5@]=-;68 5l1S4.p*a}&޻_"\.&2ؽ 1coC 1􋙅s lra?okΩ M؄µU/!%\ ⺟ z׸XYHض)xA>(}%g qFϘ0U!ɊUN-OӅې4ߥ z2ՠ\q^?`Cxi`S HVW(@ߕF u,#'D*.2Wc5Rl87;&D=^ @ BfeC4E~XFm0G GG[vG*6G|FE6D Ci5As?;s-!"%h)g-0^#4d17E:&\pAB5qDuvEFXmG 2GWGGz^GFJEND'BA@Ք>gk<;9:63U09-y)%0!J=ke u\bF:H{P!J8m(a' K5QXcju&ʟFƸ/y ?E& zkl*DǸ 27}C x骗Ƌcm$TMxn,a%k[9)2 Ț|uv :X,˵{ 4VL9OE#q '*M.>1Z4ϸ7Kq:q<3?7AQB|DdEͳF9gG SGG^GesGDF-EsDt"CfAj?j0=T:G6 8&5*c 2ti.K+ '#4SCɎܵ@ l)} 9֑&5eP@v+bJZl8۴)8n@&+?ŜV8鼠p{9SF󭖸+XM$eab/BIn'3iWspM^Y/`H9pө7ך79-{:}uߒ\\qu?/tI qk u2AMHial]R"*&)r3-0 3”6 R9Lm;(>:=@BC E}%F?FG.GVGG:ZPGaFE\dD(wB>v2A=?=Y: 8T75'52A/\+;#(y$ T&V|3vA 0%U]T jzg@K9*&̣'S@ӫ֎]rO&͍VGTĻ)r¤zTp>Eɼ)^3̷Ft'/SuM~7YYo< ĉ-l /% ̌:uOҪէG6ArVO}5% e$x"+= Qt4l8"u%?+o)`,90P$3b 68u?;"=ꓣ?^A%C=DREF3 WGLqGtGGGGCF<:EC>rB@E>v<4:w74fA1Y.+V8($ ф*0c$T 29"RO$Qrispz=A-!TIoRjՍginˮ2aS)Gd͡#78Ժ&:,j!u/jNl oFǹϺȎz3Do03RQ,5/> ͌ Z^gloQޚ49 k"^DW!Is$YnEg6js =]r.QU"7% )],/k2]e58"ӎ:8@[BC7)8E;FmGG:GMGXGTsGFKEDiC Bg@my>W<8+:,π7O4"\1+.+Br(tn%Qbr!TB-DDKb.H D<+NrbF{-ވ#PM<<Ժh)}ddzY SĶÞq迏4+_eQBn7,U#> P;N{Ǹygd"Oἀp" 57,TPi"3R n2Q!0Iw:B-%RJ$? , s AqJ%l ymC$֍'g&*.13ח699r;K=?lWAqBGFDnE (`FUjGGʔGGf G@vGϫFF=E2CIiB@}>uL#@'OBKiCDEf{FIZG?GGvGpGSGFE HD'Cg?Bѧ@ >@&AEC4|UDhE MF%GԄGGOGGYAGm:Gs4FEDC?Bj @?"$=ZF;Q8ߖ6s415.k+(%i"/ \;a ZR }SQ1 \LF0c7??ڑJƏ(ټ ox4EGf$ɷ?*|{ O\&dӫ:xvG( ,dLMK&W/+Lj~~YCxC Ѽsd5ÿ{6[öcō8DzB 7XpuH`wԥxg qYr?KrY"7m؇l@4^f BO{ e:;"q'%N(:+./&/1!35+6v8:뉞,@BF,CqGU4GGOG[uG=iG F+FcOJEc=DrChAV@Mi>!gKCBxЮsͫ *F%%¨*0Ó 5?ŎC ; o2Mm4 7 L77&cļS92|ĵo!urjpЭӅnMĻB۔!lE-\jMOV't!R8Ӆ-u g  .ع3Z1I!Z1N$$='*s,w/-2j468(:<7>8@ڲAC$3D?8EFfFSG8kG *GWAGG'G*+GMFE$D%C=)BnFA.G?D>gR<:e:V85(6-3·o1.G,h)]=&=7#Z T]=y5r> P  0n^m=) Cš Kn?=224 ܽV'3Ƒ)Ĭc\"<*ǽ;pp[~3z 8ɐG;P Ǚ)u:s[|;y!,%]Ჾz+2"dŜc?́@N6Y50n7uGۯ+#*KAe.: TZmf=W`8 ]>7# ܾ# &nn)x,~.1V r3հ57ʽ9H;4=Ϲ$?J @%B}CCI\D5PEP FF(OGGGGGGdsPGKF"FTEKbD4KCB줵@7?f=qY;W975v3*-_1Y._Es, E)+' i$!*'uۡl a4R4  tpqUKUL"Z;'%"=::i_ݦ F@ҽ'B M͛*ɠzuǦž`3v;J z_˹I(pN 4cL*g#~DĹA nwm ZB`X=5?ɣ[/9^ϧFH/%X1ޅfR[Cp%99mpDQWq"w%Ht!h ) S:Ԡd8Y%"g$'I*Y,M/0Y13ֶ5Q7U9r|;/=F >&=@ȠAB0CcD۷E gmF#GrG~MGpG2GGBGnLGgF%/Fm9nE_Dt CgB&A?3G>fb<:w9$07q'5&3Qx0L|.{,e))'Sn$y=!A/mjTmWn|:+ y Bm^Mް<,wj6DK^2BQ2I|̼,URY.Ҷ5b+>fXgϥ4˛ ƕűk/V[xH2W_<T-иl"nz+ -'goǸ^G$঺ak(׾e-{.:{yvoʙ'}P7*ϥ3 ,n?!߈L|Q=` <{L1LO~y#u&o}fY fG /iMt]gs'!e$a&c)T+ .h7T0և{2Ì4i 6i8}3:;z=t>!YW@9.A"BRCxDEI~BF9FɏMGWGsG_GxG/kGÏGN/GGFYFZE]JDЎC}BPA@|>?&=;a9@80L56c>4120h-@+"N7)&O$N!%,`.z6oVuw ,B77Ql) θvT/ƑvM)ᢽfhSCm,ճY҃YθcLg-;-5$–fW{w"REb &*^.Df$#\#b?2m |'Yb⹸$-A8jU2'-`v5ir'ZQqʯA`bRx7 &]ÁٴۉGcX x]Img* _ch.E0>{d%0%g F b{k3@E)2-L?!{:$&T}(|2+Gd-;/]1 O3Su5(G7Y91:+<<=A?a@"ےA|BEC঎DYE" F1)FqG{G7GqG׿GGGGn)GFW FatE D, CXB'Aܚ@X?=^<;cal9+ߺ7547.2.0*.+)&' :%i"Du tGҁU>e f) tc& #sԽqPh56N?|'(UHܚi/$W cC̯xEQ@Ȑm@)<QdЉV_JMNO? ?x-x-CYOsj ӟ$YsJ N#Ӻx2{ rU񀾕ӥ1TD¥K7?kϊ1QTէ9׀ (LޙkY![i\2E@RD)Ra8#+&;( fmŠ~; h Zf2i R& t"z$&)1+=-;/*=(1j3T46͔18H9G;YS?l@iٝAB?CxiDy+EEޫjFgFpMG ܛGGulGG-GcqGfG(1G^F_AF ŧEgD0DMTC%bBZAEN>@] ?G=D}oP6ɜ4z-2~1u/i,-++)'#$"Adi !$w΅>+5R [ Uo&PvG`B֙HF\Y>Ҽe63$ B_c昸SI$@m )4-t>zB̸3CAu&썡e;p.ROIS oUs.J5[ ǟ$Z/:@͠PϦ# %ԧJ)t۳@9MoL[Hܕ+uxu*#|6(EY}5Psr h DNKҴAa9>Y7+` ";ݔ$&(`*0hz,$U.Ք"0 =13S65d6MM8l9Ir%;@Yx<-=>sT @A0B{BCCD )?E E,cF5hF9Gb8GGGiGjGGƸG{GC+GF zPFT#EU(ExDXC>B|AAt?>k2=q<#;9{ Z8!y6KT532b0N.0,w *$)Vz,'4%2#&!HM' DyCHI҅ e> Q̩\'sn`&( KA1Yd*jҕ0anzp؋GԎ+/h&{bnNjgXHdk)0keFdjb mky섽Y껚7hvNRÿv?i:okGĊaxrVB~̻D"k%\+}<,/-N=\6*kǷȤEʖˠgT b[ШCYӛyNm2n}Qۚ</ߩ*j-5DiYp/s%oNsb/ C]$9;'O;c~_ kU&HffP~qOV:z w"e&m$/H& (!)Uh+UT-<.I0K.2&3/5&687T9b4:;)J=>,?n-@1AB=BCNDDkE4FFFfc@G_GpYG$GGzG\0GGKGlG]d!G6#Fp&[FTEvVEE DoD\CbBOA@?q> =M*<;9 g:`%9Y7YF}6w5@3)2a0Z/Wv-+ة"* dk(͙&d$ #=!2_z[ =qع1  8 ҢwfUB0y ^Bq#n 6I@Ero &G1o9RڦYp)վ`>żΤ E͡~uJɖ7oSKY_7=  `y-R7[gżh[[o}غ)0PչiS 3kzGS# m7j 2u qCt2N8]ƹ=|ºk9U  H\x#|ؿľ:#oƓ^L5kɜ%̟ W?ЙRqoդ  |Uܘʼݒz01=Ϧ[8~Y39PUerle?J5uvffjWTG85"  ̾qV8;{S,&2GWBM &"SX$M%@'2);*]G,-;/0 2Ng3(4 6|>7Vtr8 9Ѻ:};' ?v@Z_A~$BB)C|,D D0JE]E7FFO/F4>G߶|GGGGTGT#GpG2DGG̩{GjV=GFF9F#EIOEDDw:6D@CkB:BzAP@*?>a >=*>zro?9a"Dv!|E,bQށb۠hMePOչnuK ѺQiϦ>͡w"{?˄ʳ!#gЃ3Bۢl^ÓI XtSG-ܽ!0yF`j红oC%#*F}'K.}cP-YP-i T ۰=e(,ոznʹV 1rZHx/>Ǽi,pfʾh爿ЄP7!#4Mh@>([m2}!F wvMπ|6щґr.SOֵy'[ɽ=HH%^3ߤǴL:⌴POIju G6:A|8"`k^c1gFa ե{[RWSߍb"^eD   'LN^K̫7ɾB|> [ ("#$b&}9'UN)m*+n+&-D.#/r01}D 3M/,42&F5]Y6 d7i8e99V[:e I;0.,w? 4@T@ffAO OG*GNGHG GQGG G:GIGf2G-UGafGo/GD}F FUFBE>EL/E0D_IBDƑQ"BGgI8R)@?ӔUJ}Nfd6 :Bކݷ(M6l|??Bӓ6¿Xw p\> }a&.$0]-|5E^AWZq vi1)LQ{daҏb< i^췄X|>;srșƝwI3[GT#۩px'"9t>ԤGT?X( .OXp]oVMwm rJ] ޲'`G&؋N$@!⮭齓S=SB⽼餺7鼷KdӈQ|է"Uk'}{"p&̷--G.xڴor#J*#&h,~J ҳrK榞#LfͭKoxX(%谖' TJs!Y/8E'E=EEttkP r{u$JyȲI,ϵCF$f߫:yߥ>I|< |LmyŹ2\֦o%Ӊ{ؾvQ} Z'7&M* eCcp`X  scl3 =C[yl1dN% nI2P`=Qom[AdЖY{3<GZiEf?Q7 Q9WB؅a|+d q`y歯gH+&KZF???36 ٱ/\J(ӿFoSŔ2S֞'tMҷ hv4B = %(N$? 0z&3pz9) j̕ʵBAՅ_}9*,° 8+؉2aG! ܎)p5{ޔao w:n S[?ZBw1%rكrܞܱRn, $~Un:OypTWꝃK(/ :0B>>GC?6J66  2=*^YF& W N+)F W+2-.ht>ygz0G*M @s;t~O&MTQ'W'A'+%l+ Sj ezI]rȉF#کǥ6K/qODAQ|)ji༃h"xk ׁ7c:Q?\PAG^GB7H2Z^a? M*4@(:Cv&IBp w{vG]hߞynfW \ZWU|q7*¤ʓ%<΍u>ۡ0٬%B 8 'Jα*mh+tC_oO3+;*82ݯgw,uq!1WCDE"iP}jq[`K_`._~UAFhF#'.A>wAG'?'q)/y/ -CVVV!DmҀ_(zx sw!~ր>% (/߼V3~wNggζ X;V>܀|}%IMwؠ(*}!l!TGM},&R~)@y֪意r IRsr< NT/c9o*ڣ쪮iХBL42߄Ҫ ,-Fڞ@G`7<0+,Le` J^V &;=(j)yٛuQy` u두NO95?*Tƹo״FK ʾvKQ?T k(Ӛ+u]GLhs X[ofgߋ^u*Pl%5t>u "(.i}T8AMEᖚ3ةֿl`Qs [xb<9}FwEBD:Y!/)n4<{i$:M Y,5 &5Q͗A,Ux!a7_~,}a$nv]N^c ~{ %&+,H&x4 dQ |_ C vC CWÚ>;zJbw6_ 5~yg NYپ08rP.9HuGe;GCִFk4^?!k$ %fJ7dnO~$IR$LvX;,. !2ky40_nC͒4?55^k߻ݹIlS %-2'F)&ҔF )E&:{ڑ: q &/ w56G0vu4{,8 ݜH{X'(* 5O+'!mxAGfwFzC2Bd[\ z4j⨙#KwVyns#Fy$ɂ_wuZ %潩Fc6'd$FGSFB-g4O]r6*)Rla!fenrir-1.5.1/config/sound/default-wav/ChangeTTY.wav000066400000000000000000000703201317357605400221410ustar00rootroot00000000000000RIFFpWAVEfmt (  8qfact datap/q~$S ;L9 ɰNR93e9C9k++ey\@QG/)gJɔ ma9"le "E}wcRt  cD ]brSl Qލ硞=Ѯ~!2z?M@0|}u^u6]Nj)ifR@ u *-P߰Rb>2" ߠSαyX;-ɠuqsF%Sx}'/!ҚRmy7ntDN7"T1r7Pe HfPB<%`YrG wË60|]66gb@@\oXRĨOVA9I3R~}/:[=S.0bYo`ȤS`AOc*'1[# Q m9/ ң -|޶n'! Asuc'fZfV~sl^Zp3 WZ_@R>"N,f"l PA , nR%0~p: M5fF[O4"H;pӞ%qkg~~Ʈݕc7lw:҆ <߂{V6rB嚱p ˗KMќK;Vttz"ѸH{J׳z+tyWBL&K}[)-KF5b2pDR0 Bx fy ὂ|ZNvfs<x8M'芽@rT";A _J 2 ?kUtǪ V  ا Y?/:3(s5FaR5#@ta ѻ {h ̔X ~ } J[ vM9 uk-sȧuJk2 C~!O+jtA  iRhN3BLjelixyoa&¹DR*QM#TgØt=ܮLR. * ] Je~kɄGV}]TsLp>kJQ>@ݠhVXNq&w KJ 33HWyC ɺK k kDZ8 53bDm5NhgU/Bp()u yf~^. }yQ5*y#u3:ZHj T4lĚpN= )_?u̠%+P>CS&;MP]-#r_A"8l "cCVޒtvuTI5ReAކ> (؝FyV5%P Z |"$yvdB~쎌hJ% `BW,fXE_ 5[Sި"'m,$  A 8c 5 ը z?~ΜR/C)$r,Ij4 qb ܴ y % bS|;Bw^:jhW `y? ]) z | |/ V @ E $ x`  LoBx-H2\DWÜ1O>pPduuzbՉGBt=_;`Ē%۽B\ihy~ofg:CO\B[{b%o𵩔0˳wOesV@fgEv9X{6<X.T/TM[dZ!dUDetCe#$@gKP>\"b C ^fq * C>k2 "0$fTas: Jc >0{ uG0n]'PBac ۡ I9M wI^,  Q5de}?4E=2<^ SN ]~S ˻y_ejjBi@8!$,tD4^Ծ]35f:g!Ap& 1q;jM~Qj|^l  3.1 9 :.WCS6OL+P]reuqÀynK+ZM9gb} T Ќo4U˜Q z ~ *D]ٻ^6Kl ɳ +- e@ / @Oqi`0w|EA?QxR`ۂW_ikL ږ{n_0!*io"X}vd6-}yw#+ 6Q&,a] 10ལOA!DjՔhE腼5K:%?>IIF/:*ggueIvY^dV}L?HI~ L2Abk^cZKo% [b̆ 5 ) :#p^XثY̕'ŇE 2~~+\cۡh# q](̤~5=yj}g @ IShm??I x ZjɊc` 2I|GJ+9@)dc R,5Ƨu[ T `yP EAoTMeO cN]#Q̚B  \772b=s k S Ȧ<  q z@ kk V @H}_q'y+QcSSv.(w N .bly >o,A9!DVYA8G}aUJ19"B7}4pJz L|y5$&T}=1 JJ쎇@*b:g)2+,r ^B?w) Ԥ9 Hl<#QݔØz DD,ūYK:%a3 \{x Keh DG0n:1Y^ƺ st =* 3Q  _v GOGAs1? WrJKrSUߟ#?r_.z&2WWJGp%dB6s;٬i+4ZO jݵU$qA~=.:bޗN|4츚E63NӳuAeTXpvr+JgkAk,G7dCn:*5]r#X *~Fj5KY[ade nZj F1~rO=b=o/<]S`% (~  Z -g tTfCh0wbۘ4 bm'jI{$q I Rtw Cq5 H &at$0) 0a/7P UWv ?K|*H-r<ߗ2uH8tu]:zc܍Rő뛉 td٫G RfHM1Z |dQaB9 7qEa?`$  B ' Ԛb@jt^S{\clPBJ|Wh|$8H~/CW: <&a8'Rg(QyQI1/26ϔP#;_wBfg2k#)s!˂ ?N7Y\kI&H/HIԿlN>;qJW;ALsooC2,9{M~/ αse/ %n „.B"ufegԿcy^&ᆳۖQk{!Fػ?~dNItFV ULQt[dl ڲ ħL.$HwJIk+:!:3ib#G^iV Jշ D6HX5~.#/Q훷u9 : \H0< :r  W= k C? ת`I |*9EQ3H%UB]pgHy(`%Y>O`>Cd2_BuănUeIŘ ePe ; SC?`?maׇH" sG a>X M y7+ o i2>3+0| II  $ ?S?c<7 w M,%945Xjk ~u- 752fw-E SWjwmY= P DE0{IlQ b  [x 1H` a0cLU~-Ĵ_-Gw >\P.|2F | ,*s)" 9$^# A pUN@pHg%38@.|c+˴Sи"׵ Cw/wK ; yԳ*h ZX|0|$ʣmL$Ӓ v9֐%Pdzϵ 󟈱}樂g7FA`T8,ҙf+jIw  4Š% kpd]T:L '3 mx{hVJnN#mS~LcS%GI\\v&`be) Lb"8 n {weXs+5(VnU)%bzg @PA\ dX` h\Nf^ w<aIHhz@2›"~x EzppxL ldžT wj^.q̠`Zw#KUHƬuid2hE&ClG8f|B岉~t.Hg~o|dLw)3ՙu`>P8g$UL)-^8#H(~F\ߑ|5[i*nH-%K,Z5P R9 r2^< O26Z!A#H%tw:)a+|'n$NK'$xt$s$5x*#J#xz# wN*Y?=NG ɸ $ 4 cL mh ]P n)`v˟ p".lY$cD#c$@x:'m.'&#]WtpLW w HӦ m c-f ҉ *eAI_xkV4d9ڍQ [rBxLrŽo ן[ A4P fA6R w ^.fy:9_|,1D#\'wW$p>TԻ?Y \}=" %Df;l+{k ӊV.b-{@;Gt( .דE?ʃTK_5|N_pvov r y~ϼFzh[{x\&$i0K1q4?^lʍY[ꈘߊ"oiS,~@2nC/P;k㹨'iW䠊9K @Kz\ ߚsCVj(]Ҭ<9O"6Mss_Л(v팮->/5Cۮ .GC-:1MY8D%@r;WSYq@^RQk1@Bw. WTrnH )Ux1AC@=m՛$XGfS׈vP lLeKT2`$1[L\, $rH$D95M_bQ.[^ 4C CL4^OnNB>s޺a+vil9즺6:cgtV. Tc;T?S1ʱS5Q "H) >c m + &*k)b#?)QU3/ 6 (vyI%4 hkmCEWy:;8 C@f} F=1Ontu`i+} X1w6/oa^@攫)y`K鬤yF3F0fԾXre 'XULh <a5DLx*bГԀO tcR2 "Sچ,+Mo> 8]sW/Zd}%boO^؜s{kYג Io 019ؿ;LL 72| ]Ή  x 1`<ӈ? leZ{bϳ !VX *t]Pn HI\|LĔvs԰ۼ&ѨJ%ªK.xq!la;GJ|RB"Ai5ҴixXdεՆ?ߗK>8T p:{xISI@&5" `jX \ oiflZX$+ij.S+d'(a'숝*K{,9,-,`01LH/(%7aSԙ+ -W -B,4.6(6?0p" [(|)>W%&6"<#$M}&"78*<2G,+'$$MmԘ?+ZP~U I?/]l) G5m NI@p0J.vtpMQ_art"^T:;Nz,5RM|pPE3O'v=,F4 :n蠹xISDw"]Byayyq8󅴰F>ԄJef{ϗ i,n[.X!O!x2:rIqӳGmӣ{ {^ ?n,ф6cuF9O5QWtʯF Mg OG~6{A ^%o=Em"%"#9_+$= W*-~sU|F ad1h |iF|92cF\> PEV͇⾕If2 bhP$mTh&8Nv_ox8asj qGSgdV(m 9AG~leMOZx-iHqB+HO.KoXd;\* e #|dI5 {gIƹ ""K#n67OsiOr;O*Y tr1j˔T?;O 7x ۟7 3 Wc+ٮ:7}+M5!;S3{վߪNҶKbXDmӽ>m t6e04=1YP\ ܁x5(݇k1$@UU qRA 엣^.L즃o*;r(mro | 7\'d 4/cP??+ސjď?yE)& [mFY G mJ{&,1v7uA{i+{ <ζ e,y  T$KS+TVWjy ?.e0SiKТ``68 Z?'7w+wχ~E 9wN?!O`O~D%I‚S$=q_H1Ψ [%ճGB ); 'ATP , ZVyi? ZN!&"Ac!(! ac p9x". @ .ѴٕF98;YHV2h0o9-5t W`i$ρ$ø!:o)֣ b^T˛ i W UIWf{B 3;:53sx1G;8 |_ UH'b9T!fH gIx#0n=xٷvk!TW"#SGgc$j vy62!![#7m G' Vt 30<=Sg\L 3A[&_,n?AQgs(^[%%$HY?P 3D EqA"\cg[>=W;z F(C n ѕs3u il ѻPG\䩆pTl޾Z Y* {l3JC.='BB`z ?Zەx~ j'*YQ(jXgSm Du;rdD np[*^.+km*K #v"ưV#\6.@w7)7U2-PN%̦ 3Qjf xx& SJH3ViF,4(eP7/! .4 )e+!N(hUlD `NW m^$$kwh 3J RsM|e_%o,-~( *h ܉P OLtڱ'=樵ɟ`_mM 8I f"MUxWmՐ\߬1u7< T@ / |6WJlJ A g ?:a[rg6A @#>Y2ؚܷ2fِ\r9+'@g[]Q-$;A?翙 8܈ɩؾS#;T5Ps82@sRQɟ-_Lg4I |؜Wr8TZrsxKj_5KˊE7tJI *9 ʺ#W'|ftH WSkm! #r7+ui Rqs W3Wh,˜ ( KZHYbO~>Yk_ j۶?ƪAPn"w+?2eQ/9-;8\HnzV{Ñ"v&̎A,jS }˥8^{@6 l eYEZ@=ICѸK`Mߕ%(U-(!^! H:44~kƨ  ]" ~j,4_GICN節b~x|_C7{ty - #* 2S1x 3qq >  K B eJ D0i2~O 4$O~;s-SEc ]>cr)Ljp0X&5=  _7]:<y(JM !rњ!?Qͭ0Z M_ ^3Xc*J(liF3--J[ EO ڊ#۝J D ·W >N!4X>v óo=X 3e-T!mѻ=8[!$݃1d>[2bf=/@k(9oV"3*0?cLr~20j;sBdžeC V OU wi $4llt?$ t :G+38/#?~mVY-Y 5 #Z! 0Oۆ!hDG,mi"m#qCXl!?"Nbk007":$; c#^,-O)& A)BhZ #'S}*nHǝ 1! r 1 j hg(yzh%?<䆤41*bSu2 (~aҹ,AjPy.̟d8H({ z\#n'wO$u3wciit\~IU\0.b&1S,SV8D{ɍ ].(8cp L=];<dL)tP*/ ǐ xqŏ3 q ˿TWK`EH ϏKS t7[IQx l*6h|"FUN P" N}peZ2U..D3hiFi T< 頻,&B8:T x\ Dp']A@V.RR2| e0@FXGal}v M%'Gww؀ߟٵsۜ2!RhMfyQu_Jvq`BԷ",&K}/flk+,[Z R@nXEE/pDN̓͊).eȕXѝLN*ה+և s)Chc_5V_ *(IVb@ZzRf1Sܦ,ioOGN cϒrX9HhW evЭhrR0Prc3 0G}NFK` c * tȽy|4cF2rBeTB]T#-pz"7 نX(1/ 7 f ,H8ʾ62t{LFXFHE[uH.)]BsXܬwkJrށ!)؞l8۶[3L 3Gs>FؘPk. yy \Tߝd\c 1OR@m~\] =p+Bqxأss  -':B!Z 9Jr1UE/'İ hZw PF 8u :(?~R6 -H R0qh'!bU ~6ߚ 8U /C iqnD'jhh)*  F1n =b6 )_H{2 SنgMTpL&San$Wb8FTMj ,nHL Y evnbY4X{5r[Bo&rUr~ db3'~6*jDmLpI'8Z ,Y(kcѓnϔeh,Ir竁u-(~&Ti%.^vu> -bcC jy H=5FVU2J=} ȖfNRU* z>k3/+d LY;") Ĩ H.3)AL23:*mAuףWSD.MIf|KכHϴlZXaLübptk֍ b~'j%:6Dٞ6n\2CS is nf>5B -fQd {"GW SE u9V)3O&1!$#n*ɶ?tӚPT@(7 KMOАv9zFQcgB RE7 'Uڝ+>" i]g e! XC1g2,ʦ#NG 3*=I2M8#+y)'%Vh uoۑ0#Z<34$ܢ"LЏGsKѰ eO0 ޞ$PWp`>/\ *\_K3A?(6:" ,5`G&b3i#n)n!(+gW ?[ϝ ")!/!t%P~v*GP=| Q //8 : UUr+fyMϋ^t64 _w R=\ $$:}dAz]EgucfbtM꟯lՔGNAe6ŪzsJ-omE5zv潂w Vӑ\ R;Ə7_vV|L-,G+)\ё@cRl_yXGs۽l]x[d"#T͡ҵR՞&fe5y,[ERbMNd%*Z qCo~/׃W"] +K)-8 ^r \I `>v-rAx a[}W?4p|fr.rR7I)  kȴb7 Nn_  6 Db+䠟GRut/ ߛZ5 Iᇂu& /'ۄO141C&[ ,굓jEVyg36`$0%Cavb \Z0!eR{pc#P 6G-Q_w=6AV1)Rj!J'\%" C&"q'V!H8""Nb)ֶ&bVF 0U\e'* W؃"AX;%l=105 "RA8f6GmzBf!K>no(H>YK x+M|o> I) ZbgS "CLIk})V+*I9kTۉvhn + ',ua̬%(JiG8ss $ L},ku7j2VQ&q PIuw ktJ$Ϣ( T1,rEǴdH_A kr yf )20zrZklvE2`sn8 W򁁡-FH8bYVD  r E\ <!^,$V =oH7ro}0ϳr:;Z 0t~bLsq_bTz>0/]8| fC=`˦ժ<`l*g13; E "!ED:j,4f $V|H?'ZNG".&4O8In wqۘ C$&] 2@ SM voRLTݭpJnd:i(wGڞYǭ=4Q;&-u9hZ߯~A0&u6]9YYJꙥIz7썸jr?׸&⃄G,ߔ Լ-#!8D#`ɐߌ|u ۼ(mQvzJױ &C<ΔLM>ڶOw#]ݔBp ԔM#h t}Vz.- A7#i͕sSZ$cX2a)م2u%8O)#ySwN<&R,aj(kR~ I\K ] Pe>)w# `跉I2)L~sD%e㵎Ư ?#EFKWJ 0zp)?RFdrtyE)G'/ .)],3't) \%8@pqߤr%8=a1HpsLQN ZQOOa$Dc   )}& )%tb0S\\ L/y14o=6F#|k q ƥ #9b)¼=[~lWOJ, ( G.S* UEL+ jATH6"av v|K S>mk#xk`ɴ Ż+a1Of eC. 96%z #Tx9;:.h* l I/{rl@k8uo! hG 6]/^ u!Κ <ϋ}6Η{_'\Þ*F%` i4oIDo"'lsz]1`R +tbM9WtE< ҧhjk󄽽n!bf8'qw;yƥ#t U+"j#L 6" /|RՋ=BlZ[ |P4B_+X$4er^c5 {*,?Ӗ#ø E, * .& >?1o|z^ %)cpk+n>xꩇ0ls{mH\K3 ivxOfx;dv*!+/c=s Tcdy|k-UPm%8=RPaE 0(`fd&oP\ 2QcTQLXd 3<:$ h Y ~p&pj.Ĩe: DV&oP Lc?x0+]k\ r1aH bClZUx!ac!$1(&!$MJ ь yY Vpo,u  D2 ߮'g{))V6>(<p4m; -8~wD{7Beo=Bl 9f1 ,[CzcT4OmڸvQm!{KT[aHa;YF?8<;1t`NQak# cBb/McI I  HnA !a!x[Mwg._ m~; 95_g3 # kI:h|: ː;sn9X(ljb} ϖObʻ $._0Pw^?,Dwu6Gト;ؑ+q^&t<`k☮_Te:; UjMHbҧ*&o>Ktއ߁HB4<KIN+5&4lq9 J_hU} 0C 08e)xR#c1M e&[i~?w 59 Q[5/#TM3`;uJQ#Y:8. `@H|SnP)G' C7hD3&% aTfhT(t5m k70iAx.zl*`A1#Yh!H4N '0+qVۃ8NiPf蹗/Z ⯌G7cOY/cv/%\+\i(y1v>0q`q')2$J yN!csge2m < $^ L\m oꔆW) y./쩑G su-_V%9E6!IJ΅?ln> XG M89 A ~g6_ 7ذt"嚱37 W ꄨ A@ _'4/0%թ.kHc<hlËLUed2}Rr_VS.iޙq<? e.b 8"% bK=;؄ w7 g^8Z IJ lYz]Aܼ^w V  < r([434 ęƗ(7MfzqE*SS A_Z Q vz,A90H$$_z uRD^0G lC)SI)1_諎6IP~)vB"ղtz;JZ*ekavb/a4  2h?^ {98kp ńs ._ h~xU"+r0X'*\ tN(\YuӃI P]T#d &+gK** kS9ё{<l) Ly oL0qSf3$h! \Q"fO ;Z\{X˸BYOe}LD#_$4o|'vYRGit8Inæ{tN%Gdm8 +' {8:wPrjoIca N|>9D ( c ={g:QrwX/C2'ԋE|B;RkfmY%b9u' NvV!c Ho/=$768-eQ1+1"ƮrW[K-#?!CȪL}#}wQ9GA`rcI AQ#bJ9H3BK(kL]ܽF3ҙcktvTF}!! 1y\5JL!1Ci>3n]Tqv9ubt% t!'B > CZ `TMoV=' 7,\*i!'U V/TLt<^Fͣ߀xp[8-IނrzSNf? ЙݿIvis $OI  Y zXm17H  G&^+Pz { ty Dt csI!sTd/.OG {_ !ĸyڄ1S9/e % ,]p]CS_W9*-JiJ#W hbmB 8p܅ ZG9  Zyu  >K;*"Ft0;A˺fwߧW_ Q >[ -+TwI 9 vMqD-#̆/_NAO#'x P d8mt `Ҡ4ar ύ΅RwQ{ #-kǬP̛7ggm 14,!i;. -"Ν Z Ŀr 9"4 a.r`23~C1.?*93{f7P@֐~&Qh{|)i=Wͻ?=lrqS%@TL)-JSQ΀$st><̆t_例Naȩ(Nܙkpp >fT%쫪j?iz[5Da:fzNo_qlQQ<6@SV lf&;4 :P o pJuj>TM( "8ǮX /-PҢ C mv`; 8 U{l+/ǜVu]z984 C _QjC,#Y0kD` Jst ycNUBdI@Nfg/HKO̓4,j{xG0IGdvH5Esn&62^5btm 𧡸G 쫪^"F(p{N2g vF]X*˜=bNIf 2-5wx 7[2@l)ERUUUTYt ,ߪ[;:]qi D[_IDW;Z@H BQP6V˹~*XO;PU= _enC# ? N@ԓf7KAjN. i K ni=9Z!CR:nm . ArQ{%u.Ylj,,"oSfA@:]. Jt+gDnvVPc)O? E{Tn߷ #o0F#%*7H-c=9:!<X :Ah WɅaHKX`M7Ӯ+a`\'`@1{gn6XD }۩g͖K56lD_&&"IzXݽx Swߪɴ :*>R g#̻,w(() [yI#߸bYbXʲ"zm8%ЪB?' q*J -.d/ϊcfE2+P4V*#}7-m:< N/ P?s|AȫB׆D ǩ"G5rDINE< tWXLR XRNC# P5Q\)T`b|V#,N^Y;[U=^?Ő-aTJcWaf.hUPkh}!%/nh0H#pS% ;cs*&u퍨(AKxs*{/{6>,} .ϝ//^}]1Ԯkzk36wX759u070r>8p8:omlf,?h?eVAscC v`l_cE]/G>F[3hHXxJ ?VЕLTSŨbNPΘ/PPN QWKS"IoUF'HdWbC˯1Y\A[/Z>\YJ//Jg),ni0{*k{pFjnuC%l%}kI NiZӇ;F~gV"ke>`䮤c bҞ9r:`~M~i^چB\.Z XeYһ#WϟaRU[4͘SʥQ O| NCC8LWfJmŽH3#F0D%$C}JA2uw?'Z_=Uɫ];o7o9u7+8gϷX6DɃm4 2úa0dЙ / @ S7-kXӐc+м) 9tĻ']d%ymg$=݇~^?"M k 颖_-=!b. 3 D T+oD 270 *OGޖ]E Lmo 9dH q:c6QCsŨ%QmJS8⭌Dp];ZC` X===KXg m5 `ÿAӜ>hyϘ5[4ZU6ʩK'-ȂR+TnbD{o*pע„ryd꺏o;= }dt0 "^,ܠIEֳUZ"H`on: ֹ #zYߦ)u%>!(k**TOi4-wt /jtG2=w^4$S-Z7"9.,,lu2}A7fD3dF I/yqK*(NzNP?rAQ9SXlUnIXu"YZ,Y]£ۃ_^hb51*drwwgWOi8,M(l)k S ostgqĒ%ct͑Fv#)y\Ư{:b6~i3CL[ |dԟX6zyw)u{orzM p+fmL UkiF䨌hrȮfgcH酲 2`dv^"D[rc#|lY%V,⻹bT9Q@VUf{= 1}6;,薲84bҋ.6cC3#$֕s'1].N~ ,ۍ')ݷ'F$jв"K㾻S{- ^f!΅e7O[:jx oZ[`| <@$8xH|ptM lq9ExGomR425Wk_~&Ѥ i " w V$g%uSeemx:Q\pd{'5+,cٮHd)}!;cԑ)- 0c#!aNM>s#cdW%g<'8dU!)0~+Le,彨.fF0C<2hF4r鳨+f6jK8Q/z1:YmUE%><=zR:Bie8, x6RW x4K2`10 ,.d :,[;]}*fTp (Uޫ'>^!="%#z4#[K&8F!j(XN8+je-F|%0ݎQ2 %+5 ] =7 79E}t<=>= v_A5z /C #JF:+H۟< o5K|MMXA^nP5n3הR& U+~WEegYrh\:^ x!Qas ʄc09fh(8"k0 "m/ p4?[}rN:t],Bewm3y|NBL|+}~>~ϨY|x|y%swiuz.rMqzp56ݨm1 RX6k@Zhd)NQf7.YcE3maH3S±&^`T1\EJnSZ{_W3UW9KR0YXPPagMQnK3)ʰH\֮ŋFfD!,ѩAP8?}<|94ׅ0qQ.,#&N'Z"#Hu w \K Hğn,iH|  rR Od̫3aYA -9F>jHѷIp!8#s៼%\v'm)Tï+l;ƺS-Ȳ"/˕ 1od3 x56;M7xY9;7nBi=ۘ?F9۝As \C#2Etj) GV &ILc5CKWyMuxOd-QSI.!@U|W;-ײY\[}F=]=%R_Ra8?cYR Iec ܵg&T:i^-~(km E%Xo)1!xL4v 6tN9yvrxs;G+pp=)n:7@MliB)j 4DGh\GyL f*Iq dY LbpNt`P R^]CS["ULYo.X [W"gZU\>S(_QmaO{cM}Jf*KhuI- kիG"bkmIjE~~oC+rmArot? Dvt=Ky;w{9L2 ~7X56}3z 1xxqn/^tv -wsO+[q):n}\'l3%q?j|#agv!}ep'$cѫj`sdg^$^ \[WY3Ì|1ov*k //H;,#h*룻# (-<%lT# U<fⵋAylxs~ÊVuܝ/ lZOb~IynYPOp [F9h ݮئQŻ*ɉ_ԟp׋}if/'C{И|zZ$>Α,x8;"nI ͊.X^hwbg"!tKvẽKowid =ހŔj3 ݲ7A=¬}݇aѮc2mEᰏ1eێI0 t yٕ{|0 -@_P4֜"aEC*Pq9~ |ң5%Oy$ͪڣ t~ZDZ4"4` zmdշ%,CC=~fJO\>a ru^MɨzUŧ͞@ϟTk "҄/ $G&j).+R>m2-pKG/ \1FZ r3y5K H7G#9%;5'_=L2*?, BF.!D^r1jZ7Fk3MHz56dJ&e8zL0U:3sN<35P>R>ATpC VEj,Y &Hf%sJ2]1L!J_.& O_aaZQ;ycTǦSetUg@XiZk\m7%_plqa !r҉c0c9t fQvb|UhH\jxQjzCl|Ѵ8oV~sBqv2*sY}vOz{[fxZJxƉzyv͟|tG*r{m~Mp"|gnLy@4NlXw\4jaBumhcrBff& pGcjcnal_i Z]g-|[;eeDbYbGW]L`,U^^S5\PGYN~W\L)G9U!J|'R0HPnF/^N_;E5;B89@@"7>b>#5h<ůs39{RW1?7F:/ B5$P-;2+삲0(j.7&X#,f,$)'"' q yMM%kS&$#6 }%Cx$71nhY"]Ȅf 6H * C 2i d  ~Njq&[+sED UZ^)66G.D)U/VEz";R8zLvcU[y1ز;#b&+c;x9R |@{JPRC[_<YA;`@ՄN\5'B|ʸ͝?:wʆvN4)U74ŗìjJ'о@伇`PǍL^l4HNJٳom(5tsT[d ;­MЪ/U}Y*L%3[< 8fȡ 򨆟SE1Оtf g_Z?TD, !|L6ڏ0;a@oD yiK^8z't@H?U߀tDȆ0iRH$p։TȏYG GD+iƘ(}(} Ee٘+3áP)$#IF@lLo#e7ϺPn;y,RH8ya4br ƴKA;)+z9wi`cfrǹ!Þ _)X7CZ$&IIK C;:s$SΚ y(٘=[; 9բE :'@blz;v݆632r[5Ԯp+ůqSTr&]}b5ѥ기+F `OI B.s5),Z<% vH'ϧWBK Sl& :Ka ̸v  4? c,Ji(C YIr1! (+k#>%i'ݔq* ɮP,7"Ӊ.X%0A'U2qm)45 +ym7v-&9˂/); c29>9[H4O@Rkt6[BV8?#DG:6AF#+t-g1q\r։dP,pbm`zkf[^'Ni?5'\ lgY;e{W8 c0U_`g_WS^#QKy\NwHZ1zL؋XLJUTUH lSGl"FF8Q&BCRO/A!M5?i JJSV=yH؈#;ΌFS8A [D;60)B 4s2mfKn~ĶŝA辍bǧ %kʝa]r,̀cSN}"{#ʫVҮdVr@Cw־/Юc(,8>}ZLտdݿf & C<%iKa~qV<'|:{oa˹.s:a47. vVTuyʞ)%3)]r.{<230X_,p| ۯ6 / Tzo 2O3ְW/{Gpp<rq10 "yr.$#a!fR&G#Bu(;F5&=*\v(#,*.H,T1z/:/ %3{1ճH533k75;9w@8۰;Dm:c=ZDj\f֨hCd[%f:Qa˹dF_'f{b$D]p*]`Z?^X \.qVZͬ*T*WQfUIaOzSVM6&QKݩnOHpEQM4F3K:DZI@AFv?D_vd="B];=@nL8D$>66i/&-oL$+l"3k)[7\0P']wrq4%t)s #` ާ9H1N PKՐr uE) H[9@ӕ% L- -Qu 6a 'n\$D4ikamDrSyv9 د!e 4sSgDm,)o̹"Y9/+ UP=n솇WU)AaߨKW謒[|wftlPUy=:JΌ_%SntqH1i]OvZ"ϘA@D׹T ȜRfigy|릍 S [.贎2{dȐGtےGN3K hGBm([;A]0N6`2swj R,XR~k9,"˦gϭ't͔}Cϕ{ҪaJl/J(c:cd LxBy], nr]r¤ְ)5%ČW: ʣqQR*'WaM ]'G"7ٜ`J+GݶӻW %g"G^w'IAC 9E E{绲epSD>9wD2 x*>E!9W.=#<<%K'F(Y*Kh,*vpI/d `1ƒ3 AL6 bբ8k:EP=b"?(8A "UDEF- āI PZK5Z'+AMsL4! P&A#A`aR-M%TZ'W7&g)LhY۠s+}[-^^N/p`=1>b13x!e95D zgT7i]99+l;0n!=pG?5s AhuDwJZ F@zHI|ؙ#J~.L!ڲ~y9NFHY|EDPyNRܥwYT-LucdVrnX,p2xZ=n\{kQ<^A\iH`.g=brdd ybߴf!(`hK_]!j~i[lۅYnBuVBQpLXTrK QtOvCFMFypJl{OH*}Bc3F"JCr~e{Ao+|?Wzؓ<+x0dg:Xv 8Bt5/DrER3]pX0"n.~؋lO<,9jx)|h‰'Duf΂%%#mdc"fb$-k _`m wX^wQ\;R-JZbCXZ>*=V96T0R~ @)P n[#N#LcJQH] FG^H'3DrA ~?=, :=IX;Zn`9E:7w5P3v1/t2-yZ+fs=)>/'JRۉ%MSe#~1օ#!620Lhq͋ <˚Bȕ-O|qOt 7, ˼O} NjZ ? @Pԧ]~QF{lxf1vs8!;sU1qZ]nHXlt%j6? hmԝfrNdﶃGbyᬖ `P'JM^;Uz\]:k[Mi!ZtOHY[dX,Wcr V0'Uٜ2 [TASH SӀ]8RѤsRϳ%QͯQ˖0aQjRTQ)궖p_Qj3QkQ|R]|IzR\uRTԖS1exITPݩUUZBwUP%V2 Xse+Yص6mZ`t>[C8]p+ 3^*pc`/B!bpq<{ce go i#l< lnRpZ ոEsHqpu3Oxm?ܤ?{ ~` Xu1lDGiFrn{^k^g Kd[O`0%o\z1xXhTLmUXAP  L&ϪG;Cq >na :g^5%3ُ0+eQj&oГ!TRKeB|%"3J Bs$Kw&@T)W!Ǿ+ׁ).﷧v0"K2fp܅h5:ݽX17)ֿ=:Ш<= U?tŁ~AǼǙCqɝ,UFV%ˍHN0h+K[#0mM{PӃnRlTVׅgFW{|aYLt7t\*mr^^eߘ`Uz]:cc*~U㪬ejM6Ejبj$<-mJ4co*,uMqҞ#N\t4lhv?ʙ6y5l {ԀID~}BMb}(/zG8xnu2~\s]squpȵTn\lX+ ˣi8 c5gc.Sd #KXby_oz]ke [`Z+XhO`-VGEþS}:OQ/ u,NS$"pL$5JAg&@G%(!E)B=[+(B@-)=0/b;w183-65{>4S7Ǡ19S90/s;ݒ,n+={N*t?.'RhAm%=[C "OE YBG5Ig(K7ԉM@iOS62Q@Rv{pzT aV cXaZ,v@\ 96^`wQb$wdTUlifK[hӆ_Lj^U>l/ns-!p*2rmGKtMu`V7w8 ymy-{7e}ݑU6xg~2Dw|5ziזx&TMĦvQʶtudȦrmpW7{jnVt.lh3Lk$iʛ)gy2R:e|>/KcG$\a~ү0m_\$U~]d窉[qYuRWd=Uh QrSQ&Q# < .:$om)86H\4Tӈ3KJf"1dBÍ5/;aCI-$ \+f+)p)3nB'k%## !:K;tui"0.gDZ%XK: YN]Ҳ=cKxVŷѠ> L۷ 1 u^q%XƬn V`#1m8 ΋NdP@ez|մDɦq(r~g'mlz,r]!֏-mSXD[]xJxrωAH/8VM8ǽWڴsm6}078Qj;j|=f@GBI4dEQӡGaJwL, #_O=1Q}Xg+^TRYs}VM\YYi[}Đv\^ߎH` [c~y`e?1DZ[hMkjLi2[m o{/\r+ Ct&*]w %y^|,҇T~8Ÿ~.|֋|ܨy_LxwrB/t&ir_ WomΘjYz^h*evc YƎ`b;n ^7L7[mY#VéTJiQ pNiyLTJI4,tG DmB иͧ?? Qg=G^:I6s[`8 T?54Y3rtq80(RQ.{S+P۶=I)#&Rw@$jWk!j77R]h+#Ե.k!{ء/%'5Btu<4Tޚ 4j 6O^GH8?@U4!u&=yu[m4LQiѵ*+ H]pvQˣQ"ZՁ&D_2=7b! G*ڞ263{2#~n K 4O) X wrMZ!ҿ(h䌜Ƽ/y)YħU2>-2];I 8Yo @(!eƟKZ# 4ش6%xh'-(n|*c,ljG.ȃ[0X62Cϛ4WEP5X7F2I9 |;DW=Bc2?j ~k AXLB/.Dl$ Fi/uHڧMNJ]c2(LƎNG!4OҌQku]7Su葪hUsUAW"Y7Z8f\$ޠ^m,~`WbrC6$0dϨf[g Voijs߭k{imI+Aoq!0ɸr1tv.v5I?JpHG?nU6tE* Cu# Ai&?t(>$>'+:|P<<-|: I0c?8g26j5#mԌ DphP "~s+M wϱuT|8Ex*zMRl} :83l}AGh5Rz5ʗnYDxeHu s&߇p9Vmǿ_kBҶhh-5f>6c9Ge ad x}w^z ~[|75fMYj s6VD:"T k,QߦNX4bLIWC0ڍ!7GaXJD7[ B?*Tu?cX15N'Oۃ!`ʛ #GTk2  L؂Kϰz߆c !{Tr&X;Eq6E驰iΏބ Ls3`רs) O<GɬPW i 2L=6͛ץ641ݟDEeqm\օ5<C#NfŨ12;TM0䯼t r-&l:fÈS+`N8ȸ ]- V8:9֕}^tcғ֏p3^6NBƷ좪xn\)FOǪ2Tf3`ϣGcpf|BR,զc)cb'ؘzm|󩾿hA:] mPĿߌǜLjVwDԥgꟈ[ ,1=Jݛܧq,<%xox<}^Xަ Tχ_gKOA럕I"X_fw%"1ThdE L' 2 M ì  EHL*k~F\"$XD m<Kae  >7Mk@eq6@t% ^Npdrz_rZOK')6Hwn RBa?C  +ML-"w~Vi*PA<=ef\a)mHr DREVax|jVE,$82DW:@os&&it,$x~Q6C?|==266#{^d#of6DTc nrA5qhC.\@;L+ * hh+'J[Wk:9/- %~WJUKT_ )+OP:B zhR#qy8Q /MK|,)YF-F,'"J]hbZHR]akse+Zj(9[f@52F28d\I\?OO/{kE= J|#9azr@)T?jiB9=C3Eihdr4`IVq[AeDm*9'4(3EH~v|efq]JkC:#0Rl7~\bGX.6flxoZIV6VZ\m<mes`{izjp|_|7Sh~%gWoo lcNKZTv ;.Oif|TcmnqIwg<@/A 9aldaQpEI:M6{ "4G\Xgs25ACJ:5tqQN)5`FG4-(7+)L{wISaR E2]][lml ) pf; _D0h3a\ 0KR|xl\V?V6'oi5$(rS/g|p"5xH%! @Mc'$4=z_cAah"/=i,wM2y}HF~%/v;29K0b1G 1wfye) |^4oL<  #zvVr"#M[jmEZ$Z,yr]N%kkU @I_xdH`Qq880$ j^$@*m_uW7`6x+G'$)t&7rkY:q+/kj#)n2HOvmTI\ag^b] DU 29nn^aBo BcTv/ LA /qgscV0/cGtJv;@=?BXj#'D*FOhGF{uZ `O&P9pn /I47X~2>"5'!}t d4Pqi|/AEdHf1?wfQrk !b\|d'# H=<.AL3G!Yhs:XF7FPQahc|EhZC :OCc %D.8]Xvk\CQ2ob n]3rYF."&#^sJj||-6" ~{sF4O2kI'@B"NEAC3YI bnD$3n`Y4O53(,?SktRh,?qN#{pp]np6HSmsAWUFy_sK6"/1[9S~w?W~t~zPNlur:4>?Zi?>D)m qn5D%Xw4M,})H9m=A\lu01yy*5X|z~QTct 86mPXF i 'Vn/C#$a]kkcjCBv]2 viO$1pTxf|kw3FICz,G* eu:'56Rc $ R##$ \WDm3!{!+*.cXV7.M"bZo]B'CRdv{4>w 39 %$\K4y#DpYd!n|\gdQ\N (%mbyEX #5.%aX}yBL7He_IJ4eo1:65@4#/?`)-G7B3%&ejSJ#*  UW:@!%\aBSod#/D$qC)x}>L   7[CBIzt+$ikOM43vpfwngq<7t_0G($VI ==me15($N<I<ob7IDU  ""05wY2B7+7RT<N'/01% 'LRl/SYYgzb'_Xrk0*u>P_nYWt^RIS+(sz4/[f~e]t[7CPN 0B*<9}ivlEI%2aSF@aoxnXXH\"JID#yYH4kxP])WM6Bha$(@^- YM!"!vk_Sm]xWip/){mG5^J}>y=FGRvzY"4 Da5XMTtzCN#`TSwsYicx> HqR":<^(}}XZ0uch>z<:AI3K!'4 OW{]&i 7}c8W$ {Zc3>w59;#sbfj  Ym >^2-0 uo1(|uTB HU@byB N8 *<%U]`WX] & SS 31 NMic1Ym   7C0@:\SJ~I&.#  L;7kRx$+;COo}r(6\qX@ qQD tgC"1\tsL@\tJB&4}.n~uyj@5 64'JGMeSi'2kx*&up #^EkK)D$k`c :$ e!.) mS?C& tr+T(+Oq$I\td - =* E4uO7]XQmpnpXe@W>l_s>K_T L9EV}x  <#0q(/MIKXGWN[<=^EV|gO%4x78?n\!&Mp8ubrNvGt @(7+WAscTcvel"$Zr$=^efiKZ#d# vz&noX_D/*=h'Y~MntVyY*%.}v<:"eExyI_tN Z+OTk'+gc! p?l`,v, UelVurdR/ 0 U;Jx4a\0%ce0|_ x=_hEIM}oaal 6"_(o1kWj\8 . v4 m>~q9Z $-m`1d0C"Z/=SzA \ =?i%\>6De1{T%W kL8=| 2 ytv,!E/PT<U`Sz3./oL1%mKI'fP uJZ,%X%f\>Bgxp/?M/a yF{y1p WZ5BQY US%9t82~|- @-Jm>MRN\?YBuLt5lUV#u|N|PeLdBT?h[_*xkgxn\FgHqH8os[<" 5I:#~wS5uixe^S( 8ucuC2*.eoY{{b-mCY)"# H* %Gn>Cy4f\+0BQ8u gQ`Jm{% W5fjMWSv2P[GS"4q@|bXb/6F E/kX!SX!)'/|SJj}r)2OV%+{xoaMl/]*+1`Qt3#E>|ic;A?P5M0J G9u`u_CEJ@W&uc$(!!KW&I7dc2BzUg7?UO]KpXsYe\cxtII)6?CxshWZ_]pxjub'yx0=FI xnA1{ppw8Gf^\H?1z}bvu"mS#u$yx RR?I"izwm   F1tj%49 */*P:bGuG|-FO_ZUM?V=*ZL " 6Tq;;6rOX UgXTOH ~} tu\Q"3)48I(FD`ntx(K; "+/`jPb<5zp >P^s^o]aU> kv^fHNOH8E3zdvDC >S+h+NP)IsgrS#5('~i4_D t^W0RB$Q*z  &DU Bli3pq_]t?%Z$h_TzqQL0"x$!) < N_h?_1 kZ-Ii@xi]ZOU0aDpN)&XbbF3cDF-CH0Tl#)5,G1]S  3 xX"%2k5S?\<<]_  :,wYP3+.'puUW>N09GTm|*DGS }& \5K<Z^_i+4F$,.14<97!j]YAJ,D({ml8M) ]X `U}D2iU7 A@gmo>B-7eo)2??F?{3"uod[Yc?Ng{BHMW rl*% jbhWMCc\ii36jt|ft|1?,_g>E7;~}^W/&>-+M?H@9* ui:6 S_Vd+.p(/^_J;ymQHtu%(u{}0 25Sivwmm.3''(d\.)_[MJ)$LB*$*('(/-"(YSS[GHffY_nqfk6*UP42*'x{GH1,+.WiLR%(74[`EM ' Q] *340~{s~x .$;1tn (8ayo;QP["x~TP % JC$*) =F KLOXHYk{'8j{HF|vi`X2+E1t\E0>dqen&0"(+UN*jVOD){r`T|tXbU`PbDPYm!2}O]'OW=2qdXI I5@,/+qxrUqhh|8<HR>JT`U^D-sRjK4 bO=<F9I>_O[f>d9Suvs\Pc^f'!rIZ0ebcFHoUs3%#-+1w?Fd::=:i^t+ t~ r+vz %&1{48"G 7Q_~sf@y-32)&& ?<].A;  ',/lb^WJNN^Tu #Mqxsebg8|iw|.&0.7S 1i wp=9B9 }ZhAEBD::LL$#:G "hk{tG=>*qteD6??8+LHfTy-%+: ?^ o<<qs=>|meNJ.^I_]02rn|p-(tv2j/F:E.ADiN}:NG3dn-n-^+ia S_{A6]h}4tm^!jvB J@p0;G^Wn0W<nMokwJ5PrjgoMx=M*ZOVOK`@\rG~px1t_Hq36?<XUr/n"")3`BoO^=AE>4u3rP"or]{LqQ]$1) ' &&'Z- Pe9A?jUQ6_E2#m7.t<`Sl7[2@1@HHM)  }9Lh]T?>,%}% -8*zI_5Cgp~.=ww1._?w+&QJ!m{exBVLXwn=@u$s 0- DC/!2%;1mb;/9;u2%FLNPl_vbC^U2;" 27r{enCU] H> ]kVRutOIGLCLji/}nG+ic )-!5FT\ten+.yp-(n\n\+H9qeBKdr\nz7AOZqj&%[\TA=.oh%2 #*FIRQJN9<q^2aR !wvTWo{% Vg 'GFwe# _lX_@D39%w[]xhB;96^aRGI9yyGNlcwpCChx?Ef;V<&_t dFdHsg,wpvJ6Y:XdRv2 x5A0Ams{ CY,GW8TkMk1H NYQLmoSYTj %. X[J3USX0.mW"<*Y : us@YuLzax_)dA\ .:Mp{c: ]Y(e E |vjKBIw%  Y   Ox/F_zE*Dj$Fd.Sh7<c U^oqx^:}FQ"_biZ@ a  v J8.jSB,t-.IRJWYXjFmWpRsfyJ{}OR2)A*A1Bgaa0/5Ե(p/5md i u Q 4'Q*6835$3%W`JOղ0OZqIݲſ1)ܹ!C ي=)o٦ /duV B 9G"oPځHxtgJTeB/  *vRK*߲UkJ a,A%GO ll#0`bzh7)@Z9Ecx1uQ` XN 8^ Us@n (Te:l{_7h57QSOQC?A{EGLXNi*+ 9筫ת|f; 1ГӌҮٗ1IO"ok'i[r&M(f-e/%gWQnU{"GLk@ތ'ZBMejݍkGVz 71 Gv e D<  .m)D}* L uk d a &rp  >H*'  ^t J{_I'gJU-%AG# $ o "$CK' z & f.sW>%b!)k51G-aB1 YQ eTD#+teCQnv+\ \-xtIgXAD M,}?( P  [0(9/83Dz i  _ hyBh l s  7xOeF;8`42tOz^nb['^ A^*`aA7y%_Is[H: m.q <q@7I8NO6!Ha!?#pt ?(Gw]`re1F-9>aAL q|1i9ud)]a EpL!GU\I|x+D; ;2p\?G#rCm//+Gb=@>  haj>:i h*.m+M:.<C5fEujyn 78rq?)1Q05{xMAV`L"JewKza|5  !#*mk,9z"/YagQo>[u+U |m  N{Xoh= OY]Zf(EOSrUICP#HN kwbqUh-`[OhcyL[x <Cher !aR1TTQ&l Y3LJ(jA#/8EL\d|9F58o 1_KNDc:]O-s%h"\(T-@DXie?TfU+z=$\h H$(W$~Ni|{5P9ulpCX4M{ e&W\i?W13r@ Z++OpMSi#L>)~qCwrmm^g66)Z\ ZB\-qChQ9Q1+GRM[U-W jo$uRZGC<(J]w>0Xh0y+n;3`m6@u1,[ Ov]}>]%C[8FWc1I7.\Zu )2MAYx^KsxFme"C{V1=*>QXlTj_%l%e[4iiJfU.UBb? }z3 -/Z~~YM!504 NmqQ(%;=Y,7;?a hCLeP%1f $ q8j *0Oo)PISs"MLi#d/KvAD}0.Gg FT.}Gg2m|^9o}N"XDwInV W@LQ|HWAoFLw^qJf`OpkaM(&>zD.[hsq<(m@nF=gAD9vU@el#kzPm`Y17|T609x i7v0AC|="2H6_|snGy$~hqc9TO5'  dnY^yfIEKE|wM3J~0eMD"b@~W#t>x)<{Cl;1ig73.mgk6QH579:}+2<wZuf?,(]M+@z T$}GPYYrN|Dd1"**$(9GwJ hri2q;v;JuWan|&tkc+a.<<&mUACp :l}_T`|T. ewYlHU^Mtd /_RVI?zrbHf9 ~ ]>3'ao9vzOLs4xqZ~Z('Ay)15:CMv9/ucsqo?Z]K ~ V$c{ %_ ^ e59[Y(]Exfr073.xo"0(|yPuM|=L lj_|z&w{r2(" hP1#ycJgL/ V4E(+ jO]we^Bn-/a?|%[7+4cy/Vkm^oJoF QOf_ZPziwnM5&U0P1r"vnTY>JqHn LUi:o;7)71A^PfSG9 a&`iNoBxRJRZgsbwj} :!&V*iwgt(/4`aOcpGP A/?nwhtSY%$<b1wnt?: US"RFo5w^5d*) SpZ %6  GL\N+!w-lAPf]&45!@E0b&[(4NwebnkR=" D@N>L8swO2 F"O)dNK8 ' =?ict`j@J35'XG/EF`g8hw$D"=lGt>zH\fAV=WWNaK9.9>[tGT|0ZeswUobw`RVE:[ _R:*p:yQz#>Dy2y;W,3>zyo&wMMR9ajvrZ8"P S%A+ %"I#K'SD7ApV@_-*)x^e],5 1  E#Y:xcfi}yz{lAs)y3FtAY8@1+* 3;B:i.[&2Ag:] ##+&(7;8VIo_]+i4Tm3M#<;):OP-2D7`3q(ypg!E@?>Z*fR58cbF$ !#+ <B$7`@xc]YBN&+!1596') 0ym~V{)D 7( N$Y[?"$2ARbY:`++0('2G(K @06@MXC 9;F^)EwBl9rMfL?9eh[y2]F :('*=DR?D:0ZRl|jcSbHXM^H8- +C2 )'4!9/,.'.0'%'7(6,25930*.#N<=.0*.6<I88+) #17 20#$ 3(    (&%  %$2+%#! &"$#3*% "     !                             $$*)##    !%%$!  "(()&+)#&!  !#$& !*+ !%   !$'#)-0(*,0'516,/,/&-+*$$           #         $%'"%                                                                                                                                                                                                                                                                                                                                                   fenrir-1.5.1/config/sound/default-wav/EmptyLine.wav000066400000000000000000000133201317357605400222560ustar00rootroot00000000000000RIFFWAVEfmt (  8qfactdataeaj(Hp&TWB{ $1 W)$y gm źF) ewt,;<@;E. ,kF37i&DkU'Q+ z%F)<2 r8va?U,ءߖFσ?F0MOAši8"kZv;J̱:%㭂`B`,Ug9Dw۟}D QE7Z4Zsl?dB8 J"l~rɒ"R#amVʾaQ⢏Eě^|Cvh>'-?IQEZ:  ])( $0H8jHґ6&)nOuz<3Vd c0`EZ 2`{` x F `ȻF o/}|yH(?sᯓig3ۥWf:zO qb,I$)SӷIbr*>6fRQ`̴ԝ=N7(O4yp=h^,s8-4iCm"M nIJFC"溌S2 3s"zrSVb~ m-Gbkk " ç As d3n(XH忖E $V "!N,n+_ 쿑k5, f#Q'!.G]PVnP #B% =;Z_&>h*:L̆  ͌QŜKvI2lhE>tVMFa:$P3|0=|9HF @Qdz/,|{LD6i*Ro@ϻ483^l[ ^t \t6J8NB^]g>*%5'H&8e~N W>2$K9Z%,3743z rK\^+(o 'Gpx(DͮEԑV5j!%JC>W]q{ a$~0;9 t;͑n) =%$N; Ak.-kv(;"DU5UQΖ#ӻ"@YQ%\p)ת(W` 5cꧭ1_WٵwY,IѫΗi[|5;$If f#~*|Zi#eQ ^ "Q.0O5:O p :q!l 5jjMi/wj ו,>[LNbn BdY 'Y/n3" ,H&h1/Q(#*Kht{(6DmfiYoV?Q zZaٞ#jMH t\_|0u| 밣@ZiAc:vխ:#`sSRqF߭pE7jP 6s=Uy>"Dzr enOFATdZYF" Xme*VOr+wn(ۃ Hy]_փQ.hǪt5ldY("ս ^=T㘵ɞhjI3ѣ$O<PׯaxLR G  gky9衁 ӭS?T lOR`}9isŅ!(:2ug-:*.4 %!Hthd-%%fRǴ֖e~gOئ%QJ >;4FB^] +#Nj}7T.֨PBgPa&seB T&qCKC'q̞TC 7$Jhx!E+apg+; B?w&,> +N 4)HTHE&Jf4P BY8g }IL  ' , G_)SH==34e: ]DOs{!*}_@|<U _8${zTVG>3B 8( )%#18l >@# C4|z\I#)Ex"o9 Z šߡ)nwWf2S5W] a*캋cU߳ +r2'Z i!EZԴo)3 Wܾ˶i#P9o $T:Ei3SPCE7f:J zhn%9*^LiDf ,(Ź*aK& (/*tய 1Z){Q~³Q<) ${d]m6* hmX.b2Ct -% ~zmB%NC.S%_ܗe 6S&eXf}n'5b GoOBos`U , ! }IK.$Q?wN`x*aI$ކ bu$CQJHn"239 DS( "-8WO#6(;j?Ƃ3"'c7pK"Iȅ;D-@f2 VC)lL2 E#-\W Vy)N*5\g'a )eK(Mh.v،3YTMA .):趥'*tH ^- &2sl5"=b*W`xޝ5Zʼn2?9.Y=eUe 6nƱ7`d#G$) AAP\(?0A u 3&S!Jbu!Kҗ ?duOCZSe Fnb|b3 hfNZ*w"+Q2I1D A%, 7  ? "58lxV6V1 X?Dr5TPKqmBY %lu4G, x2NFLٶM[=.|Ա:-$ǽ82Zпza ̎۫cւS<(ޔ4+B&lC> Ĺy9C}xCfSl3C5fM]-.(9r]譤ˑ,"k}BQpj' iDقމwV pNT~ٸ7  H Hm  >lMWDN<㝋y0G /e$  F@D:oQ<R?a5|LaЍgw&m-? YߓA496im g:W 8/ Ww[{7 ZTfT }l^t pEd5N6.^yhdp: %tT+| %Z1 R `z-u]}(As@jYDfT՟Q 8 J) s2JB"")YСQ%> l';EFr^l$)L '-! ;To" NPg:>[R̶~8KI}' l t{gGiWɟ4+uVd4 Ȋ86 yMl$Kص'^m׋aF\X‡FۨV( 8>;SDHj(<A~՞ӗ6i'1ֽͤY:6+ zY""h ѝ 8 q:͹ 1E?1S%D=A^񿜡Hڿn}>%:IUl"ZD `k {f} קhYHv@Cbsc_8W#Jr ȝg#EX *#qvpa0}qQ22gS1c*21L'xk , jVyS uf<ܭ}Z]_WpJeeHyf;>TJޜI}"ׇzLOwO0ʛ܈$I <븋tގؕϱ+)Zpڽݸeڑ1s2R | vg`+&=^Chᚌ vQ=qp0s Łfenrir-1.5.1/config/sound/default-wav/EndOfLine.wav000066400000000000000000000265201317357605400221610ustar00rootroot00000000000000RIFFH-WAVEfmt (  8qfactdata-̌ ګaڈw.ekB `<TKHJ=ݶ+u1Xޔ7 %pCfNO4*[ɟtg^rԂ~ ➊ܐ|YG6ܪ%q3ћ0AŲwdZkPA_ T^H $<l0D1<ٽ%zoHnMT )`$l-'w+W/힏3+{7X̼;95ͱ?@ϥCGЙGjҎKUӂOvScc)kW@_[qTS_Hc)~ӊzPȎLW4zZϤh9vcvcj? _ #S"H.M<:0'Fw%ƮnR 5K^ μ(j6Cv ` Q _yVm3I{s 2v bj >]_ S - '!G 3#<; ?$0 KF&$I mW'! Jcp) %W'o+){,,e/.0/4sY18x2<U4@36Dέ7HB9L:P$lvX2a ?j\=,A^`@!BSd,VDGhN8E;lDG0p\PI$tl\JxjIh?L |&tMxiOPꇆRދ (TӏxUǓTRW2X)|Z\7];_E `u `fbjS!=c^!&eRa"1%gG"=h;o#IOj/#Uk$}$kaym%Hmo Ӌ%%yp&8r)z*gTX64BbN&Y!peP%ܩq)~݆}z-c1@599Ξ=!׸cAE/ЍzIo"nM=K跦cQ)LWUKLY w@]Y 4a#(egy/6iW;˱mu4G`qSt^x j|v׀酂Īc޼&?s4׽2ÑBĆ\zPnnKc^(WKlF@4z(p(y4V@4L/ȖXcYϤo+{ײ9b߿>BGlUΖc+zmnqJUb'W K? !4-?(y9#UEi3Q1]"h(&?t*R.M2a|6[>:>i;BFwe J yNl nR I$bV&WZOK^?b(&y3f2(j6x>nTJ8rD 2Vv bbyR m} y ` !"օ #ˉn `K% =&| u( *̟+4-.yk^0nI1b-%3V5J;6?+H83I79(wCr;WSO=1[>eg1@rAs~[CD܁F_HCFӝ8ߧ i,T a"b?.( :pERQ~]|iьmuJ;ٚ'а!e/羰盼$}=xȹrUNfK2ZxOY C7h8,  v`'b>3 ? J!V bK$n('lzu,I ҷ05&Ӭ44ՠ8C֕<^؉@Q}Dx͈qH_TfL2ZPmGOTCX{r7\,` d`,1h=8 lD[oOs,[wg{:skDÃHI%nV߮d-}rwWqTf1ZNC A7+#%k _1 1<= øI*?T`TMlx~[jHi$=w ߳g  ˑ} v&!q S"e 0P$Z %N) {'B )7 7*+*:, E_6-;Bd/SN0Y2!ae#4%q5)o}M7-i81}Gw:5$ <9==޸6?A@E `B|IuCqM.REeQ/GYU< HNY JJB]JK7a#tM+eX/ Oi^;Pmf:G3RqSStt^]UxjV|vXـ Z΄i[ˆFF]#^% p` ݽb3!ɚc!/e|A"tfp"QYheO#.iY# kN]$mB$n6k%(Cp*%4qSG3囎;ڲ00Aۏő$l [PI &!^-8l޽DDޛPٜzw\n"Uh&1t*-.¤2ɗW6⥣직:+ワu>`jB9=ǫ^F@RJGկGNj;RU/V$Zck*^H bq%&Tf2i=~mIqUuva=yTm»}"0ygįţ0ꐑǘȜ&Ɍ>ʁPuL_i.E?#h"fASE.B ":DaE%FQGo]OIiJ}tuyLPNً.O 8QR İbTU.ȌWt\!Yh<9Z]K\QJ]Ev_:Y  a. b" g!g'5d!D3e u"!?_g"Jh#Vj $bl$$nm(%szHo,%Op0&&-rrg٥7kgڂC6o_Oːsu<[`wg{r ~ݱލIykޛm&Gsb%V4ƝJ2>Bǣ3\'PvS^0  l$F0ۮz3c+'urRV/  )5A?M#]Yi־!;eײ%1q٧)|(ۛ-?шܐ1Rބ5Mx9i|l=[EaA#ĦUEi;JI>Mwe2Q'UtY Q %].a #Od.h(:ylFp6Rt\^8xD:j|vbRЍ`!xnhKlEa|"uU I >4 2 &s_P-- (;3?HIKWrW [c 9oe {1 s В[" # %x g'l E¯(`!D*U+I$n->/220&s .2AP3 -!X5O -688]D:P;k~\A="[h>&y8tk@*B.C2З*E6F:THw>fIlB*D~K`F MUJ8ިNIN=P=RFQ2VhS&ZTrT^OVbb,&'Xf 2Yip=Q[mI\q~U{^u }a`y Zma}!7y:c!d!"df"Ϝg/#i##kw=$ell$CMn`K%oT%wqIY& sqR;e/ЏY! eNB/ď6ܣ$+=ܹ݁]NK;yZ  h#8/͢vi;bFG#S _!#j'vK+䗂|/'tup3Q e75.Y; 4M?CɵBC^6GQ+KሺO_\S:WmHZ^{rb(f4jh@1nELȶr"X[ʪvc˟z,o͓~{χ:𖇯|sDpHQd-nYV M˜Bd-6*rW[9 !A乜-ٽ#9kgE1DQɸ!]*?htTM~{[rpPdi,=Y MwgA5ߑ* ~&[8Q){ &72 >: EfJ CVd S!b$m(ay#,0oM{4qp8}Owd< + X@ MD 6AH 5L `!*P }"T. Z$X 7 &\< '_ J)cJ+*g7t,kXC .ofO/sfB[31w g2{tr]4~57 9{p:oNF㭼.P"LgDz Z"h:ϴݳvdѷr'ŻP3 ,?#Ò KVMˠb⿋'nwӮ~z t5[hۼ86\CQ`EQϵ9._"gٴmCI !{s   3q,O8]ܹ,Dݮ- Pߢ[";g&sF*I}s.Zph2W7\6P:e/E>κ9BsY-F"JfރNB R UCY ]$ma%e2q1iN=,m@+IqUVuN`yl}\x|sjY? h7 \xi PDͿ9 (-׽"eRA )|7 紾 <ܸE *м p6f S MB! *N#a Z%% e&o qO( })}|y+sX-g6.[80P1D b394-.܌6!d!8<A9 L;K <v> Y# @/Ago;5CLGDu)S_F_G#jI' vK+L~/{HNr3WOg7&5rQ[;SP?4|TDC1V8GBW-K[Y!OPcZS@\ W^^Z_^l Eab (bfz!4odj"n@fn"KLgr#(X.iv#djz$oXl~${m+%o~%zqr9&WrDۍzڭPpۉ\x͈ghlCt/`Ֆ!ĕTYIݤۗ=+޸2ޕ&9rOBG,נ lUd,}rZV 8&뫱2=IU? aԳw$#fmik(By`,1 T0(I4?ڜ=8鷨R1 e_4"fS"3hGB#ֵi;#]k0P$l$$lهn^%Jp %&q52ٟ)6'|u:Y >56B4ECɔI^MQݪQ݈U_dYB ]mHa$ݟe{0ri<mH{qpT1ouM`Ƨcy*l[X}xL,䃅A5:垛)|DHXٲ6nV֘d-ºبrW̬dA)5AĒAņ#MkzȪoYo1Mecи)q*X?}LT@M4~)[{Xi5=wg &c @Q #).{:7FR:zEn^o#Ljdc'S(vW+K/a#@347oM);z?}WwC4 GաJ6NR `VZ.c^? b<(f3JjJ? nKt rXW zvmcnzfKo3c~({Wt]K@4 (y VF 3% p  3 !㩺 /#׭A $˱ bZ&O >!' -)]8+D,kPC.\/zymhm1nJt3bՇ'4W,6Kݕ7?V94:(*x<U>82Ӫ??AFBiDUEGca)I =&Jq2SL=MI}OUQ aRy$lm](@wO_DL T`H 2ybLZ!dO!eSh"8gW"h[v#cj_#`kc$<+mg %7"ok%Bpo&NLrĦLzZ) h:#ϓvܞ/d~z;s„XGg 4S#[ʒ_OjMDҠv8'ੂw-ڮ !5c@6 C˦`QՊ_nmKI)߱|t  (43~y@ȹrWL]f3X[!-dO%oD);{8-먇F,1I셓!5bp9W? =@e/DHsYLPnTKӸX( Ԭ\C֡`!וd$-mىh9~l2yErpVQ,ft@3][xiVO|NtCʀ8\,!jb?> xiӓ (ۣϧmRëJ)'}7&2}xJfrSUVf3bZan%OyCoɅO8,}y a > 8 b.l!=I&L K   +vY 7  C }g xO5"q T[#f"u 2g_%Z& s&O* ~(C. Ȋ*72+,6H- :`.>&=r0 B2E4ќ3I15MB6Q[8UPk9YH ;]^%=a%>el0E@i EK8RdXEg_&el-sy[lM!.O~tDU6r 8f|]>,  [   % +fO2G8(}? FLCSYr`n gOm08tzf,vÛWZ8 !OÝ"~#}_$@%!&C''q( )*7h+ I,f*- ..+&/,0Z319p2@Q3 G24M5NT5Z6}a7h8nx9BuY:{:;q<<=7>Μ?e@aABB+#C½DYDEѧF؈GiHNJI+J| KKLBM NprOSP 4Q6'R-Re4S:TAU*HzVN[WYUuo5v<wBw5IxOydVz\e{cF|)j'}p~Xw~} mNN/}񅫲҆BڿquV77eڍ+}_Y@!㔶"ĕN)/|6g=HC)BJ PpW̜^d6koqPex1~*ԣ’YwX9Mܪ|ǽΞB`Ap"6Ųd iJ*+# Y*0ι7>DqMKRQ3{X_eAlrpyyZĞ;5͓dȒ*bXC$͇εLܨ{jKө,A o מ5s$Tc+51ܒ8)?EXLR{Y\`=fLmszz橇@dהEo&띨4̵clM).WtKU7z @%n,}3^9?4@ FbMSZ(agfWnGt({  K ╍ yn O 0?ֶnĴʕ3vWb8(V `A"J &y-4 :!?Ah"GI#mN*$U %[%3b&h'ao(up)|Q*'2+,V,-./x0JY1:2x334>Ҿ5؟6m߀7a8B92#:;a;< ='>j?U!K@',A. B5B;CJBDHExOrFVSG\4H>cIiIlpJwK}L2zMɊ[Nalwqmxn~n=oԋpkqerFs1'tȬu`uvw%njxmyTNz/{||}H~yv W8>m#ۄ*037~=_aD@J!Q'X㋾^ČUekrgyH)J x̓>oխPl12ԚεaՖwX&9Uܡ IaBx$#+1=8Ʃ>lELiRJ2Y+_ `flΰs&zqTR3ַI஘wyZ;=k޾ݿ1b`C$Ď% ŽTȂ%k,Lʱ2-H9?wFMΥS4?E@ݥ@tA BC:zD[EhcdeeDfǣgs΄h eiFj9'klglmn-o np\Oq0rs!$s*tP1u7v~>vwEWxK8yDRzXzs_{ f|l}8s~~y_i@!/ƚă]g#H)Q 뉀֭̊܎FoPt1 :Ց hxY.%:+]28ݘ?"FLQSaYB`#gmEtƠzt iJ9+ћ hΧ.żq\R3"֮P䷯꘰yZ;E sߵ 9&,cg3D9%@-GMȽ\TZak!hLn-Pu{~ŭDsۜTs5 ʡ8нgĚ{Ε\-=[Ҋ!ԸOe F~'٬ D'-r4 ;mݡAN8H/NfU[b,iou[vV|7扃 縐O杜}}^쬱?C ھr Ҥ7مffG( ,Z o P!1O(.}5>6?#@d*A0B7dC*>EDD&EXKFQFXG_HeIMllJrMK{y.LMMANؓOoPtQUR56S̴TdTUȺV)ϛW|XX]Y>Z[\\L]^{ _f`Ga@(b$ co+c2d8e5?fEngcLOhR0iYj)`jfkWmlsmzvnWo8pLqqzrst@~u׵_vn@w!xy4yzcݥ{|g}(H~)Y 쀇 ́Mp%Q|,239A@ՈFpMTxZY6a:gdntݏ{*YaB#MƗ䶧{iJA+ pΞ믟5qdR4 *ץX &-z4[:c!'ɑ.)5;WBeHFΆO'Vд\KcizpwmԨ}N@/׊n؝4˫ubV7ݑ(޿Wӻٜ}^?K y?gn"H))/ 3673=mDKQ2X^yaeZk;r'yU쌠bCI$ x !">ȉ#j$lK%,& '2'(a)*s+& T,5-U..$/+011I8{2>\3xE=4L5R5=Y6_7lf8m9sd:2zE;ɀ&<`==>&?@TlAMB.CDDIEϲFw֓GtHUI=6JKkKLM1 N}O`^P?Q% R%,S2ST9T?UFVMfWSGXHZ(Y` ZwgZn[t\<{]ԁn^kO_0`a1aȢb_cdve%Wf8gShhi޼jkH~l_mv@n !op< pfenrir-1.5.1/config/sound/default-wav/ErrorBraille.wav000066400000000000000000001357201317357605400227450ustar00rootroot00000000000000RIFFȻWAVEfmt (  8qfact.data3XxDø2HzAҀ T]>}--vr;zOB8)xrW5K'ulܱ%2m֥‡`$c`é0u!:`ăE\]ŤZ6~Z*pXǡW?1zU UTȜ$R-jvɾ:OOʘ )OLq˺ KdI̔$4myF͵GIΏCӂ!i^ϱ@B.ϋsӸ=|eCЭ:>zчXϝ7`(wҩm:4ӂ=t˂\ 2ԥRq헰5~"/gnXՠ7,|k1ªzL) hSקלa&-evؾ1w#Ob٘F( q_ں\Kۓ\+%qmܵY@F܏W Viݱ%TBkދ;Qd߭ >PN `eKᩪ95 zH˿\J㥏EԄ5~_ƤBW/t?1~zD‰ v)q4SsJ#1hp$m8.}mFìM+ jhةb(Bg2x%ddG>"a]`^,9r[B[Y5W~'VWl1h~ZB;*{od8?x=6Tu`$3ir990o[Į N-5l}٫d*Wi31y'yf IS$c-^u!`.Ns](Cq[JX$(Xlm F=U  hRR A" gO Ҭ  d7 |L > L ΑI ׈ _ aF91vC[F5@}[W=+}p1y:@z R8Uw,u%5ktN:2(qpŰ P/Jnڭ$e,lk4Ez)hJh&eB_#b/ct _=D]_Y9)Znʳ[>W5}STŘV# hQ 譐 0 y8!}N! Í!R!M "K",؊"t"b #H#N#2#w$(E$p$G$%JB%%\%#&l?&,&q&F&<'A|''g':(Vy(A((&7)lv)c));4*=s*Ʋ* *Q1+_p+ۯ+ +9f.,m,,6,[{+-j--4K-}(.g..V`.%/d/00/xu/"0 b0RE001,_1tZ112N*\2o2ߴ2(3p?Y333J4TV4ڙ4#4l$5iS55F596~P6ď6g 6N7M7Aٌ77c 8J8c838x9=G99H9:_D::]:9;A;-;s;Z;>0mx>x>> =6?Ru?Ǵ? ?,R3@tr@ܱ@"@Mg0AoAA'7Ap|-BlBBJLB*CiC#CkaC'DfDE1DvDֻ$EdEgFEE!FAaF[FҠFGc+^GpGG\a&e뤸51~v#ƻbWFṠ _1z[޺  \S+pۻ,Yu@ؼOWUս(q%TjҾJ:Q$Ͽm ONF dK h4 yHB‹IEdԄì^=BĆ.t`?Ũ~C9ł<|Y[Ƥ9(y5n~6>vWȟ 41Ssy #1Shpʜ,8.u}m˽¬NM+̗jש(qb(͹gJ2͒w%ۼd$lGε"aFϏ\ס^h,аqB[ъAӆdYҬV=ӆ&Vk`Ԩ;S9Ԃ PP[դ eM5}5 {JWןJ0GyՆ `SDٛ/,uuAڽENڗ>~(Zq۹;*{Joܓ8#?xlݵ6FTuގ $3hir߰A90~oî dN-ᬓlث=c*Ψi_3x'f9Hʍ$c[]!4`}-rW]B0y[W R'Xl,uY/x TVR#,iSt9M~PÏ'NpM،Ic J#3kxGEHDg]A@-rҷ>cB~<<W{͜^'9lxﱷ8<6ɁuǴZ Q3 r 3ܱ |! f0! o!V!6!{-"0l"x"K" *#Qi##`#+'$tf$0$v$M$%d%E%'%o!&a&[&I&'*^'#p'k'(?[(E(()UX)g))$*@jU***:+bR+đ+ +2X}2❼2+2s(;3mz33M3=84ނw4'ȶ4o 4R55t5Iݳ5"5g26#q6k676|/7Dn77L7,8gk88a8@)9h919w9b&:f:F:<:#;c;\;^; <+`<8q<<=A]=Z==>4VZ>|>> &?UkW???/;@xT@œ@ @QPAQAڐA+ AseBNBBM5Bz C޿KC'CoJC DHDHD_D٤E"EEk/EtEFEBFDFՉFGf@GYGG_JGԆ9Ƹ_ʤDꃹ[/ùtA4}Dʼn>W~Y0;y){n R8>xヷ,u6SuN#3hr'p80~oJîM-#llثb*EiŽ2x'hfðGA$ĉc]c!Ŭ`,=rņ]B_Ƨ[8Wǁ'X[lȣ4Y󧃘8SVɘZ#hS뭒3|8}P ÏVMM/،xb JQ2w+GtGMD\'oA,rI>A~"kX}Z';3mz| =8UwǶ /R5xtܳ "Qg2q*7s|/nML,k'oa)hH1vٻ&"fkF#Dc[ՠ f+`p@@]хbUZ;%jW^: T 7œ O!Q!Yڐ!!d"3N"|"4" z #UK##I#. $wH$$_$Q%E%.%+t%s&B&D&L&'@'&Y'o'')=(Hn|(((">:)jy)ȸ) )DS7*v*ݵ*#*fh4+s++?8+}1,p,,bM,.-m-;-b-̧+.j.]2.w.(/7h/G/Ȍ/%0Ye0\003"1{,b1q1 1U2A_2憞2/2w3V\33P3&4kY4*4s4;5V5Lƕ5 5P6&S6nے6 6f7HP7757"{8jM88J8D 9J99`9f:G:/:?u:;D;E;b;<B<;Z<<<*?=]o~===7?<>{>ɺ>>YT9?x?޷?3$?{i6@îu@ @U9@~3ArA/ AwNA0BoBPBcB-C*lCs3CxC*DLjDHDݍD&'EngE]EEH$F-dFrF"Fj!GBaGGCGx)h<H͍&e_]#8b-r Z_B޻4|]W ۼV'Zl/ؽxQA~ܙ+[3| TXU#/iUw 9Q~RÑ*NsO؎Mc 함L&3ox IHHF"k]ﳢCD-rշ@fB񯇿@>W}ќb';lz;<8́wǶ^ Q5t7ܳ!f2qY6{/3n|K ,Uk`.)wh0vQ&fE*s#c[L *`&po@]H"UZj$DjW:fTē ?OQِbdN;4y ̾K]I H7^ȣEY.s3B{CĈ U@X松.w(=m|P=: y *ȸ s R7 v Lݵ " g4 &s n 7 }1 Hp  L !. jm  a D+j1wf(hF?%e\a"+b;qA_]7V\&YkY2;{Vŕ UPSڒ. wePP5zM*rJ JL_ݤ%Gn/tHDDى"jBYC)?n~f><{?ɺS9xa޷#h6 ;u 8 ~3!]r!!M!60"o""c"Y-#l#2#2x#{*$j$ H$T$'%g%.]%w%$&-d&Pr&&!')Ba'r''(LW^(((&')nl[)))G<*X*Ɨ*! *jQ+U+۔+C!+f,ԫR,,e6,{-O-?-K-А .L.a.`. /:I/0/u/0]G0E0061D1Z11X2*A2o222{2?>3 }3Tʼ33T;4.z4v߹4$4j85Pw5595)56rt6 6O6K27q77%d7n/8n838Gy8,9l9!I9i9):i:C^::&;.f;es;;#m]>˲>>\=?Z?Ǚ?6 ?R@ǗW@ݖ@X"@gATA2Az7A|B QBTBLBC-NCvCaC DPKD1DvD) ErIEFEEKFFF[F%FmG+CGpGGGa J@쉸1ɸvGbFƹ@~Y[Ȫ;ɄSX̘^#ʦhUﭔ78}RÑYˢMO3؎{b LU͝2w .IwGQFϙ\*rCл,rLѕ@A&oѷ>V}HҐ&;!lzjӳ;8DwԌƶ Q5ftծ۳ ?f2ֈq6b{/תn;K׃,k]`ئ)h70uȺ&fYEڡ#2c{Zğ U*`ܝo.v?]ݿPޙTZ♙*s$߻iWLߔ9~T&ēn NQHِc!Nj3x CKH fH]?E-saBB;@X]'=7m|=:YyǸ 2R7{vܵ "Ug4띬s.7w|1pPL왑.m*ra+jL1vݻ(%hnFﶋ%He[٠!"j+bpC@_ԅfU\?%jYa:V;ŕ OS]ڒd6P4zYMI2 {J _TG..twDDPB)Yr)?Ln~%>Z*Aao:?>}ɼ\T;z޹6$i8ǮwX9~5t2 zNÓ2 qTc/-nv3x,PlH))ri]K&-fr%m#BcG!W` i'l]C<ZeǙ Q >W ܖ ! g!aT!!6!:|"Q""L"\#N##6a#~ $K$1$Xv$ %I%1F%z%& F&T[&&'-+C'vp''(O@@((ʾ()(rU=)|))K%)j:*ܯy*$*m:*7+v+G +O+ؔ4, s,i,d,1-Bp-4-y-..en.I..>+/k/^//`(0.h0s0:0%1Ce11\1#2Xb252~2( 3n_3X33=41\4zț4 4 S5SY5ݘ5"5-h6vV6686O}7S77(M7q8P88Kb89M9$29mw9 :K:FG::; H;i\;;>V?>ϛ~>>`&>k]7۽TZYؾ#2iW{տ 9T~TÓ.NvQؐPc˜N*3rx ûKLHÔ H%n]ĶEH-Őrٷ!BiBƲC@njWԜe'=Ȯl|?ȇ<:ЁyǸa ɩQ7v;ܵʃ!f4s]˥6{16pK.Ym͡`2+zj0 vT(ϝhE.v%пe[PИ"*b)prѺ@_LҔ%U\mӶ$GjYԐ!:jVղĕ CO֋Sْed׮P?4ׇyоMaIة J:ك^̣G].ڥs6D~CLjXBܡX2z(?m~ Tݜ=<{-Ⱥv ޿R9xPݷߘ"g6)uq7}3KrL%0noaG-l1!wi*jFC'g\e$+d>q懶!Aaa:V^肛&\k[饰6;~Xŗ XP렕Uڔ2 zeêR T5zO-vJ LO_ )Ir/tKFD܉%mDYG)An i>>}CɼS;ze޹#h8>w8~5`tM:2qc\/n26x~,lHX)i1]z& -fTr#-Bcv!OW`)'ql]K<Zƙ$ mQWۖG!fثT i6{QBKӐNe` >K0u `IE:FZ\*Co5~?@XʾT= 1| y߻ $ j: Sy 9 -7 vv O O4 s  (d q1 p 4 Ky .n$Im+kF^( .his%BCe#dXb>( m_ϲ`=\Ǜ9 R˗Yݘ\"gV5}7|SWL1Pza SM1v- uKFOH[(q+EqJ@B$mU?F~% k<h{:B9 x P d6!u!!>e!3"r"5"`z"0#p#9J##-$m$[_$$*%5/j%~t%ƹ%'&WDg&&&1%'yYd'ž' 'S)"(na(䳠(,(u>)^)ɝ)O)S*[*(ޚ*q#*h+X+J+8+},$U,m,M,-FR--b-.hO.2.w.B /M/G//d 0J0\0=01,G1r1`12AD29223WA3[33&35l>4~}44<4W;5z5 50Q5y86w6 !6Sf657t7,67u{728r8NK88/9(o9q`99,:J0l:u:ۺ:#*;lEi;;;F'ӄ`>ʟ>d>T?]?=ߜ?$?i@Z@_@9@~A9WA ANAB[TBBcB4C}QC3CyCWDODHD0Dy ELE ^ERE F-IF,sFuFGCFGNGGxGMH̸ iJ]ɹCG-sƺdDB>ûBX`'?:m~=<\{Ǻ 6R9~xܷ"Xg6u17z|3r TL0o-ua¾-lO1Øv*)jqFĺ'Kgœ[ܠ%$m+dƶpG!Ǐ@aׅ iȱU^Cȋ%j[dɭ:X>ŗʇ OU`ڔ˩d:R̂4z\OͤI6 ~L_X ϠI.1tzF DTМD-YuѾ)AOnҘ)>>q}ӺȼKS;ԓzݹ$#mh8յwG8Տ}5t hMֱ2qB׋bӧ/ne2حw,>lنGό)`iک\:&ۂ,fq[#ܤAc톢5~!V`Xݠ&k]1y; ZSƙߜ P-Wuۖ fOT5({qQKKN$`l K/Fu䏺 H EhFBZ抟*Cdo筴>?@膄ɾ_T=騙|޻9$i:ˮy\9~7v5 }NƓ4sWc11py3x .SnH,+uk]O(-hr(q%BeJ#Wb$l' l_F< \hǛ QBYܘ!gdV6>|SL`P9aM1[v K5F}HW[1+Eypµ S@B,uU?~O%j<{(p:9xJ O۔6$uld3Fr4y0hpIB-m^d*.js='Cg`%Xd9("na[= 5^ }ȝ S W[ ݚ " 0h yX 8 S} U  ,M t R  Nb O(2qw MJG #Jl\F,Gq׶hADAVAқd&k>}=;΀;z_ P89w e5[t5z42}rJW/o_0x,/l uR)Di,u'ZfN)$(ocp?!J`ɟ#Tl]ޜ#Ei Z 9 h~!W!!AN!"T""cc"#Q#=3#x#ν$O$_H$$ %9L%]%ʢ% &[-I&r&&4'}BF'Ň''V(WC(蜂(0(y')l@) )R)<)=*,|*t *Q*:+Ny+!+f+'7,pv,6,|,J4-t-K-#-l1.q.`.E../0n/v/g/,0Ek0A00)1[h1c11*&2=pe222@#3_b3ʡ338U 4_4ߞ4%4[j5\554:5}6Y6 6VO67V707xd78 S8R48y89+Q9tI99:NN:^:ߣ:' ;p.K;s;;ImB>>g>=???A~? ?R?<@c{@"@g@<9AxA7A}A_6BvBLB8B3CsCbCZC0D1pD4wD}D.E GmEVEE+F/\jFxFF ,(GRqgGGGJ/n1$wl,lFF깏)i \h纱&+fBq#Acd!>V`޽&_k]۾9;Zř ٿ[PWږ5 }eƪTW5zQ1yJ NSÛ_ ,Ku/ľt NHŗD߉(pFƹYJǓ)Cn$lȵ>@FɾȎS= |h޻ɱ#h:Byʊ8~7dvˬM=4̆sc_1ͨp29x́.nH[Τ+k5]}(-hWrП%1Bey #RWbқ,' ul_ӽN<ԗ\ƛ( pQչYܘJ!Ւf۫V$l6ֵ{SF׎K֐Phذ`BMي0u cKڬE=ۆHZ_ܨ*Eo9܁?B[ݤT?5~}߽$jk}:E;z Pg8wAe5t5cz2r=J/o__,8/ltʹ)[Di4'|YfŞV)$nc糢0x>!` ɟRS],ޜt#hZN8}'WpMITb#kQ2wEOGg L\A ,IrcAF=WC_& 8l@  < [= | 4Q |: y ! Vf 7 v 06 x{ 4 t RK 1+qt`.N0nuߺ',oEkI)Zhڟ#l*&oeE?#քbʡgT _Aߞ$i\c9~4A4Ȁ44^S4>5}58#5h5ɭ;6z6Z86}6873x7|M7Ē7 58Vu8b88/29w2r9w99Q0:Go:⌮:+:s-;\l;;M;,*"c>k>&>k!?D`??;?@g]@ @P@@AZA AfAbBWB5B<{BCUCKC^CDRD7`DDE0OEZuEE F3ELF{FF  GUZIGGGNP(`ϸpM0Iu̹ J#ElɺHEZƻ*EgoüA?BcT?~޽<$i<ή{_9~9x9 Nɓ6uZc34r}3x0VpßH0-xm] R*ś-jr,t'ƼBgMƖ%Wd'pǹ'"maIȒ<#^kǝɴ QE[ʎܚ!ggX˰6A|̉ULcͬR=aͅO1_vΧ M8Fρ JZ[У4+G|pŵV@Dҟ0xUA R%Ӛj>},t:Խ;zM ՖOޔ8'wpָd5Itג4y#2krشIE/ٍo^g,ڰ.lsAډ)Cic۫'Xf=܅($nc^ݧ=!8`ށȟ SZ]ߣݜ"4h|Z 8V}W0MxT Qb⚧Q+2tw㼼ONG䖌 'Lo\帡 I,Iqڶ#kAF紆DVC֛g&k@A;р=|b P:f}"g@;z7}b8xL<5ub]21r7w0GoZ-3\l{ ,*Uqi/A'wf˥QV$c*&sk!`M; ] & nP !Z!H !e!٪""W"j5"z"#DU#J#Տ#$fR$_$$@%/O%t%%a &DL&&;& 'YI''^')(nF(7((>)C)Yɂ))S*3@*{*#* i*U=+|+8+.~+w:,z,N,Q,7-w-*c-r-4.3t.Lx..2/&Hq/n///0H]n000"-,1jrk111DB)2h2̧22fW&3e33?'3l#4ѱb44b<4 5_5; 5Q5̖6\6]!6f677Y767{78YW8K8839{T9`9 9U:0Q:u:.:w;EN;;P; &E>nʄ>>T?HB?߁?$?!j@j?@~@9@D@#ăb ɡUӞS _/ޞw#h \Q՚8}+YsֻMMVוb&oSظ2xHّQG"jڳN\Dڍ ,KrfۯAH@܈WEbݫ&;lBބ<^?ߦ~ 7Q߀<{!Yfࢫ9x36{{6 vUK➐3/sw`0Q0pu+.sEm弊L+Zjݟ&o*(ogH?%لd"ʣjT"aDߠ$i^f9~?[ NbXc<U3y]SH7P^Y -M3s{ CJU/XGw(PmD󙲃*=sAǀ LR>}&"ng;zH7|8"xjL5Cuaզ2f1rv@0FoЋa-[l;+*pi]@'f7˥U$cY%j!3`{: T] O.wZePW4*zrUJLR&_n.OHt !DLj DYI)enF?> C Ȃ  aS @  ;# h ̭= | ]8 } : 7z M ǒ 7 Yw b 34{2tw T2Gq匰.w/\nP,,qk*rA)hĻV&&en&k#Hb;! j_ PD\ feY5?{WKaT;`0Q]u7EN XZK2* {oHô U?EɄ.vTB߁P$i ? *~ r9 ~ 6a ~6O66:;7{7d77]884x8y868~69Iu99X93:^r:2:z:.0; to;T;;C-<.lrf>>>>K$?c? ?%S?m!@`@"@Gh@A]A!8Ai}AB[BCMBBCXCebCCD?2UDwDмDE`GREEE:F\OFˡFF\, GqLGG6GS.2wwҸQQGϹ*Ns\̺ L,Kqݶɻ&oAHƼHVEٛ!ýj&kBD;Հ?~f PT}՝!f.;wzֿ6|P8יxK*r5ػuaLؕ20r&vnٶ0EoHڐ-![lj۲**Cpi܌@'efݮʥ?U$ވcߢ%aj!ߩ`;:߃] ]OঔZ6dǩWY4y2U{IÎ TR^.v.OsP CLላ*r XIL(mF&n=CGȂ R!@j"gC=|7}e:zL?7wba41t:w2Gq]/7\n,,Xqk񡶪2A){h˧ TV&e.&vk#bP; _* rP\K eܪ%Yn5zGWJ؏!iT_C/QteDN> YKa) nH;>E\ɄS6Bށ#iX?~82~z<| NT9y.cv63vOx4)Hsr1K]p%-.mrmGB+j̩!iW(gC'l% Աd  e< " a > Q ϖ ^ `! f  :[ 6 {  \Y K 6~V`X0Su2zEP TZM-v* pJO?)GqʆUKD߃$%jmA9G> ~!Oi;{Bd84xey6>Iu3`^r:.0so˸\C-lͫ6~X*ƝiX(m'f2z=Â$ cS R! -` v" g !O]!7!|!)"q["L""K#X#a#%#m$1U$v$F$%FR% %i%&[O&C&&+ 'qL'd''@ (>I(ˈ((V)`F))%):k*C**;*\+@+ +6P+~+=, },We,,:-15z-zz-¿- 8.SJw...-5/u_t///O/20tq0๰0)0qD/1n1ϭ1J1Y,2ܞk2$2m)2n)3h3G3>3׃&4 e4h4S4#5Bb5#5h5 6d_686}6>7]7M77`8Z8b8:892W9x9[9:GT:5:~:;]Q;W;;,<1rNuH>>'>Ol?E??(EE1FΊpFЯF`FZ.GmG9G*G52u{`å 2T0ru.0vEoP-Zl៫)r**oiL缔?'݄f%ʥn彶T$cGߢ$i!!`j9߿~C] NeZc?‡W3yaéUH:ÃR^]ĥ-O6s CLXơ 2XI{ (TmFȜ-=vCɿǂ PRʘ@)"rgʺ=|K7˔|:%znL̶7Gw͐aئ 4i1tβvC2όFqԋe/Э[n>Ї+,pkaѩ@)h:˧҃U&e\ӥ%j#6b: X_ՠ O1z\ eTםY4-zvؾWJOؘT)_rٺ/QKtڔ%DNm۶ GYKܐ ) inHݱB>ދEȄeS߭B݁>#߇hϭ?~`8}<:|M˒9\yb66~2vwX4Gs録1z1\p S,.qm-vA+jO̩V()gq&l%Kd;$"ma PG^ !fi[5B{YKeV>`0S`u喙:EP\ZM񥟌5* ~oJƴX?GɆ1zT™D ߃S$iA-v9~>O ~N(;q{cK83xx%m6HuF3]r i-0roBB-ldͫW*>i'm'`f<9$c R\!`!5g~]7W|[1Lz XSa,1UuvOFR)q[OJ+ pLܵ$m@ IʈFU ךF h% j C B :  @ d O == } d  `: 4z y 9 8Iw[5^t5~.2tqWC/1nyέ Y,Sk(-n)uh>O&e (Sq#b#Jh _$8l}]FM ZhbB2WwӼdGT=\QΡ`,qN9A ʆK̊[V H5}&kEW; 1B y P !S?! !e!-!u<"5|"{"N":#Jy#(#q#7$`v$J$$/4%$us%l%%D1&Fp&ϯ&& Z.'hm'')'Ao+(j((?(d()g))>T)%*d*$*_i*"+a+99+~+, _,[N,,-5\-}c-ƨ-.W3Y.x..1/yHV// /R0]S0㢒0,0u-1rP11N1B2߇M2(͌2p2W 3J3J3'3l4$G4l4<45ED5 5Q56hA6!6f6B6>76~7|7c7<8K{8=8899ax9_9906:9vu:::F3;[r;б;;5[0<}o<<+i> >RU>'?f?,%?tj?$@c@N:@@!A( aApOAABJ^BdB۩B#Cl4[CyCCFDIXD֎DDgE^UEEAE.FsRFFcFCGOG=ΎGG6W~IǎոXT^ҹ1z.Qs ϺSCN刍-̻v XKOɼ( mH)qƽ=EKȄ ľR$Bm݁"gG?~7 }i<|LB9ybd­61v>wÇ4Gs`Ĩ1:\pł,.\qmƤ5A+~j˩XV(Ƞg1&zk%°d S;ɜ"a- uPʾ^O ˗e([q5̹zKY͓J܏$mVε_FϏ/St iбDPBЋYMdѭ) nJ>҆>G`ɆӨS9DԂރ#i\Aդ85~~>~NW֠;{1cz8 3xSx؛6,Huuپ3O]rژ(-0qro۹JB-ܓl̫$mW*ݵiF'ݎl'ױf h<ޱ$cB ߋQӖ!`d!f=]6{`[K9X`[0Uu5~ERWZO1y* pLS? ,IuʈUNF߅$(jqC:J@ $Ol=}Fd쏩:4zhy8BIw5d^tﬣ=.2sqθ_C/nͭ9X,ʝk[(m)h5}=Ƃ&eW R#0by"g S_7|,u]LNZa(p1WwJFT#l[QF+ qNh@ AKˊV dH%=kE;_B 9P? [e<45|}zƿ:WJy07y_v R/4ts㹲,uD1pϯNY.ߞm'p)n+jJ>ۃ( $g l S % Ed # h " ha 8 } A _ M  c \ b = 2Yx_GV8]S[,4rP}BVM̌0W yJ 'RlG,<tD NQA(!pf>I6~{#<lK{E9`x֥g06uuAE3ҊrбcZ0o=*o-l_?*8iT'Zf$i4$ }c 9  V!! a!N!0!x"^" d"R"#3[#+y#t#$IX$N$$%'^U%p%%.&IsR&&&#C'kO'͎''EX (L((((gm )I))A=)*F* *cR*+C+<"+g+ͬ,@,_7,|,,8>-L}-ɑ--Z;.az.릹.4.}18/vw//V/F50t0/ѳ0x0[21 q1R1+1p/2,n2t2@2,3Mk33U3')4ph4%4k4I&5e5:5#5k#6 c6O6E6 7`7e7g784]8@z889JZ9c99:<_W:::/;^tT;;;8DųK> >V>> ?H?0?xS?@ E@Q#@h@A+BAt8A}ABM@BMBޒB'Bo=Cb|CCIC2:DwyD#DkDG7EvEDҵEE\4FsFgF,Fq1G@pGGAG982xw[6Gu쌴5}3\rW,0qo0yA- lS̫V*,itᨽ&l'Nf;($qc QJ!` $fl]5F{[Kh°XB`Ê0UduĬ=ERņ_ZOƨ9* ǁoLʴ[? ȣIɈ5}TƙF߅W$ɟiC0y9~ @S ˛N,=u}̽cN:͗3zx(p8ιHwJΒ5]t#lϴ-2rqFЎB/nhͭѰW,AkҊ'm)dhӬ<=&ԅe R_#ըb!9gՁ _7[|֣]4L}ZWa؟01Wyv RFTڛ,u[Q۽N+ܖpNߵ'p@ ݹKˊJݒU ۚH#l%޴jEEߎ:Bh OA?dc<4|y=:Iy_7^v8.4ts[C14p}ίY.Vm(0n+yj >R(g +St%d#Nhꖭ"a'8p}_IM쒒#\lbE2YwּgGVﰌA\Sҡc,qP=AΆM̌_V J8&kGZ;4D} P VA e0x>5~ {R K} @ ;azc083* 4sJ44T4M5G5#5'i5o6D696H~67B7"N7k77?8Dc~8883<9fx{999@H9:x:ҷ::b]6;u;;;-;r3<̷r<<^B<0=o=7=W=Ȝ->l>Y'>l>*?3i?|85~׀zɿރ*'ip޸S'Ifߑ#h"$kc8}E!aMg^b@2[xcGX<]U^,8rR恷BZO̎3W |L 'Vl 鞱I/oK}I;`zڥ"k08uwDE5֊tгgZ2q@*o/nb?, J3|SĘ GU#h.Dw8}QBM*s?b~L2<w{&oG9xHҷ\6!uj,q3DrA0foV?-l&lb*i;;' g Q ] $! d!7f!!!"6a"Y{""#2K^#{## $U`[$$$.0%wuX%%%PE&U&ϔ&*&sZ'R''L*'o(ݴO(&(n?( )L)H)T)ٙ *!I*j$*i*+CF+9+~+,f D,N,,?-A-c--a-3>.x}.;..H;/z/]ӹ//]807w00-0s51Yt11B1222{q22 X2U/3n3'3.m3w,4k4=4P4)5 i5*R5r5&6"f6Lg66#7%7c7n|77!8HL`888"9ja]999C1:vZ:Ի::fF;W;Ж;?;[<РT<N>]>U> ?6K?%?j? @YH@:@@2A{ FAOA ATBCBdB.BwC4@CzCPCCI=D)|DrԻDD_:ELyEE.E%t7FnvFFCFG4GsGG!YGV*i /Sw'f#Qh忚$c+8s}!aMM&^ob¸I2[Ñwڼ"jGXijDō\Uաg,ƯqR@ƈAцO̎bǫV L<Ȅ&k I^ɦ;7Fʀ PZCˢ e3{@5 {U̞>J}/w;`zQΙ/8+uwsϼE5MtЕϳ&Z2oqѷ*Ho/ґn"?j,ӳkDTӌ)h$fiԯ&e@9Ո~# cbN֪ <`ׄcͨ^3]ئx7ـHZȍYڢ]W뢖3{-rT U۝BQ/͐wWNQݙ'l *Ks޻< MHߕ Q&nE!fHB6"|j@KD=a|f0:@vy䈻F7bvе;[4愠s+^p1禵p7@.mYU袚+j3%{jį( gU:%. ewO뿔"Qbd*r4_yLI\ݎ&o^YH.sV!jCSDΒXPf(m?M= bJ R;G"h]D77}BMY?2b~{ 2. wL  T P I # *i r F 9 L~  D %N n  A Hc !3>jx}CH;zҹe]8w?-r5зtaB2q;W̜/n]'l,6k<ǁ)Y iQ2&{!ff T#6c{.v!K`P`])r0vZLE%WnЖZGT*!pjQ?CNUe K$?j H : a ! F!:O!!"C"]d""#64@#y#Ǿ##XI=$|$ӻ$2${^:%ãy% %T.%s7&v&-&vC&4's'P'X'1()p(r((m(.)Km)=)݂)%+*n k*R**G(+"h+g+!+i%,7e,|,C,#-Lb--e- .a_.>..1/w\/a//F0:Y0ј00\1\V11+16q2S22A2X3P332V3z4M4 &4Tk4 5J5-;5v56 H6OP667) E7re778K5B8z8ܿ8%9mJ?9~9Խ9G9_<:ؤ{: :i/:t9;x;C;D;ԉ6<ur=)=n=0>`o>>>>:-?m?S??\*@#j@h@6@~'A8gA~AXA%BMdB1BzB"C caCTCC2D-x^DvDDHEO[EҚEE)]FrXFF-FKrGUGG$BG2]xf۸GZ@ع]Waպ,;rTһB]Q̐м7WN፽'ͽYl K3<ʾ{ H TQǿE.!wfBQ6{*@rK»L=Õ`|ݥ&n0:ķuyHĐE7يv!еjųZ4sDƌ*o1peǮ?.?mȈT+ajɪ$i;(ʃg9]%˦ eN7"bdX̡3_2y{ I\UΝ.^YvϿ.PsVЙ*CrSѻ͒LXҔP%(nmӷMH=Ӑ J! iRԲGC"ՌgլDe7֮|?BׇLБa?تa~;؃1襃 L6Sǘ IY#h2Fz8} TDM.vAbP2>w})rG;zLҹ\8%wm,q5GtA!2jqVC/n&le,k;?) iQa& f:f#6c]{!6K`~X`]20zuZú TEWϖ-vZTP*oQnWӖuDR@/ D5օ-f#B#`Dz%`zEjRN+ہce]Jo{lr3  ;ViT|',eK*wzyU̽[!9KzNt,* N=;abهA^/! 30@ 2c  , w * kF )1 "R #s W - ץ V . L %j | ؇ U c 0 vK }ܽhoi:KmD$4"q7D.%@pQL55Qԁ}/i©r d?"dwzmNH &4}xItOo!kcwfGa\ XXT y.,M2oS]M '2KRFrTٰ# pr+ZI6}gY38I73yOk󻋇mD˾"H9>+E`?8z ATkE&^,xE^vXˎ|?Ҿ,37JaqGx0(_"0S"F~'KvADGJvMԉPfS;V Yo[^GaNcޡfRDiktnqsvxz:^}3!xɆXٖtΏ*On}7ív:xR\:ɴ#}@յhhپb=D=-1*F2RK=9FR$Gȓ_!B1*[p9 ]; GM\!5: t;+Q}'7Q1N4/j` U  .( ɭ 0 } -  ;vPMi|T9 B\6aYќ.XU3peДOw=b΅S/#EXjzAƕǰQ&Kļ¸O@^<]xhXE1~_1?bA`I7 PLU$z>Ue!^u:D>pL)nOmx ԃ?4  @  / E   D   ; .  , QW `H/K? K T dZU\ZU3M=A1f "^$&(h()>*,z-׬/v1<346i{85:;=O?@B%ODEoG54IJiLFMO#QհR;TU[IW XLZQ[C]߻^,1`٣acbdGeTgehjd~klf8nop:Ɖd4TMs驑#’Tؓ5)v3;#BF#IIHqEz@91&C. N?שª**x\S>ڱhhU?aX%anJuuԾWLMGv,@cDg]PUHPIaD}R,.:l A t !p8_Qoǟ,DVIdSnYtur%l3?aM\Rp?( Jj_;5~Q%z!IR,7k{S= ZLuoYt$}V.$h0,`{"r_\>pF&ppEpHӏ `+n*1q;P.k!\ DV}b#OZ:}.b+-U^-gM&|A1a]He K3\Dž`J%LsǾ b-tQ#ulS! C d „  {  ~" @ _ | K a W( C ^ y  " h n + 8D )\ s # . b n  V& _; P d x f ʳ c ":4EVwg xe\`t&,<:GTa\nz#87{g ^'0}9GBJRS[ckLszC}t0ä,mw@] Y /g~sH #X%')+p-*/0D23467889&::;Q;;;;l;3;:t:9Q9876543g2 1/.{,*)#'0%)# !=OX  p5 g =JH7Z]%MhvxznuVp3kf`[-VPeKEp@:O5/K4Uvٗ{8ZXwɖ^+/Mj\g>V4Pl- :*D^x2)JBZr3.E'\rۈa8 i s5XJ_s"p}8B&9L_or%>5 U&8OIbZVk)|ތsA{p1Z-<L=[PjEyܖ}m`$1n?LZBgVtQ2D*z e!-8$DOZf=qL|E)T]NusJ"+[5>[HQ[Ldwmvj9<ļ;8ji8%C-4O Hf$)S/4:\?DINT*Y1^,chmqvn{'Ԅx# pʨaй,8:2!@M~ x A2r #' *8-H0P3P6I9:<$?BDGJEMPRhUXZL]_lbdpgiZln)qsu/xzz|~4f։ ̝\+y3B#K׺^_L'LI],U{~\6 yBCbe M=Vcf]J,l5OTD c   $ `    : k     C i      ! : P d x                      u c P < &       g G %     j A     c 3    h 3 Sd&e#W<^z,>INM rW9!#$&(r*A, ./1\3568E:;=T?@BIDEG#IJPLMsOQRTUWXZ[]|^_^ab6degehi$klm/opq$sqtuwJxyz|J}~'Y 0UwҎ0BR`mw~vl`RB1٪gF$ڱ_3ֶr>Ѻ_#g&Y4ISPB(f:k-St4FS\aa^VK;(fF"d7m6_!>SahicVD*v U.uFTXT E.g D{NK| <j!Ny%OxAh$Hm=_  > ] { fenrir-1.5.1/config/sound/default-wav/ErrorScreen.wav000066400000000000000000001357201317357605400226120ustar00rootroot00000000000000RIFFȻWAVEfmt (  8qfact.data3XxDø2HzAҀ T]>}--vr;zOB8)xrW5K'ulܱ%2m֥‡`$c`é0u!:`ăE\]ŤZ6~Z*pXǡW?1zU UTȜ$R-jvɾ:OOʘ )OLq˺ KdI̔$4myF͵GIΏCӂ!i^ϱ@B.ϋsӸ=|eCЭ:>zчXϝ7`(wҩm:4ӂ=t˂\ 2ԥRq헰5~"/gnXՠ7,|k1ªzL) hSקלa&-evؾ1w#Ob٘F( q_ں\Kۓ\+%qmܵY@F܏W Viݱ%TBkދ;Qd߭ >PN `eKᩪ95 zH˿\J㥏EԄ5~_ƤBW/t?1~zD‰ v)q4SsJ#1hp$m8.}mFìM+ jhةb(Bg2x%ddG>"a]`^,9r[B[Y5W~'VWl1h~ZB;*{od8?x=6Tu`$3ir990o[Į N-5l}٫d*Wi31y'yf IS$c-^u!`.Ns](Cq[JX$(Xlm F=U  hRR A" gO Ҭ  d7 |L > L ΑI ׈ _ aF91vC[F5@}[W=+}p1y:@z R8Uw,u%5ktN:2(qpŰ P/Jnڭ$e,lk4Ez)hJh&eB_#b/ct _=D]_Y9)Znʳ[>W5}STŘV# hQ 譐 0 y8!}N! Í!R!M "K",؊"t"b #H#N#2#w$(E$p$G$%JB%%\%#&l?&,&q&F&<'A|''g':(Vy(A((&7)lv)c));4*=s*Ʋ* *Q1+_p+ۯ+ +9f.,m,,6,[{+-j--4K-}(.g..V`.%/d/00/xu/"0 b0RE001,_1tZ112N*\2o2ߴ2(3p?Y333J4TV4ڙ4#4l$5iS55F596~P6ď6g 6N7M7Aٌ77c 8J8c838x9=G99H9:_D::]:9;A;-;s;Z;>0mx>x>> =6?Ru?Ǵ? ?,R3@tr@ܱ@"@Mg0AoAA'7Ap|-BlBBJLB*CiC#CkaC'DfDE1DvDֻ$EdEgFEE!FAaF[FҠFGc+^GpGG\a&e뤸51~v#ƻbWFṠ _1z[޺  \S+pۻ,Yu@ؼOWUս(q%TjҾJ:Q$Ͽm ONF dK h4 yHB‹IEdԄì^=BĆ.t`?Ũ~C9ł<|Y[Ƥ9(y5n~6>vWȟ 41Ssy #1Shpʜ,8.u}m˽¬NM+̗jש(qb(͹gJ2͒w%ۼd$lGε"aFϏ\ס^h,аqB[ъAӆdYҬV=ӆ&Vk`Ԩ;S9Ԃ PP[դ eM5}5 {JWןJ0GyՆ `SDٛ/,uuAڽENڗ>~(Zq۹;*{Joܓ8#?xlݵ6FTuގ $3hir߰A90~oî dN-ᬓlث=c*Ψi_3x'f9Hʍ$c[]!4`}-rW]B0y[W R'Xl,uY/x TVR#,iSt9M~PÏ'NpM،Ic J#3kxGEHDg]A@-rҷ>cB~<<W{͜^'9lxﱷ8<6ɁuǴZ Q3 r 3ܱ |! f0! o!V!6!{-"0l"x"K" *#Qi##`#+'$tf$0$v$M$%d%E%'%o!&a&[&I&'*^'#p'k'(?[(E(()UX)g))$*@jU***:+bR+đ+ +2X}2❼2+2s(;3mz33M3=84ނw4'ȶ4o 4R55t5Iݳ5"5g26#q6k676|/7Dn77L7,8gk88a8@)9h919w9b&:f:F:<:#;c;\;^; <+`<8q<<=A]=Z==>4VZ>|>> &?UkW???/;@xT@œ@ @QPAQAڐA+ AseBNBBM5Bz C޿KC'CoJC DHDHD_D٤E"EEk/EtEFEBFDFՉFGf@GYGG_JGԆ9Ƹ_ʤDꃹ[/ùtA4}Dʼn>W~Y0;y){n R8>xヷ,u6SuN#3hr'p80~oJîM-#llثb*EiŽ2x'hfðGA$ĉc]c!Ŭ`,=rņ]B_Ƨ[8Wǁ'X[lȣ4Y󧃘8SVɘZ#hS뭒3|8}P ÏVMM/،xb JQ2w+GtGMD\'oA,rI>A~"kX}Z';3mz| =8UwǶ /R5xtܳ "Qg2q*7s|/nML,k'oa)hH1vٻ&"fkF#Dc[ՠ f+`p@@]хbUZ;%jW^: T 7œ O!Q!Yڐ!!d"3N"|"4" z #UK##I#. $wH$$_$Q%E%.%+t%s&B&D&L&'@'&Y'o'')=(Hn|(((">:)jy)ȸ) )DS7*v*ݵ*#*fh4+s++?8+}1,p,,bM,.-m-;-b-̧+.j.]2.w.(/7h/G/Ȍ/%0Ye0\003"1{,b1q1 1U2A_2憞2/2w3V\33P3&4kY4*4s4;5V5Lƕ5 5P6&S6nے6 6f7HP7757"{8jM88J8D 9J99`9f:G:/:?u:;D;E;b;<B<;Z<<<*?=]o~===7?<>{>ɺ>>YT9?x?޷?3$?{i6@îu@ @U9@~3ArA/ AwNA0BoBPBcB-C*lCs3CxC*DLjDHDݍD&'EngE]EEH$F-dFrF"Fj!GBaGGCGx)h<H͍&e_]#8b-r Z_B޻4|]W ۼV'Zl/ؽxQA~ܙ+[3| TXU#/iUw 9Q~RÑ*NsO؎Mc 함L&3ox IHHF"k]ﳢCD-rշ@fB񯇿@>W}ќb';lz;<8́wǶ^ Q5t7ܳ!f2qY6{/3n|K ,Uk`.)wh0vQ&fE*s#c[L *`&po@]H"UZj$DjW:fTē ?OQِbdN;4y ̾K]I H7^ȣEY.s3B{CĈ U@X松.w(=m|P=: y *ȸ s R7 v Lݵ " g4 &s n 7 }1 Hp  L !. jm  a D+j1wf(hF?%e\a"+b;qA_]7V\&YkY2;{Vŕ UPSڒ. wePP5zM*rJ JL_ݤ%Gn/tHDDى"jBYC)?n~f><{?ɺS9xa޷#h6 ;u 8 ~3!]r!!M!60"o""c"Y-#l#2#2x#{*$j$ H$T$'%g%.]%w%$&-d&Pr&&!')Ba'r''(LW^(((&')nl[)))G<*X*Ɨ*! *jQ+U+۔+C!+f,ԫR,,e6,{-O-?-K-А .L.a.`. /:I/0/u/0]G0E0061D1Z11X2*A2o222{2?>3 }3Tʼ33T;4.z4v߹4$4j85Pw5595)56rt6 6O6K27q77%d7n/8n838Gy8,9l9!I9i9):i:C^::&;.f;es;;#m]>˲>>\=?Z?Ǚ?6 ?R@ǗW@ݖ@X"@gATA2Az7A|B QBTBLBC-NCvCaC DPKD1DvD) ErIEFEEKFFF[F%FmG+CGpGGGa J@쉸1ɸvGbFƹ@~Y[Ȫ;ɄSX̘^#ʦhUﭔ78}RÑYˢMO3؎{b LU͝2w .IwGQFϙ\*rCл,rLѕ@A&oѷ>V}HҐ&;!lzjӳ;8DwԌƶ Q5ftծ۳ ?f2ֈq6b{/תn;K׃,k]`ئ)h70uȺ&fYEڡ#2c{Zğ U*`ܝo.v?]ݿPޙTZ♙*s$߻iWLߔ9~T&ēn NQHِc!Nj3x CKH fH]?E-saBB;@X]'=7m|=:YyǸ 2R7{vܵ "Ug4띬s.7w|1pPL왑.m*ra+jL1vݻ(%hnFﶋ%He[٠!"j+bpC@_ԅfU\?%jYa:V;ŕ OS]ڒd6P4zYMI2 {J _TG..twDDPB)Yr)?Ln~%>Z*Aao:?>}ɼ\T;z޹6$i8ǮwX9~5t2 zNÓ2 qTc/-nv3x,PlH))ri]K&-fr%m#BcG!W` i'l]C<ZeǙ Q >W ܖ ! g!aT!!6!:|"Q""L"\#N##6a#~ $K$1$Xv$ %I%1F%z%& F&T[&&'-+C'vp''(O@@((ʾ()(rU=)|))K%)j:*ܯy*$*m:*7+v+G +O+ؔ4, s,i,d,1-Bp-4-y-..en.I..>+/k/^//`(0.h0s0:0%1Ce11\1#2Xb252~2( 3n_3X33=41\4zț4 4 S5SY5ݘ5"5-h6vV6686O}7S77(M7q8P88Kb89M9$29mw9 :K:FG::; H;i\;;>V?>ϛ~>>`&>k]7۽TZYؾ#2iW{տ 9T~TÓ.NvQؐPc˜N*3rx ûKLHÔ H%n]ĶEH-Őrٷ!BiBƲC@njWԜe'=Ȯl|?ȇ<:ЁyǸa ɩQ7v;ܵʃ!f4s]˥6{16pK.Ym͡`2+zj0 vT(ϝhE.v%пe[PИ"*b)prѺ@_LҔ%U\mӶ$GjYԐ!:jVղĕ CO֋Sْed׮P?4ׇyоMaIة J:ك^̣G].ڥs6D~CLjXBܡX2z(?m~ Tݜ=<{-Ⱥv ޿R9xPݷߘ"g6)uq7}3KrL%0noaG-l1!wi*jFC'g\e$+d>q懶!Aaa:V^肛&\k[饰6;~Xŗ XP렕Uڔ2 zeêR T5zO-vJ LO_ )Ir/tKFD܉%mDYG)An i>>}CɼS;ze޹#h8>w8~5`tM:2qc\/n26x~,lHX)i1]z& -fTr#-Bcv!OW`)'ql]K<Zƙ$ mQWۖG!fثT i6{QBKӐNe` >K0u `IE:FZ\*Co5~?@XʾT= 1| y߻ $ j: Sy 9 -7 vv O O4 s  (d q1 p 4 Ky .n$Im+kF^( .his%BCe#dXb>( m_ϲ`=\Ǜ9 R˗Yݘ\"gV5}7|SWL1Pza SM1v- uKFOH[(q+EqJ@B$mU?F~% k<h{:B9 x P d6!u!!>e!3"r"5"`z"0#p#9J##-$m$[_$$*%5/j%~t%ƹ%'&WDg&&&1%'yYd'ž' 'S)"(na(䳠(,(u>)^)ɝ)O)S*[*(ޚ*q#*h+X+J+8+},$U,m,M,-FR--b-.hO.2.w.B /M/G//d 0J0\0=01,G1r1`12AD29223WA3[33&35l>4~}44<4W;5z5 50Q5y86w6 !6Sf657t7,67u{728r8NK88/9(o9q`99,:J0l:u:ۺ:#*;lEi;;;F'ӄ`>ʟ>d>T?]?=ߜ?$?i@Z@_@9@~A9WA ANAB[TBBcB4C}QC3CyCWDODHD0Dy ELE ^ERE F-IF,sFuFGCFGNGGxGMH̸ iJ]ɹCG-sƺdDB>ûBX`'?:m~=<\{Ǻ 6R9~xܷ"Xg6u17z|3r TL0o-ua¾-lO1Øv*)jqFĺ'Kgœ[ܠ%$m+dƶpG!Ǐ@aׅ iȱU^Cȋ%j[dɭ:X>ŗʇ OU`ڔ˩d:R̂4z\OͤI6 ~L_X ϠI.1tzF DTМD-YuѾ)AOnҘ)>>q}ӺȼKS;ԓzݹ$#mh8յwG8Տ}5t hMֱ2qB׋bӧ/ne2حw,>lنGό)`iک\:&ۂ,fq[#ܤAc톢5~!V`Xݠ&k]1y; ZSƙߜ P-Wuۖ fOT5({qQKKN$`l K/Fu䏺 H EhFBZ抟*Cdo筴>?@膄ɾ_T=騙|޻9$i:ˮy\9~7v5 }NƓ4sWc11py3x .SnH,+uk]O(-hr(q%BeJ#Wb$l' l_F< \hǛ QBYܘ!gdV6>|SL`P9aM1[v K5F}HW[1+Eypµ S@B,uU?~O%j<{(p:9xJ O۔6$uld3Fr4y0hpIB-m^d*.js='Cg`%Xd9("na[= 5^ }ȝ S W[ ݚ " 0h yX 8 S} U  ,M t R  Nb O(2qw MJG #Jl\F,Gq׶hADAVAқd&k>}=;΀;z_ P89w e5[t5z42}rJW/o_0x,/l uR)Di,u'ZfN)$(ocp?!J`ɟ#Tl]ޜ#Ei Z 9 h~!W!!AN!"T""cc"#Q#=3#x#ν$O$_H$$ %9L%]%ʢ% &[-I&r&&4'}BF'Ň''V(WC(蜂(0(y')l@) )R)<)=*,|*t *Q*:+Ny+!+f+'7,pv,6,|,J4-t-K-#-l1.q.`.E../0n/v/g/,0Ek0A00)1[h1c11*&2=pe222@#3_b3ʡ338U 4_4ߞ4%4[j5\554:5}6Y6 6VO67V707xd78 S8R48y89+Q9tI99:NN:^:ߣ:' ;p.K;s;;ImB>>g>=???A~? ?R?<@c{@"@g@<9AxA7A}A_6BvBLB8B3CsCbCZC0D1pD4wD}D.E GmEVEE+F/\jFxFF ,(GRqgGGGJ/n1$wl,lFF깏)i \h纱&+fBq#Acd!>V`޽&_k]۾9;Zř ٿ[PWږ5 }eƪTW5zQ1yJ NSÛ_ ,Ku/ľt NHŗD߉(pFƹYJǓ)Cn$lȵ>@FɾȎS= |h޻ɱ#h:Byʊ8~7dvˬM=4̆sc_1ͨp29x́.nH[Τ+k5]}(-hWrП%1Bey #RWbқ,' ul_ӽN<ԗ\ƛ( pQչYܘJ!Ւf۫V$l6ֵ{SF׎K֐Phذ`BMي0u cKڬE=ۆHZ_ܨ*Eo9܁?B[ݤT?5~}߽$jk}:E;z Pg8wAe5t5cz2r=J/o__,8/ltʹ)[Di4'|YfŞV)$nc糢0x>!` ɟRS],ޜt#hZN8}'WpMITb#kQ2wEOGg L\A ,IrcAF=WC_& 8l@  < [= | 4Q |: y ! Vf 7 v 06 x{ 4 t RK 1+qt`.N0nuߺ',oEkI)Zhڟ#l*&oeE?#քbʡgT _Aߞ$i\c9~4A4Ȁ44^S4>5}58#5h5ɭ;6z6Z86}6873x7|M7Ē7 58Vu8b88/29w2r9w99Q0:Go:⌮:+:s-;\l;;M;,*"c>k>&>k!?D`??;?@g]@ @P@@AZA AfAbBWB5B<{BCUCKC^CDRD7`DDE0OEZuEE F3ELF{FF  GUZIGGGNP(`ϸpM0Iu̹ J#ElɺHEZƻ*EgoüA?BcT?~޽<$i<ή{_9~9x9 Nɓ6uZc34r}3x0VpßH0-xm] R*ś-jr,t'ƼBgMƖ%Wd'pǹ'"maIȒ<#^kǝɴ QE[ʎܚ!ggX˰6A|̉ULcͬR=aͅO1_vΧ M8Fρ JZ[У4+G|pŵV@Dҟ0xUA R%Ӛj>},t:Խ;zM ՖOޔ8'wpָd5Itג4y#2krشIE/ٍo^g,ڰ.lsAډ)Cic۫'Xf=܅($nc^ݧ=!8`ށȟ SZ]ߣݜ"4h|Z 8V}W0MxT Qb⚧Q+2tw㼼ONG䖌 'Lo\帡 I,Iqڶ#kAF紆DVC֛g&k@A;р=|b P:f}"g@;z7}b8xL<5ub]21r7w0GoZ-3\l{ ,*Uqi/A'wf˥QV$c*&sk!`M; ] & nP !Z!H !e!٪""W"j5"z"#DU#J#Տ#$fR$_$$@%/O%t%%a &DL&&;& 'YI''^')(nF(7((>)C)Yɂ))S*3@*{*#* i*U=+|+8+.~+w:,z,N,Q,7-w-*c-r-4.3t.Lx..2/&Hq/n///0H]n000"-,1jrk111DB)2h2̧22fW&3e33?'3l#4ѱb44b<4 5_5; 5Q5̖6\6]!6f677Y767{78YW8K8839{T9`9 9U:0Q:u:.:w;EN;;P; &E>nʄ>>T?HB?߁?$?!j@j?@~@9@D@#ăb ɡUӞS _/ޞw#h \Q՚8}+YsֻMMVוb&oSظ2xHّQG"jڳN\Dڍ ,KrfۯAH@܈WEbݫ&;lBބ<^?ߦ~ 7Q߀<{!Yfࢫ9x36{{6 vUK➐3/sw`0Q0pu+.sEm弊L+Zjݟ&o*(ogH?%لd"ʣjT"aDߠ$i^f9~?[ NbXc<U3y]SH7P^Y -M3s{ CJU/XGw(PmD󙲃*=sAǀ LR>}&"ng;zH7|8"xjL5Cuaզ2f1rv@0FoЋa-[l;+*pi]@'f7˥U$cY%j!3`{: T] O.wZePW4*zrUJLR&_n.OHt !DLj DYI)enF?> C Ȃ  aS @  ;# h ̭= | ]8 } : 7z M ǒ 7 Yw b 34{2tw T2Gq匰.w/\nP,,qk*rA)hĻV&&en&k#Hb;! j_ PD\ feY5?{WKaT;`0Q]u7EN XZK2* {oHô U?EɄ.vTB߁P$i ? *~ r9 ~ 6a ~6O66:;7{7d77]884x8y868~69Iu99X93:^r:2:z:.0; to;T;;C-<.lrf>>>>K$?c? ?%S?m!@`@"@Gh@A]A!8Ai}AB[BCMBBCXCebCCD?2UDwDмDE`GREEE:F\OFˡFF\, GqLGG6GS.2wwҸQQGϹ*Ns\̺ L,Kqݶɻ&oAHƼHVEٛ!ýj&kBD;Հ?~f PT}՝!f.;wzֿ6|P8יxK*r5ػuaLؕ20r&vnٶ0EoHڐ-![lj۲**Cpi܌@'efݮʥ?U$ވcߢ%aj!ߩ`;:߃] ]OঔZ6dǩWY4y2U{IÎ TR^.v.OsP CLላ*r XIL(mF&n=CGȂ R!@j"gC=|7}e:zL?7wba41t:w2Gq]/7\n,,Xqk񡶪2A){h˧ TV&e.&vk#bP; _* rP\K eܪ%Yn5zGWJ؏!iT_C/QteDN> YKa) nH;>E\ɄS6Bށ#iX?~82~z<| NT9y.cv63vOx4)Hsr1K]p%-.mrmGB+j̩!iW(gC'l% Աd  e< " a > Q ϖ ^ `! f  :[ 6 {  \Y K 6~V`X0Su2zEP TZM-v* pJO?)GqʆUKD߃$%jmA9G> ~!Oi;{Bd84xey6>Iu3`^r:.0so˸\C-lͫ6~X*ƝiX(m'f2z=Â$ cS R! -` v" g !O]!7!|!)"q["L""K#X#a#%#m$1U$v$F$%FR% %i%&[O&C&&+ 'qL'd''@ (>I(ˈ((V)`F))%):k*C**;*\+@+ +6P+~+=, },We,,:-15z-zz-¿- 8.SJw...-5/u_t///O/20tq0๰0)0qD/1n1ϭ1J1Y,2ܞk2$2m)2n)3h3G3>3׃&4 e4h4S4#5Bb5#5h5 6d_686}6>7]7M77`8Z8b8:892W9x9[9:GT:5:~:;]Q;W;;,<1rNuH>>'>Ol?E??(EE1FΊpFЯF`FZ.GmG9G*G52u{`å 2T0ru.0vEoP-Zl៫)r**oiL缔?'݄f%ʥn彶T$cGߢ$i!!`j9߿~C] NeZc?‡W3yaéUH:ÃR^]ĥ-O6s CLXơ 2XI{ (TmFȜ-=vCɿǂ PRʘ@)"rgʺ=|K7˔|:%znL̶7Gw͐aئ 4i1tβvC2όFqԋe/Э[n>Ї+,pkaѩ@)h:˧҃U&e\ӥ%j#6b: X_ՠ O1z\ eTםY4-zvؾWJOؘT)_rٺ/QKtڔ%DNm۶ GYKܐ ) inHݱB>ދEȄeS߭B݁>#߇hϭ?~`8}<:|M˒9\yb66~2vwX4Gs録1z1\p S,.qm-vA+jO̩V()gq&l%Kd;$"ma PG^ !fi[5B{YKeV>`0S`u喙:EP\ZM񥟌5* ~oJƴX?GɆ1zT™D ߃S$iA-v9~>O ~N(;q{cK83xx%m6HuF3]r i-0roBB-ldͫW*>i'm'`f<9$c R\!`!5g~]7W|[1Lz XSa,1UuvOFR)q[OJ+ pLܵ$m@ IʈFU ךF h% j C B :  @ d O == } d  `: 4z y 9 8Iw[5^t5~.2tqWC/1nyέ Y,Sk(-n)uh>O&e (Sq#b#Jh _$8l}]FM ZhbB2WwӼdGT=\QΡ`,qN9A ʆK̊[V H5}&kEW; 1B y P !S?! !e!-!u<"5|"{"N":#Jy#(#q#7$`v$J$$/4%$us%l%%D1&Fp&ϯ&& Z.'hm'')'Ao+(j((?(d()g))>T)%*d*$*_i*"+a+99+~+, _,[N,,-5\-}c-ƨ-.W3Y.x..1/yHV// /R0]S0㢒0,0u-1rP11N1B2߇M2(͌2p2W 3J3J3'3l4$G4l4<45ED5 5Q56hA6!6f6B6>76~7|7c7<8K{8=8899ax9_9906:9vu:::F3;[r;б;;5[0<}o<<+i> >RU>'?f?,%?tj?$@c@N:@@!A( aApOAABJ^BdB۩B#Cl4[CyCCFDIXD֎DDgE^UEEAE.FsRFFcFCGOG=ΎGG6W~IǎոXT^ҹ1z.Qs ϺSCN刍-̻v XKOɼ( mH)qƽ=EKȄ ľR$Bm݁"gG?~7 }i<|LB9ybd­61v>wÇ4Gs`Ĩ1:\pł,.\qmƤ5A+~j˩XV(Ƞg1&zk%°d S;ɜ"a- uPʾ^O ˗e([q5̹zKY͓J܏$mVε_FϏ/St iбDPBЋYMdѭ) nJ>҆>G`ɆӨS9DԂރ#i\Aդ85~~>~NW֠;{1cz8 3xSx؛6,Huuپ3O]rژ(-0qro۹JB-ܓl̫$mW*ݵiF'ݎl'ױf h<ޱ$cB ߋQӖ!`d!f=]6{`[K9X`[0Uu5~ERWZO1y* pLS? ,IuʈUNF߅$(jqC:J@ $Ol=}Fd쏩:4zhy8BIw5d^tﬣ=.2sqθ_C/nͭ9X,ʝk[(m)h5}=Ƃ&eW R#0by"g S_7|,u]LNZa(p1WwJFT#l[QF+ qNh@ AKˊV dH%=kE;_B 9P? [e<45|}zƿ:WJy07y_v R/4ts㹲,uD1pϯNY.ߞm'p)n+jJ>ۃ( $g l S % Ed # h " ha 8 } A _ M  c \ b = 2Yx_GV8]S[,4rP}BVM̌0W yJ 'RlG,<tD NQA(!pf>I6~{#<lK{E9`x֥g06uuAE3ҊrбcZ0o=*o-l_?*8iT'Zf$i4$ }c 9  V!! a!N!0!x"^" d"R"#3[#+y#t#$IX$N$$%'^U%p%%.&IsR&&&#C'kO'͎''EX (L((((gm )I))A=)*F* *cR*+C+<"+g+ͬ,@,_7,|,,8>-L}-ɑ--Z;.az.릹.4.}18/vw//V/F50t0/ѳ0x0[21 q1R1+1p/2,n2t2@2,3Mk33U3')4ph4%4k4I&5e5:5#5k#6 c6O6E6 7`7e7g784]8@z889JZ9c99:<_W:::/;^tT;;;8DųK> >V>> ?H?0?xS?@ E@Q#@h@A+BAt8A}ABM@BMBޒB'Bo=Cb|CCIC2:DwyD#DkDG7EvEDҵEE\4FsFgF,Fq1G@pGGAG982xw[6Gu쌴5}3\rW,0qo0yA- lS̫V*,itᨽ&l'Nf;($qc QJ!` $fl]5F{[Kh°XB`Ê0UduĬ=ERņ_ZOƨ9* ǁoLʴ[? ȣIɈ5}TƙF߅W$ɟiC0y9~ @S ˛N,=u}̽cN:͗3zx(p8ιHwJΒ5]t#lϴ-2rqFЎB/nhͭѰW,AkҊ'm)dhӬ<=&ԅe R_#ըb!9gՁ _7[|֣]4L}ZWa؟01Wyv RFTڛ,u[Q۽N+ܖpNߵ'p@ ݹKˊJݒU ۚH#l%޴jEEߎ:Bh OA?dc<4|y=:Iy_7^v8.4ts[C14p}ίY.Vm(0n+yj >R(g +St%d#Nhꖭ"a'8p}_IM쒒#\lbE2YwּgGVﰌA\Sҡc,qP=AΆM̌_V J8&kGZ;4D} P VA e0x>5~ {R K} @ ;azc083* 4sJ44T4M5G5#5'i5o6D696H~67B7"N7k77?8Dc~8883<9fx{999@H9:x:ҷ::b]6;u;;;-;r3<̷r<<^B<0=o=7=W=Ȝ->l>Y'>l>*?3i?|85~׀zɿރ*'ip޸S'Ifߑ#h"$kc8}E!aMg^b@2[xcGX<]U^,8rR恷BZO̎3W |L 'Vl 鞱I/oK}I;`zڥ"k08uwDE5֊tгgZ2q@*o/nb?, J3|SĘ GU#h.Dw8}QBM*s?b~L2<w{&oG9xHҷ\6!uj,q3DrA0foV?-l&lb*i;;' g Q ] $! d!7f!!!"6a"Y{""#2K^#{## $U`[$$$.0%wuX%%%PE&U&ϔ&*&sZ'R''L*'o(ݴO(&(n?( )L)H)T)ٙ *!I*j$*i*+CF+9+~+,f D,N,,?-A-c--a-3>.x}.;..H;/z/]ӹ//]807w00-0s51Yt11B1222{q22 X2U/3n3'3.m3w,4k4=4P4)5 i5*R5r5&6"f6Lg66#7%7c7n|77!8HL`888"9ja]999C1:vZ:Ի::fF;W;Ж;?;[<РT<N>]>U> ?6K?%?j? @YH@:@@2A{ FAOA ATBCBdB.BwC4@CzCPCCI=D)|DrԻDD_:ELyEE.E%t7FnvFFCFG4GsGG!YGV*i /Sw'f#Qh忚$c+8s}!aMM&^ob¸I2[Ñwڼ"jGXijDō\Uաg,ƯqR@ƈAцO̎bǫV L<Ȅ&k I^ɦ;7Fʀ PZCˢ e3{@5 {U̞>J}/w;`zQΙ/8+uwsϼE5MtЕϳ&Z2oqѷ*Ho/ґn"?j,ӳkDTӌ)h$fiԯ&e@9Ո~# cbN֪ <`ׄcͨ^3]ئx7ـHZȍYڢ]W뢖3{-rT U۝BQ/͐wWNQݙ'l *Ks޻< MHߕ Q&nE!fHB6"|j@KD=a|f0:@vy䈻F7bvе;[4愠s+^p1禵p7@.mYU袚+j3%{jį( gU:%. ewO뿔"Qbd*r4_yLI\ݎ&o^YH.sV!jCSDΒXPf(m?M= bJ R;G"h]D77}BMY?2b~{ 2. wL  T P I # *i r F 9 L~  D %N n  A Hc !3>jx}CH;zҹe]8w?-r5зtaB2q;W̜/n]'l,6k<ǁ)Y iQ2&{!ff T#6c{.v!K`P`])r0vZLE%WnЖZGT*!pjQ?CNUe K$?j H : a ! F!:O!!"C"]d""#64@#y#Ǿ##XI=$|$ӻ$2${^:%ãy% %T.%s7&v&-&vC&4's'P'X'1()p(r((m(.)Km)=)݂)%+*n k*R**G(+"h+g+!+i%,7e,|,C,#-Lb--e- .a_.>..1/w\/a//F0:Y0ј00\1\V11+16q2S22A2X3P332V3z4M4 &4Tk4 5J5-;5v56 H6OP667) E7re778K5B8z8ܿ8%9mJ?9~9Խ9G9_<:ؤ{: :i/:t9;x;C;D;ԉ6<ur=)=n=0>`o>>>>:-?m?S??\*@#j@h@6@~'A8gA~AXA%BMdB1BzB"C caCTCC2D-x^DvDDHEO[EҚEE)]FrXFF-FKrGUGG$BG2]xf۸GZ@ع]Waպ,;rTһB]Q̐м7WN፽'ͽYl K3<ʾ{ H TQǿE.!wfBQ6{*@rK»L=Õ`|ݥ&n0:ķuyHĐE7يv!еjųZ4sDƌ*o1peǮ?.?mȈT+ajɪ$i;(ʃg9]%˦ eN7"bdX̡3_2y{ I\UΝ.^YvϿ.PsVЙ*CrSѻ͒LXҔP%(nmӷMH=Ӑ J! iRԲGC"ՌgլDe7֮|?BׇLБa?تa~;؃1襃 L6Sǘ IY#h2Fz8} TDM.vAbP2>w})rG;zLҹ\8%wm,q5GtA!2jqVC/n&le,k;?) iQa& f:f#6c]{!6K`~X`]20zuZú TEWϖ-vZTP*oQnWӖuDR@/ D5օ-f#B#`Dz%`zEjRN+ہce]Jo{lr3  ;ViT|',eK*wzyU̽[!9KzNt,* N=;abهA^/! 30@ 2c  , w * kF )1 "R #s W - ץ V . L %j | ؇ U c 0 vK }ܽhoi:KmD$4"q7D.%@pQL55Qԁ}/i©r d?"dwzmNH &4}xItOo!kcwfGa\ XXT y.,M2oS]M '2KRFrTٰ# pr+ZI6}gY38I73yOk󻋇mD˾"H9>+E`?8z ATkE&^,xE^vXˎ|?Ҿ,37JaqGx0(_"0S"F~'KvADGJvMԉPfS;V Yo[^GaNcޡfRDiktnqsvxz:^}3!xɆXٖtΏ*On}7ív:xR\:ɴ#}@յhhپb=D=-1*F2RK=9FR$Gȓ_!B1*[p9 ]; GM\!5: t;+Q}'7Q1N4/j` U  .( ɭ 0 } -  ;vPMi|T9 B\6aYќ.XU3peДOw=b΅S/#EXjzAƕǰQ&Kļ¸O@^<]xhXE1~_1?bA`I7 PLU$z>Ue!^u:D>pL)nOmx ԃ?4  @  / E   D   ; .  , QW `H/K? K T dZU\ZU3M=A1f "^$&(h()>*,z-׬/v1<346i{85:;=O?@B%ODEoG54IJiLFMO#QհR;TU[IW XLZQ[C]߻^,1`٣acbdGeTgehjd~klf8nop:Ɖd4TMs驑#’Tؓ5)v3;#BF#IIHqEz@91&C. N?שª**x\S>ڱhhU?aX%anJuuԾWLMGv,@cDg]PUHPIaD}R,.:l A t !p8_Qoǟ,DVIdSnYtur%l3?aM\Rp?( Jj_;5~Q%z!IR,7k{S= ZLuoYt$}V.$h0,`{"r_\>pF&ppEpHӏ `+n*1q;P.k!\ DV}b#OZ:}.b+-U^-gM&|A1a]He K3\Dž`J%LsǾ b-tQ#ulS! C d „  {  ~" @ _ | K a W( C ^ y  " h n + 8D )\ s # . b n  V& _; P d x f ʳ c ":4EVwg xe\`t&,<:GTa\nz#87{g ^'0}9GBJRS[ckLszC}t0ä,mw@] Y /g~sH #X%')+p-*/0D23467889&::;Q;;;;l;3;:t:9Q9876543g2 1/.{,*)#'0%)# !=OX  p5 g =JH7Z]%MhvxznuVp3kf`[-VPeKEp@:O5/K4Uvٗ{8ZXwɖ^+/Mj\g>V4Pl- :*D^x2)JBZr3.E'\rۈa8 i s5XJ_s"p}8B&9L_or%>5 U&8OIbZVk)|ތsA{p1Z-<L=[PjEyܖ}m`$1n?LZBgVtQ2D*z e!-8$DOZf=qL|E)T]NusJ"+[5>[HQ[Ldwmvj9<ļ;8ji8%C-4O Hf$)S/4:\?DINT*Y1^,chmqvn{'Ԅx# pʨaй,8:2!@M~ x A2r #' *8-H0P3P6I9:<$?BDGJEMPRhUXZL]_lbdpgiZln)qsu/xzz|~4f։ ̝\+y3B#K׺^_L'LI],U{~\6 yBCbe M=Vcf]J,l5OTD c   $ `    : k     C i      ! : P d x                      u c P < &       g G %     j A     c 3    h 3 Sd&e#W<^z,>INM rW9!#$&(r*A, ./1\3568E:;=T?@BIDEG#IJPLMsOQRTUWXZ[]|^_^ab6degehi$klm/opq$sqtuwJxyz|J}~'Y 0UwҎ0BR`mw~vl`RB1٪gF$ڱ_3ֶr>Ѻ_#g&Y4ISPB(f:k-St4FS\aa^VK;(fF"d7m6_!>SahicVD*v U.uFTXT E.g D{NK| <j!Ny%OxAh$Hm=_  > ] { fenrir-1.5.1/config/sound/default-wav/ErrorSpeech.wav000066400000000000000000001357201317357605400226020ustar00rootroot00000000000000RIFFȻWAVEfmt (  8qfact.data3XxDø2HzAҀ T]>}--vr;zOB8)xrW5K'ulܱ%2m֥‡`$c`é0u!:`ăE\]ŤZ6~Z*pXǡW?1zU UTȜ$R-jvɾ:OOʘ )OLq˺ KdI̔$4myF͵GIΏCӂ!i^ϱ@B.ϋsӸ=|eCЭ:>zчXϝ7`(wҩm:4ӂ=t˂\ 2ԥRq헰5~"/gnXՠ7,|k1ªzL) hSקלa&-evؾ1w#Ob٘F( q_ں\Kۓ\+%qmܵY@F܏W Viݱ%TBkދ;Qd߭ >PN `eKᩪ95 zH˿\J㥏EԄ5~_ƤBW/t?1~zD‰ v)q4SsJ#1hp$m8.}mFìM+ jhةb(Bg2x%ddG>"a]`^,9r[B[Y5W~'VWl1h~ZB;*{od8?x=6Tu`$3ir990o[Į N-5l}٫d*Wi31y'yf IS$c-^u!`.Ns](Cq[JX$(Xlm F=U  hRR A" gO Ҭ  d7 |L > L ΑI ׈ _ aF91vC[F5@}[W=+}p1y:@z R8Uw,u%5ktN:2(qpŰ P/Jnڭ$e,lk4Ez)hJh&eB_#b/ct _=D]_Y9)Znʳ[>W5}STŘV# hQ 譐 0 y8!}N! Í!R!M "K",؊"t"b #H#N#2#w$(E$p$G$%JB%%\%#&l?&,&q&F&<'A|''g':(Vy(A((&7)lv)c));4*=s*Ʋ* *Q1+_p+ۯ+ +9f.,m,,6,[{+-j--4K-}(.g..V`.%/d/00/xu/"0 b0RE001,_1tZ112N*\2o2ߴ2(3p?Y333J4TV4ڙ4#4l$5iS55F596~P6ď6g 6N7M7Aٌ77c 8J8c838x9=G99H9:_D::]:9;A;-;s;Z;>0mx>x>> =6?Ru?Ǵ? ?,R3@tr@ܱ@"@Mg0AoAA'7Ap|-BlBBJLB*CiC#CkaC'DfDE1DvDֻ$EdEgFEE!FAaF[FҠFGc+^GpGG\a&e뤸51~v#ƻbWFṠ _1z[޺  \S+pۻ,Yu@ؼOWUս(q%TjҾJ:Q$Ͽm ONF dK h4 yHB‹IEdԄì^=BĆ.t`?Ũ~C9ł<|Y[Ƥ9(y5n~6>vWȟ 41Ssy #1Shpʜ,8.u}m˽¬NM+̗jש(qb(͹gJ2͒w%ۼd$lGε"aFϏ\ס^h,аqB[ъAӆdYҬV=ӆ&Vk`Ԩ;S9Ԃ PP[դ eM5}5 {JWןJ0GyՆ `SDٛ/,uuAڽENڗ>~(Zq۹;*{Joܓ8#?xlݵ6FTuގ $3hir߰A90~oî dN-ᬓlث=c*Ψi_3x'f9Hʍ$c[]!4`}-rW]B0y[W R'Xl,uY/x TVR#,iSt9M~PÏ'NpM،Ic J#3kxGEHDg]A@-rҷ>cB~<<W{͜^'9lxﱷ8<6ɁuǴZ Q3 r 3ܱ |! f0! o!V!6!{-"0l"x"K" *#Qi##`#+'$tf$0$v$M$%d%E%'%o!&a&[&I&'*^'#p'k'(?[(E(()UX)g))$*@jU***:+bR+đ+ +2X}2❼2+2s(;3mz33M3=84ނw4'ȶ4o 4R55t5Iݳ5"5g26#q6k676|/7Dn77L7,8gk88a8@)9h919w9b&:f:F:<:#;c;\;^; <+`<8q<<=A]=Z==>4VZ>|>> &?UkW???/;@xT@œ@ @QPAQAڐA+ AseBNBBM5Bz C޿KC'CoJC DHDHD_D٤E"EEk/EtEFEBFDFՉFGf@GYGG_JGԆ9Ƹ_ʤDꃹ[/ùtA4}Dʼn>W~Y0;y){n R8>xヷ,u6SuN#3hr'p80~oJîM-#llثb*EiŽ2x'hfðGA$ĉc]c!Ŭ`,=rņ]B_Ƨ[8Wǁ'X[lȣ4Y󧃘8SVɘZ#hS뭒3|8}P ÏVMM/،xb JQ2w+GtGMD\'oA,rI>A~"kX}Z';3mz| =8UwǶ /R5xtܳ "Qg2q*7s|/nML,k'oa)hH1vٻ&"fkF#Dc[ՠ f+`p@@]хbUZ;%jW^: T 7œ O!Q!Yڐ!!d"3N"|"4" z #UK##I#. $wH$$_$Q%E%.%+t%s&B&D&L&'@'&Y'o'')=(Hn|(((">:)jy)ȸ) )DS7*v*ݵ*#*fh4+s++?8+}1,p,,bM,.-m-;-b-̧+.j.]2.w.(/7h/G/Ȍ/%0Ye0\003"1{,b1q1 1U2A_2憞2/2w3V\33P3&4kY4*4s4;5V5Lƕ5 5P6&S6nے6 6f7HP7757"{8jM88J8D 9J99`9f:G:/:?u:;D;E;b;<B<;Z<<<*?=]o~===7?<>{>ɺ>>YT9?x?޷?3$?{i6@îu@ @U9@~3ArA/ AwNA0BoBPBcB-C*lCs3CxC*DLjDHDݍD&'EngE]EEH$F-dFrF"Fj!GBaGGCGx)h<H͍&e_]#8b-r Z_B޻4|]W ۼV'Zl/ؽxQA~ܙ+[3| TXU#/iUw 9Q~RÑ*NsO؎Mc 함L&3ox IHHF"k]ﳢCD-rշ@fB񯇿@>W}ќb';lz;<8́wǶ^ Q5t7ܳ!f2qY6{/3n|K ,Uk`.)wh0vQ&fE*s#c[L *`&po@]H"UZj$DjW:fTē ?OQِbdN;4y ̾K]I H7^ȣEY.s3B{CĈ U@X松.w(=m|P=: y *ȸ s R7 v Lݵ " g4 &s n 7 }1 Hp  L !. jm  a D+j1wf(hF?%e\a"+b;qA_]7V\&YkY2;{Vŕ UPSڒ. wePP5zM*rJ JL_ݤ%Gn/tHDDى"jBYC)?n~f><{?ɺS9xa޷#h6 ;u 8 ~3!]r!!M!60"o""c"Y-#l#2#2x#{*$j$ H$T$'%g%.]%w%$&-d&Pr&&!')Ba'r''(LW^(((&')nl[)))G<*X*Ɨ*! *jQ+U+۔+C!+f,ԫR,,e6,{-O-?-K-А .L.a.`. /:I/0/u/0]G0E0061D1Z11X2*A2o222{2?>3 }3Tʼ33T;4.z4v߹4$4j85Pw5595)56rt6 6O6K27q77%d7n/8n838Gy8,9l9!I9i9):i:C^::&;.f;es;;#m]>˲>>\=?Z?Ǚ?6 ?R@ǗW@ݖ@X"@gATA2Az7A|B QBTBLBC-NCvCaC DPKD1DvD) ErIEFEEKFFF[F%FmG+CGpGGGa J@쉸1ɸvGbFƹ@~Y[Ȫ;ɄSX̘^#ʦhUﭔ78}RÑYˢMO3؎{b LU͝2w .IwGQFϙ\*rCл,rLѕ@A&oѷ>V}HҐ&;!lzjӳ;8DwԌƶ Q5ftծ۳ ?f2ֈq6b{/תn;K׃,k]`ئ)h70uȺ&fYEڡ#2c{Zğ U*`ܝo.v?]ݿPޙTZ♙*s$߻iWLߔ9~T&ēn NQHِc!Nj3x CKH fH]?E-saBB;@X]'=7m|=:YyǸ 2R7{vܵ "Ug4띬s.7w|1pPL왑.m*ra+jL1vݻ(%hnFﶋ%He[٠!"j+bpC@_ԅfU\?%jYa:V;ŕ OS]ڒd6P4zYMI2 {J _TG..twDDPB)Yr)?Ln~%>Z*Aao:?>}ɼ\T;z޹6$i8ǮwX9~5t2 zNÓ2 qTc/-nv3x,PlH))ri]K&-fr%m#BcG!W` i'l]C<ZeǙ Q >W ܖ ! g!aT!!6!:|"Q""L"\#N##6a#~ $K$1$Xv$ %I%1F%z%& F&T[&&'-+C'vp''(O@@((ʾ()(rU=)|))K%)j:*ܯy*$*m:*7+v+G +O+ؔ4, s,i,d,1-Bp-4-y-..en.I..>+/k/^//`(0.h0s0:0%1Ce11\1#2Xb252~2( 3n_3X33=41\4zț4 4 S5SY5ݘ5"5-h6vV6686O}7S77(M7q8P88Kb89M9$29mw9 :K:FG::; H;i\;;>V?>ϛ~>>`&>k]7۽TZYؾ#2iW{տ 9T~TÓ.NvQؐPc˜N*3rx ûKLHÔ H%n]ĶEH-Őrٷ!BiBƲC@njWԜe'=Ȯl|?ȇ<:ЁyǸa ɩQ7v;ܵʃ!f4s]˥6{16pK.Ym͡`2+zj0 vT(ϝhE.v%пe[PИ"*b)prѺ@_LҔ%U\mӶ$GjYԐ!:jVղĕ CO֋Sْed׮P?4ׇyоMaIة J:ك^̣G].ڥs6D~CLjXBܡX2z(?m~ Tݜ=<{-Ⱥv ޿R9xPݷߘ"g6)uq7}3KrL%0noaG-l1!wi*jFC'g\e$+d>q懶!Aaa:V^肛&\k[饰6;~Xŗ XP렕Uڔ2 zeêR T5zO-vJ LO_ )Ir/tKFD܉%mDYG)An i>>}CɼS;ze޹#h8>w8~5`tM:2qc\/n26x~,lHX)i1]z& -fTr#-Bcv!OW`)'ql]K<Zƙ$ mQWۖG!fثT i6{QBKӐNe` >K0u `IE:FZ\*Co5~?@XʾT= 1| y߻ $ j: Sy 9 -7 vv O O4 s  (d q1 p 4 Ky .n$Im+kF^( .his%BCe#dXb>( m_ϲ`=\Ǜ9 R˗Yݘ\"gV5}7|SWL1Pza SM1v- uKFOH[(q+EqJ@B$mU?F~% k<h{:B9 x P d6!u!!>e!3"r"5"`z"0#p#9J##-$m$[_$$*%5/j%~t%ƹ%'&WDg&&&1%'yYd'ž' 'S)"(na(䳠(,(u>)^)ɝ)O)S*[*(ޚ*q#*h+X+J+8+},$U,m,M,-FR--b-.hO.2.w.B /M/G//d 0J0\0=01,G1r1`12AD29223WA3[33&35l>4~}44<4W;5z5 50Q5y86w6 !6Sf657t7,67u{728r8NK88/9(o9q`99,:J0l:u:ۺ:#*;lEi;;;F'ӄ`>ʟ>d>T?]?=ߜ?$?i@Z@_@9@~A9WA ANAB[TBBcB4C}QC3CyCWDODHD0Dy ELE ^ERE F-IF,sFuFGCFGNGGxGMH̸ iJ]ɹCG-sƺdDB>ûBX`'?:m~=<\{Ǻ 6R9~xܷ"Xg6u17z|3r TL0o-ua¾-lO1Øv*)jqFĺ'Kgœ[ܠ%$m+dƶpG!Ǐ@aׅ iȱU^Cȋ%j[dɭ:X>ŗʇ OU`ڔ˩d:R̂4z\OͤI6 ~L_X ϠI.1tzF DTМD-YuѾ)AOnҘ)>>q}ӺȼKS;ԓzݹ$#mh8յwG8Տ}5t hMֱ2qB׋bӧ/ne2حw,>lنGό)`iک\:&ۂ,fq[#ܤAc톢5~!V`Xݠ&k]1y; ZSƙߜ P-Wuۖ fOT5({qQKKN$`l K/Fu䏺 H EhFBZ抟*Cdo筴>?@膄ɾ_T=騙|޻9$i:ˮy\9~7v5 }NƓ4sWc11py3x .SnH,+uk]O(-hr(q%BeJ#Wb$l' l_F< \hǛ QBYܘ!gdV6>|SL`P9aM1[v K5F}HW[1+Eypµ S@B,uU?~O%j<{(p:9xJ O۔6$uld3Fr4y0hpIB-m^d*.js='Cg`%Xd9("na[= 5^ }ȝ S W[ ݚ " 0h yX 8 S} U  ,M t R  Nb O(2qw MJG #Jl\F,Gq׶hADAVAқd&k>}=;΀;z_ P89w e5[t5z42}rJW/o_0x,/l uR)Di,u'ZfN)$(ocp?!J`ɟ#Tl]ޜ#Ei Z 9 h~!W!!AN!"T""cc"#Q#=3#x#ν$O$_H$$ %9L%]%ʢ% &[-I&r&&4'}BF'Ň''V(WC(蜂(0(y')l@) )R)<)=*,|*t *Q*:+Ny+!+f+'7,pv,6,|,J4-t-K-#-l1.q.`.E../0n/v/g/,0Ek0A00)1[h1c11*&2=pe222@#3_b3ʡ338U 4_4ߞ4%4[j5\554:5}6Y6 6VO67V707xd78 S8R48y89+Q9tI99:NN:^:ߣ:' ;p.K;s;;ImB>>g>=???A~? ?R?<@c{@"@g@<9AxA7A}A_6BvBLB8B3CsCbCZC0D1pD4wD}D.E GmEVEE+F/\jFxFF ,(GRqgGGGJ/n1$wl,lFF깏)i \h纱&+fBq#Acd!>V`޽&_k]۾9;Zř ٿ[PWږ5 }eƪTW5zQ1yJ NSÛ_ ,Ku/ľt NHŗD߉(pFƹYJǓ)Cn$lȵ>@FɾȎS= |h޻ɱ#h:Byʊ8~7dvˬM=4̆sc_1ͨp29x́.nH[Τ+k5]}(-hWrП%1Bey #RWbқ,' ul_ӽN<ԗ\ƛ( pQչYܘJ!Ւf۫V$l6ֵ{SF׎K֐Phذ`BMي0u cKڬE=ۆHZ_ܨ*Eo9܁?B[ݤT?5~}߽$jk}:E;z Pg8wAe5t5cz2r=J/o__,8/ltʹ)[Di4'|YfŞV)$nc糢0x>!` ɟRS],ޜt#hZN8}'WpMITb#kQ2wEOGg L\A ,IrcAF=WC_& 8l@  < [= | 4Q |: y ! Vf 7 v 06 x{ 4 t RK 1+qt`.N0nuߺ',oEkI)Zhڟ#l*&oeE?#քbʡgT _Aߞ$i\c9~4A4Ȁ44^S4>5}58#5h5ɭ;6z6Z86}6873x7|M7Ē7 58Vu8b88/29w2r9w99Q0:Go:⌮:+:s-;\l;;M;,*"c>k>&>k!?D`??;?@g]@ @P@@AZA AfAbBWB5B<{BCUCKC^CDRD7`DDE0OEZuEE F3ELF{FF  GUZIGGGNP(`ϸpM0Iu̹ J#ElɺHEZƻ*EgoüA?BcT?~޽<$i<ή{_9~9x9 Nɓ6uZc34r}3x0VpßH0-xm] R*ś-jr,t'ƼBgMƖ%Wd'pǹ'"maIȒ<#^kǝɴ QE[ʎܚ!ggX˰6A|̉ULcͬR=aͅO1_vΧ M8Fρ JZ[У4+G|pŵV@Dҟ0xUA R%Ӛj>},t:Խ;zM ՖOޔ8'wpָd5Itג4y#2krشIE/ٍo^g,ڰ.lsAډ)Cic۫'Xf=܅($nc^ݧ=!8`ށȟ SZ]ߣݜ"4h|Z 8V}W0MxT Qb⚧Q+2tw㼼ONG䖌 'Lo\帡 I,Iqڶ#kAF紆DVC֛g&k@A;р=|b P:f}"g@;z7}b8xL<5ub]21r7w0GoZ-3\l{ ,*Uqi/A'wf˥QV$c*&sk!`M; ] & nP !Z!H !e!٪""W"j5"z"#DU#J#Տ#$fR$_$$@%/O%t%%a &DL&&;& 'YI''^')(nF(7((>)C)Yɂ))S*3@*{*#* i*U=+|+8+.~+w:,z,N,Q,7-w-*c-r-4.3t.Lx..2/&Hq/n///0H]n000"-,1jrk111DB)2h2̧22fW&3e33?'3l#4ѱb44b<4 5_5; 5Q5̖6\6]!6f677Y767{78YW8K8839{T9`9 9U:0Q:u:.:w;EN;;P; &E>nʄ>>T?HB?߁?$?!j@j?@~@9@D@#ăb ɡUӞS _/ޞw#h \Q՚8}+YsֻMMVוb&oSظ2xHّQG"jڳN\Dڍ ,KrfۯAH@܈WEbݫ&;lBބ<^?ߦ~ 7Q߀<{!Yfࢫ9x36{{6 vUK➐3/sw`0Q0pu+.sEm弊L+Zjݟ&o*(ogH?%لd"ʣjT"aDߠ$i^f9~?[ NbXc<U3y]SH7P^Y -M3s{ CJU/XGw(PmD󙲃*=sAǀ LR>}&"ng;zH7|8"xjL5Cuaզ2f1rv@0FoЋa-[l;+*pi]@'f7˥U$cY%j!3`{: T] O.wZePW4*zrUJLR&_n.OHt !DLj DYI)enF?> C Ȃ  aS @  ;# h ̭= | ]8 } : 7z M ǒ 7 Yw b 34{2tw T2Gq匰.w/\nP,,qk*rA)hĻV&&en&k#Hb;! j_ PD\ feY5?{WKaT;`0Q]u7EN XZK2* {oHô U?EɄ.vTB߁P$i ? *~ r9 ~ 6a ~6O66:;7{7d77]884x8y868~69Iu99X93:^r:2:z:.0; to;T;;C-<.lrf>>>>K$?c? ?%S?m!@`@"@Gh@A]A!8Ai}AB[BCMBBCXCebCCD?2UDwDмDE`GREEE:F\OFˡFF\, GqLGG6GS.2wwҸQQGϹ*Ns\̺ L,Kqݶɻ&oAHƼHVEٛ!ýj&kBD;Հ?~f PT}՝!f.;wzֿ6|P8יxK*r5ػuaLؕ20r&vnٶ0EoHڐ-![lj۲**Cpi܌@'efݮʥ?U$ވcߢ%aj!ߩ`;:߃] ]OঔZ6dǩWY4y2U{IÎ TR^.v.OsP CLላ*r XIL(mF&n=CGȂ R!@j"gC=|7}e:zL?7wba41t:w2Gq]/7\n,,Xqk񡶪2A){h˧ TV&e.&vk#bP; _* rP\K eܪ%Yn5zGWJ؏!iT_C/QteDN> YKa) nH;>E\ɄS6Bށ#iX?~82~z<| NT9y.cv63vOx4)Hsr1K]p%-.mrmGB+j̩!iW(gC'l% Աd  e< " a > Q ϖ ^ `! f  :[ 6 {  \Y K 6~V`X0Su2zEP TZM-v* pJO?)GqʆUKD߃$%jmA9G> ~!Oi;{Bd84xey6>Iu3`^r:.0so˸\C-lͫ6~X*ƝiX(m'f2z=Â$ cS R! -` v" g !O]!7!|!)"q["L""K#X#a#%#m$1U$v$F$%FR% %i%&[O&C&&+ 'qL'd''@ (>I(ˈ((V)`F))%):k*C**;*\+@+ +6P+~+=, },We,,:-15z-zz-¿- 8.SJw...-5/u_t///O/20tq0๰0)0qD/1n1ϭ1J1Y,2ܞk2$2m)2n)3h3G3>3׃&4 e4h4S4#5Bb5#5h5 6d_686}6>7]7M77`8Z8b8:892W9x9[9:GT:5:~:;]Q;W;;,<1rNuH>>'>Ol?E??(EE1FΊpFЯF`FZ.GmG9G*G52u{`å 2T0ru.0vEoP-Zl៫)r**oiL缔?'݄f%ʥn彶T$cGߢ$i!!`j9߿~C] NeZc?‡W3yaéUH:ÃR^]ĥ-O6s CLXơ 2XI{ (TmFȜ-=vCɿǂ PRʘ@)"rgʺ=|K7˔|:%znL̶7Gw͐aئ 4i1tβvC2όFqԋe/Э[n>Ї+,pkaѩ@)h:˧҃U&e\ӥ%j#6b: X_ՠ O1z\ eTםY4-zvؾWJOؘT)_rٺ/QKtڔ%DNm۶ GYKܐ ) inHݱB>ދEȄeS߭B݁>#߇hϭ?~`8}<:|M˒9\yb66~2vwX4Gs録1z1\p S,.qm-vA+jO̩V()gq&l%Kd;$"ma PG^ !fi[5B{YKeV>`0S`u喙:EP\ZM񥟌5* ~oJƴX?GɆ1zT™D ߃S$iA-v9~>O ~N(;q{cK83xx%m6HuF3]r i-0roBB-ldͫW*>i'm'`f<9$c R\!`!5g~]7W|[1Lz XSa,1UuvOFR)q[OJ+ pLܵ$m@ IʈFU ךF h% j C B :  @ d O == } d  `: 4z y 9 8Iw[5^t5~.2tqWC/1nyέ Y,Sk(-n)uh>O&e (Sq#b#Jh _$8l}]FM ZhbB2WwӼdGT=\QΡ`,qN9A ʆK̊[V H5}&kEW; 1B y P !S?! !e!-!u<"5|"{"N":#Jy#(#q#7$`v$J$$/4%$us%l%%D1&Fp&ϯ&& Z.'hm'')'Ao+(j((?(d()g))>T)%*d*$*_i*"+a+99+~+, _,[N,,-5\-}c-ƨ-.W3Y.x..1/yHV// /R0]S0㢒0,0u-1rP11N1B2߇M2(͌2p2W 3J3J3'3l4$G4l4<45ED5 5Q56hA6!6f6B6>76~7|7c7<8K{8=8899ax9_9906:9vu:::F3;[r;б;;5[0<}o<<+i> >RU>'?f?,%?tj?$@c@N:@@!A( aApOAABJ^BdB۩B#Cl4[CyCCFDIXD֎DDgE^UEEAE.FsRFFcFCGOG=ΎGG6W~IǎոXT^ҹ1z.Qs ϺSCN刍-̻v XKOɼ( mH)qƽ=EKȄ ľR$Bm݁"gG?~7 }i<|LB9ybd­61v>wÇ4Gs`Ĩ1:\pł,.\qmƤ5A+~j˩XV(Ƞg1&zk%°d S;ɜ"a- uPʾ^O ˗e([q5̹zKY͓J܏$mVε_FϏ/St iбDPBЋYMdѭ) nJ>҆>G`ɆӨS9DԂރ#i\Aդ85~~>~NW֠;{1cz8 3xSx؛6,Huuپ3O]rژ(-0qro۹JB-ܓl̫$mW*ݵiF'ݎl'ױf h<ޱ$cB ߋQӖ!`d!f=]6{`[K9X`[0Uu5~ERWZO1y* pLS? ,IuʈUNF߅$(jqC:J@ $Ol=}Fd쏩:4zhy8BIw5d^tﬣ=.2sqθ_C/nͭ9X,ʝk[(m)h5}=Ƃ&eW R#0by"g S_7|,u]LNZa(p1WwJFT#l[QF+ qNh@ AKˊV dH%=kE;_B 9P? [e<45|}zƿ:WJy07y_v R/4ts㹲,uD1pϯNY.ߞm'p)n+jJ>ۃ( $g l S % Ed # h " ha 8 } A _ M  c \ b = 2Yx_GV8]S[,4rP}BVM̌0W yJ 'RlG,<tD NQA(!pf>I6~{#<lK{E9`x֥g06uuAE3ҊrбcZ0o=*o-l_?*8iT'Zf$i4$ }c 9  V!! a!N!0!x"^" d"R"#3[#+y#t#$IX$N$$%'^U%p%%.&IsR&&&#C'kO'͎''EX (L((((gm )I))A=)*F* *cR*+C+<"+g+ͬ,@,_7,|,,8>-L}-ɑ--Z;.az.릹.4.}18/vw//V/F50t0/ѳ0x0[21 q1R1+1p/2,n2t2@2,3Mk33U3')4ph4%4k4I&5e5:5#5k#6 c6O6E6 7`7e7g784]8@z889JZ9c99:<_W:::/;^tT;;;8DųK> >V>> ?H?0?xS?@ E@Q#@h@A+BAt8A}ABM@BMBޒB'Bo=Cb|CCIC2:DwyD#DkDG7EvEDҵEE\4FsFgF,Fq1G@pGGAG982xw[6Gu쌴5}3\rW,0qo0yA- lS̫V*,itᨽ&l'Nf;($qc QJ!` $fl]5F{[Kh°XB`Ê0UduĬ=ERņ_ZOƨ9* ǁoLʴ[? ȣIɈ5}TƙF߅W$ɟiC0y9~ @S ˛N,=u}̽cN:͗3zx(p8ιHwJΒ5]t#lϴ-2rqFЎB/nhͭѰW,AkҊ'm)dhӬ<=&ԅe R_#ըb!9gՁ _7[|֣]4L}ZWa؟01Wyv RFTڛ,u[Q۽N+ܖpNߵ'p@ ݹKˊJݒU ۚH#l%޴jEEߎ:Bh OA?dc<4|y=:Iy_7^v8.4ts[C14p}ίY.Vm(0n+yj >R(g +St%d#Nhꖭ"a'8p}_IM쒒#\lbE2YwּgGVﰌA\Sҡc,qP=AΆM̌_V J8&kGZ;4D} P VA e0x>5~ {R K} @ ;azc083* 4sJ44T4M5G5#5'i5o6D696H~67B7"N7k77?8Dc~8883<9fx{999@H9:x:ҷ::b]6;u;;;-;r3<̷r<<^B<0=o=7=W=Ȝ->l>Y'>l>*?3i?|85~׀zɿރ*'ip޸S'Ifߑ#h"$kc8}E!aMg^b@2[xcGX<]U^,8rR恷BZO̎3W |L 'Vl 鞱I/oK}I;`zڥ"k08uwDE5֊tгgZ2q@*o/nb?, J3|SĘ GU#h.Dw8}QBM*s?b~L2<w{&oG9xHҷ\6!uj,q3DrA0foV?-l&lb*i;;' g Q ] $! d!7f!!!"6a"Y{""#2K^#{## $U`[$$$.0%wuX%%%PE&U&ϔ&*&sZ'R''L*'o(ݴO(&(n?( )L)H)T)ٙ *!I*j$*i*+CF+9+~+,f D,N,,?-A-c--a-3>.x}.;..H;/z/]ӹ//]807w00-0s51Yt11B1222{q22 X2U/3n3'3.m3w,4k4=4P4)5 i5*R5r5&6"f6Lg66#7%7c7n|77!8HL`888"9ja]999C1:vZ:Ի::fF;W;Ж;?;[<РT<N>]>U> ?6K?%?j? @YH@:@@2A{ FAOA ATBCBdB.BwC4@CzCPCCI=D)|DrԻDD_:ELyEE.E%t7FnvFFCFG4GsGG!YGV*i /Sw'f#Qh忚$c+8s}!aMM&^ob¸I2[Ñwڼ"jGXijDō\Uաg,ƯqR@ƈAцO̎bǫV L<Ȅ&k I^ɦ;7Fʀ PZCˢ e3{@5 {U̞>J}/w;`zQΙ/8+uwsϼE5MtЕϳ&Z2oqѷ*Ho/ґn"?j,ӳkDTӌ)h$fiԯ&e@9Ո~# cbN֪ <`ׄcͨ^3]ئx7ـHZȍYڢ]W뢖3{-rT U۝BQ/͐wWNQݙ'l *Ks޻< MHߕ Q&nE!fHB6"|j@KD=a|f0:@vy䈻F7bvе;[4愠s+^p1禵p7@.mYU袚+j3%{jį( gU:%. ewO뿔"Qbd*r4_yLI\ݎ&o^YH.sV!jCSDΒXPf(m?M= bJ R;G"h]D77}BMY?2b~{ 2. wL  T P I # *i r F 9 L~  D %N n  A Hc !3>jx}CH;zҹe]8w?-r5зtaB2q;W̜/n]'l,6k<ǁ)Y iQ2&{!ff T#6c{.v!K`P`])r0vZLE%WnЖZGT*!pjQ?CNUe K$?j H : a ! F!:O!!"C"]d""#64@#y#Ǿ##XI=$|$ӻ$2${^:%ãy% %T.%s7&v&-&vC&4's'P'X'1()p(r((m(.)Km)=)݂)%+*n k*R**G(+"h+g+!+i%,7e,|,C,#-Lb--e- .a_.>..1/w\/a//F0:Y0ј00\1\V11+16q2S22A2X3P332V3z4M4 &4Tk4 5J5-;5v56 H6OP667) E7re778K5B8z8ܿ8%9mJ?9~9Խ9G9_<:ؤ{: :i/:t9;x;C;D;ԉ6<ur=)=n=0>`o>>>>:-?m?S??\*@#j@h@6@~'A8gA~AXA%BMdB1BzB"C caCTCC2D-x^DvDDHEO[EҚEE)]FrXFF-FKrGUGG$BG2]xf۸GZ@ع]Waպ,;rTһB]Q̐м7WN፽'ͽYl K3<ʾ{ H TQǿE.!wfBQ6{*@rK»L=Õ`|ݥ&n0:ķuyHĐE7يv!еjųZ4sDƌ*o1peǮ?.?mȈT+ajɪ$i;(ʃg9]%˦ eN7"bdX̡3_2y{ I\UΝ.^YvϿ.PsVЙ*CrSѻ͒LXҔP%(nmӷMH=Ӑ J! iRԲGC"ՌgլDe7֮|?BׇLБa?تa~;؃1襃 L6Sǘ IY#h2Fz8} TDM.vAbP2>w})rG;zLҹ\8%wm,q5GtA!2jqVC/n&le,k;?) iQa& f:f#6c]{!6K`~X`]20zuZú TEWϖ-vZTP*oQnWӖuDR@/ D5օ-f#B#`Dz%`zEjRN+ہce]Jo{lr3  ;ViT|',eK*wzyU̽[!9KzNt,* N=;abهA^/! 30@ 2c  , w * kF )1 "R #s W - ץ V . L %j | ؇ U c 0 vK }ܽhoi:KmD$4"q7D.%@pQL55Qԁ}/i©r d?"dwzmNH &4}xItOo!kcwfGa\ XXT y.,M2oS]M '2KRFrTٰ# pr+ZI6}gY38I73yOk󻋇mD˾"H9>+E`?8z ATkE&^,xE^vXˎ|?Ҿ,37JaqGx0(_"0S"F~'KvADGJvMԉPfS;V Yo[^GaNcޡfRDiktnqsvxz:^}3!xɆXٖtΏ*On}7ív:xR\:ɴ#}@յhhپb=D=-1*F2RK=9FR$Gȓ_!B1*[p9 ]; GM\!5: t;+Q}'7Q1N4/j` U  .( ɭ 0 } -  ;vPMi|T9 B\6aYќ.XU3peДOw=b΅S/#EXjzAƕǰQ&Kļ¸O@^<]xhXE1~_1?bA`I7 PLU$z>Ue!^u:D>pL)nOmx ԃ?4  @  / E   D   ; .  , QW `H/K? K T dZU\ZU3M=A1f "^$&(h()>*,z-׬/v1<346i{85:;=O?@B%ODEoG54IJiLFMO#QհR;TU[IW XLZQ[C]߻^,1`٣acbdGeTgehjd~klf8nop:Ɖd4TMs驑#’Tؓ5)v3;#BF#IIHqEz@91&C. N?שª**x\S>ڱhhU?aX%anJuuԾWLMGv,@cDg]PUHPIaD}R,.:l A t !p8_Qoǟ,DVIdSnYtur%l3?aM\Rp?( Jj_;5~Q%z!IR,7k{S= ZLuoYt$}V.$h0,`{"r_\>pF&ppEpHӏ `+n*1q;P.k!\ DV}b#OZ:}.b+-U^-gM&|A1a]He K3\Dž`J%LsǾ b-tQ#ulS! C d „  {  ~" @ _ | K a W( C ^ y  " h n + 8D )\ s # . b n  V& _; P d x f ʳ c ":4EVwg xe\`t&,<:GTa\nz#87{g ^'0}9GBJRS[ckLszC}t0ä,mw@] Y /g~sH #X%')+p-*/0D23467889&::;Q;;;;l;3;:t:9Q9876543g2 1/.{,*)#'0%)# !=OX  p5 g =JH7Z]%MhvxznuVp3kf`[-VPeKEp@:O5/K4Uvٗ{8ZXwɖ^+/Mj\g>V4Pl- :*D^x2)JBZr3.E'\rۈa8 i s5XJ_s"p}8B&9L_or%>5 U&8OIbZVk)|ތsA{p1Z-<L=[PjEyܖ}m`$1n?LZBgVtQ2D*z e!-8$DOZf=qL|E)T]NusJ"+[5>[HQ[Ldwmvj9<ļ;8ji8%C-4O Hf$)S/4:\?DINT*Y1^,chmqvn{'Ԅx# pʨaй,8:2!@M~ x A2r #' *8-H0P3P6I9:<$?BDGJEMPRhUXZL]_lbdpgiZln)qsu/xzz|~4f։ ̝\+y3B#K׺^_L'LI],U{~\6 yBCbe M=Vcf]J,l5OTD c   $ `    : k     C i      ! : P d x                      u c P < &       g G %     j A     c 3    h 3 Sd&e#W<^z,>INM rW9!#$&(r*A, ./1\3568E:;=T?@BIDEG#IJPLMsOQRTUWXZ[]|^_^ab6degehi$klm/opq$sqtuwJxyz|J}~'Y 0UwҎ0BR`mw~vl`RB1٪gF$ڱ_3ֶr>Ѻ_#g&Y4ISPB(f:k-St4FS\aa^VK;(fF"d7m6_!>SahicVD*v U.uFTXT E.g D{NK| <j!Ny%OxAh$Hm=_  > ] { fenrir-1.5.1/config/sound/default-wav/HasAtributes.wav000066400000000000000000000227201317357605400227520ustar00rootroot00000000000000RIFF%WAVEfmt (  8qfact` data%r]#t Ǟn+nȅKȭɢGreb$S~~wF7=ѯ3pSa8^'xͿ#AVU#vϽ&I[_ /(:^kszLN-2_ަԜBզ~" #֖!֬v?nh}'k"3kVڿp8ۀxܕw' ޤ}} 7࠭!Ro#rtZ+(. R GO*ǧL,uN"Zꀎ`s:5ĩE mJ8A 4Ȃ+% ,~⻇6vOJ݇ȱg_!~F&cxi6BK"+u67~u3\GwV2i4 R  #j : - .PxzsY%(0q |n+VK{(N=f9Do'S9mh .!!"#)$%x&u{'ezk(\)UN*A+z5,A+-:!.7v/f0c 1-W2ű2*3]~4^5+j670u8]8;Z7U6BO5AI4A382/12$0Z/q{ .f,+*t)3(%'I&h%)Ci$R#9" !G_ obܒs^S1 `hzsSj*ҰM % T} {O 3 U¿1ʍ@Z&v|UL&0Աka$Zjf˗$"q!Z d=wbڦ]kFtl$ȉŸ.M߲ڣ/ٚ_'խ6mraцFZi&A98ȍks/*4c ˻W37΁ИGs}/M԰}I,ڶ݁9܊jިߔWNH)K>:>o7ꁩ436ݸ@><F~Tn%f[|\ Sg%%EKj Il }Q ~>)L3/XQ4@T&^p_k-=p %" $$g%m'3)^*d, .")/c1R3 4el6wK8׌86P(5Tt3?1[ 0R.,,*()l'+%#Z5"=v Si42óogpTXu Fx0 c _[8Cu'U iIp-U}&+'1Qq.DžO޾ ~۴(4|KufbաwёTKsdLjȪ]˰Yۄϥ{xs#Rl4f׭a']mZ݂ XdW#W;X[Z]سaf +mYrtt|]wݛKµ?5S* Z0 F=H]c uW؍k+V#IC8!yFX#Py%c'})Ǟ+].-02U2s}46R 8cu]7015.3_=0ť.YFu,!C*0(J%#ءQs!fe{^8,-J$inO#1 K 6.[r\d4'#S&),|/ 3F ?68׊5#]2'L/R,6(LX%m"2Bֺb}>lcؾ D}:C\]l7%B.dKiشqgݸ{ڊ)׏Մ/0ˎK Jw;Ͱ)ЃM&O;޽W(V`Jf:\{IC1fw M|J۴ ɮ LlVjICKD"N0&`)]y-q0S4~7a7Sn3<&l0W,~r)$%׷t"HrSlI>*b > dTBD+ڲP1a>B<6? 4!}RMaɯǩ&qc`h՘ ٖn>aG`%@obXhf6vf[ ! o=v5k"h&mT*wz .1,|5 #9g5Z1p--0*p&"4,:hi$@| qQ߈Fĥ(L\>!Կ6 ~<dM⦅zޅڗ۸R$Lإs ʽIѣ:w^݃> p]雹ZNx}}eyOC:ڳ% >Vpp=l-?#uȳ'x+H/j3R[762.p*X&i9"_pn0(" G&)SaIݸPꈼt |tfdbR?+z#HdM܈!=Zx &4|dL$Csh 0ˎ U*I v2]"{& *ڞ.l<3F7#L6)2az.F*hI&7u!:nh.n:۷ 9zi<ͺc+~|&T:T"Fm ^' ,ىSNzlɘ) %OPv^;Dn^礹oME# z  0ȍ 5Jժ n 8)$T5) -(2h6P77 3vݵ.U{J*f%p!!&ʤ"= fQ U@i+x<4QM޽^ [h,j0deV {ή&'ӮS|4ż FU鹩[)iuG#E LGboH 3%)5uf.C>37U61*,:C(B#B;]:,&Cm ju,sCH,hB݋#TԴϕ*k%0 Ѳ-d @ lgǍHfک>E^j}ᩆj]۪҃ ~kаTӮ>Y)-g+ A8b}Ҝ /JɈPxvr"m'7h,je1 c6661Ji,'ն")G" 0pⴶ^fh3ok^܈L׏8]$3C@ %٣ N-&,QF1r6Ĺ61s\,>,'O!@draC+ _ `Lh[,u)Ҝ[*Xoe?>\\F3}b'8~^O QFE7#^E)SE.3x 9P3T.O(2Ě#0<>{GKSPM{"SQQ|IҬ5@jOж2XY |En: Gxd! k^?~\"q^(U-e3ݵ8+i3Ic.(S#*G>\$j% oVm;cxRQ7U-樻༂Bk{'93Ό> ozߕ刈I\׭3L\FSV ;4.{8#W(<.(?4k8»25 -X'6!a<36 -]<+0nƯU/V\nӫ=Hy"H=p~'hj3|R0i9 r 5L $0X*;.0_`6pN|6W0o*$8O3̠U=v )ӕ`P/dA H$= Vށdm̠ؐ"[:k"|qFg3^QVwOI3D A&]>,ʪ<2;8~4.L(I:"y: o5 /Z3J +;߆iӮyfOṢHhI~]QnaMyr&5eS `r(Q@!&'ق.ZC4te7X1nS+u%4"K} bf?5,%nBWhe2dkpiί_U JA: kH䘣%, |Kӎ}3  _"u8)/5 >6)5R#%:]e ܤ^ӸįYV㩺ݝEÌj=zϏQ(o""Ի5ֽDA O1uV申Yo}cXԽ/0Rt7\-lj9| &ʧ_1:[Z!NV(/Χ55D6gt/̜(cT"-ֺ)XMHݩ 7h핃%V# 3̅&9kG#SmCBPyx)%~ A|6%b, 3G8n1ō+U$A%;[ mFQ]\6 mlȰ;0Քhܻ7㯏q]5{Nu# E!8 eS'aZ.*45\I6,l/B(P!VcUK :)!E`Wy짒o/:@TC]4r؏bJT芔F":p.V$ Ш]  j&-(4~c6d/Od(ӻc!ar^Z ۟U[OcH8@ 7U,ҋ!ہBcm&έU#>EY-lD \ɲtas#*j1V@952*#TlFŷbh4yLǶk͆ e&E+2x C(LK R30qKl|$U+%37k0\q)."_` ({և=︓f1Y Ґʠ:ʹѠpU1?&C.2-;j; h ˴N"f) 1ej802_,+#Ve͚ 3b1!Hbٵ3FTʾe?ʺу"O ~|mp_ V#%TP+2S( 8Lm0y)߅!i ,3}#Q Kgpu4|_zqJ adH1'ΪJU"(ENcm쩺:0 ebh!4)20)q8 I2_*#^c *] uH&l}IZ(ޜ|ι!Qm3DݓF#eceW ŷC"*Iu2p&8@=h0B(v `&wcC B>sxתNmՆ61_&)ӿ1]˓٬O/TR&} .yxP@( P%(-/7x2*u~ #)dIlg #, (Լw\㬕ܒԫ5[qF3!Z{"jG%t (*)0u8A1)ZS!2)M\,m bf6($F,Am4?p5 X->%$$8 y n!~@q>O0@-T ԫ ˯B 4][ Qf H8 ugu_P#I+J-45*w-^%>V Ipo))3<낃$xۥ7ӂPSJ5ӜMzڿp Nб_^+ vݒ^&42`. 6[X3`+ "` m o] Rn]m$ם=N%φ2׋^Iim`w vE+ #Q+3Z%5g->"%ԲA# c>]Q]ta]Rن>=#Ⱦ$΢OTӼ|!;I|# [V0 #+n*4((5ԗ,-$_} &QmLO%(gG>aΜ<_kN{t9; s1: an]P(%9.%77}2ď)$2!Z78+G6^䠵ۙ*KyÙ2bp2Ez SflLA#+45.V,O#K *οiM/4fN Ԛ&o7U>! آ]UV+xmG"V(+z44,g?#bƄ0gD8":\{U,o{N̩դnhs e~nf[`%S.F7c2()1 n:h&ACGXLfPIlS@jUi`VNVϒPS9VٹjZ`_e,m)|u~3+!r *3ڜ5T,|#?/k(XCD=08 dцȯ#m@׹a^r]}`Nlp_'L s)$T2E6Em-C$[P2<x`0[aښlcBwroe:$X9lmm čޢԼԣ;+ 2?!a*V4v4g*.oX!'S6UCs|%qPހ P q$Uߨt0a.rQokvN"8X,*5i2)&dش,x(uhy_!e>S ''IŀߜCLٖ掽6N.TT*74!>b y^ki=XNmGGb%YɵUZ!)H^}ؔt]7ӫ\Mc+QȔ "뀊 "Y 3}+IۂıLPZl \FTmDzU_jۆ?2sZ^a$ oP) |!Pӹ,{-2*wv1SN릝$:lS+wN e D.'b4y&ke.2,R%`q+ Tjb|zzvo9$\Esc<Y*uv^IbUvdD^KAIV$mA&&r94ܐ|u+T4HCKڻg 5")}}Px]ثΐkaT%\\&r sV#))|Xu`^9ڬ7PbN&AV^"QgμKAr 9 Wa$lPD{adq$-B> ƺ<$\g6CnrJW7;f24l\F>8MǭOV B'DŽuU˼`6~U&s , `]H@ʢ#^j"@h$l W}H$!+lcr{X=A3Ȩ Wb`@}+Xrؽ =6 ۾<,b(Aח ~aKK2$m)Ƣ.ZBc^,V˫bX ܳ7QFԌ};䲩7to=41Ah8~zЪoUѐO}zo>JLuG1W!chW:=z |o ' 'D?T9V}xRb2%H6!]d.9^WHy a8گJ'u஧̢=PmpQ HQ) |!4N~|̹3|V:!YcT "9`fgX6 IY ْX6$m:  o>oL8JvPdC,s2YͥG1~z4H+{"rgDdD.1;vpd,jҒTA;*7}w+12f`֙!|YwW<fkB\#ލiAD͠%p5^?L3{p\DC!BdlE_K Tr>qJxUA $QR%( ox`9 !)Hzg{rEE~{NF?Hݝ♺:. 9N*6[ҷw'54۝4<HT1!o|NuAŦOMV'vX0 ^)e1/>6N/GkVAև"gCɯϮ%l >o>+i=<@[;³2/OօX]ym.e1_V3T,F*@}T!B#bgk!`_c%n=W>fԞ}ܹ9G4 $'ykYV"FhҔpQ\ a V"%golfE3j@1b'I?C欷@'(9jx>p/PaLLF !0 f2f `4}sIwZ  #Hh.ڗqXT lDDL+8&2Nr\L gdٜ-mFFUVj7Qm#Ij#3fkP ȅYs ![" ZxSIj[ԓC⼡ NDbo&NqRŸ'='twH0 \`6/aD@"hb5M9Y|. =!+Ґ#5 k_C;7Eﲥ<} ua]Eߢ'GDrϡa$^;a"# hY/ -SrWIr$VWnMؙf23 α/٥IܻnE|Kt FӓR6ӬV`c_*8"hh58G3%`"q + ރ'ؚ$m0!dFJ8Gq S"=M3氚yRk1^@(zNϔ~ {(j>c?(gl5EOK9IKO6%ФXqQ pa-8V=E^ Y% c*7ϳ!nBe_d).| \?9ᯭ[n K'ڴ%1 qyJj=È ̵PL9rWi~W;{<==y~\ za;L"<́bh'>%(3wܛ9vbNJW5dY- }xhSո":f>4|>ܜt=ѵ1FɁX&\ sڙlۍE-*~6 oP!Y X$lZ?%ིqQN_sZ悾;k@A?^ۙ'tdMJWMœtں]#{rX-Ej4>}/x45A.C:+ܠH٦0s4Yu`a6"FYTj>8R! d$nRr!XeuOa?Lۼ`җ wk < &X MVH a$A!ԿeYQ! ~ci2=PM|\S9xXhCKkaA$֢!dxoi8OiJU B&rƚQ[Z.S$m3㓛1R2T (ׯ87"ԧf550] 4;] KݿȘ?8!hd9\$Nmfi :4<%)} V_(h8A؎܉:J-;"އfc?*TF# ok-[M/ !TUrV@67ŧoNJsYevd[%~p{"{h?OTB>s'Yv kF=Cӵ?/y܎k "Qi};x%DnFL:  ^B(ǚw;f,:b՞ %΋lɮ_] /KZ>Ǘ) |ט}%Yxp 1u ΁ؤk @DR"> e(mHFW~8|nJ.NV`C Cp Q%HU6kT{CN߼8@Vݺ 09q^RnC#j)j{?~{S OJzޝV /V334 lF-DRMFՙsZFǢUo%LpP "f- 9g"6haL[#[Tԯ{N^ϒa$E2LH>COrWמ!x dh" qMGA 6WmrHWЌ8sn XK0kjX.= ,sYK{68q\QDDwBes5YLZ8 6(#y+k>)a{mH%q?-yk򴂰+-$l/TnJ~ ք{a!ci~ v'b@}GvֆW\2ѾtnK ?3,kAкp0󺏠: !qrU=; <脓_EKLOd .%2Ni;G5Ji;@=X ?<}FyU~zGJ2!ޖcg64^qISގ-竈dPMZ Q&ssYId ,)[ȓ9oM[-ykg%4qս9@ĥ  Bd\.CslZ/FrVGm Gդe0P. 9`ǥWLo;M}iył%pцsG *]#~eM 0ިw+T¶UFZ>M 4(Ja#2X06 -!KZ큒B Y$ x* ^ca*Uݶ $) 3|՗qkTB߼+6:JWθl*r!AVd-ߛ*P~#AhQau #` 'hv8^/E!BeX>IU%obv%%dpb5 %b(ytD]άbީ=!cN+YVȅHߎڝj0@ b4 wfP(1x*O]63K&sA=KOZ 3>0PjJ@ S{ q"wi|uDй4H,7'Juܟ ]'wo enO%_V/ێm1.y8m?Βl+^YX&ssAYăNoAXkRBrXm H1[֧n4L\*?"}Cf"&grp Ϳh?VǣO $qhT9UX \V:\:&8rC,O%H9EJ~!{[[㵵 !bnJ  &?'8D=ߥ ,%\M 9#؀#5RRI!e5v(dL60Y\ \ U%@>&tv;dRJ./4\¸ ' S;BDsZRDfƭ44# Xk!^|ruW1IŔ{&pMtِRH,DE͔³*JI7j >BlEع4+.Šd-G//ٍnKJM_}H@QGlyClElпE<.+Z߳ 5(c x)%,?%KpöJ$ s)VvdvcYZopMOPt \i lM F!VXgɗs [Df> 1&02|ߏt Pڜ܌M1 Ӕ`І<o]'v Ѥ@MBYn$ Km5b% jE@=BmhG90TKlV a8'%uo q#'S\kKVEh" 7hi =&U%spt'^v0q7mRGνq.8U-9J!]pbQ|U4st8\C(Uy[!d,?&~rLSv b& G,11Ih/ d#"@ g"( 3c\?EJܾޔ r) rp͎* f!u_mH1;ޕEL[X;pP_j;=_-ZI7Vb2"0hD ͧ"J #VZxi Ǫ>weR}OwkB)YF]\˩`+ %FpK2:ݕȇYa0%+Ib/';7:ɇ[grZ6WApCG!؍d2t\wI5LЧMrLf 2G `֫25.Gy<2k3Ӂ}xG_&@sx[[櫊+K%q#&0jrN Vm߮4  ~z GaX>u _^'3ID9U. #[.q_Uxܬi` zVmRHٿ;1;WRG\ )zp>sAYġ?}wL%pYŜ P;9ӥbR'd -1DSA ?2۫ )l"{D˦LbE\@^y/m`$^.n{c?r*DIEͦپhX1,1c< $)!lva4AőS!(e/j6=]0j :@5ec1 FK q bU%yAk^VS b -9CN7'ɧuA7>蘵-SZb&ʮ9] f2PROfEƵ-kA^7!>dZdz!d}yf 1^7 8ﲩ* ; }'`@w%g o~ |"W  !2) |`.@*SL9"6fI=RSa #n#k A,t/ \ 2)9!-Sc%&q19lDxj,e1m@HRW@}wuG^X39LnJ'}V?}%2Kqۚi=NpODao7䠦:v|u=6[ZΘ k)A |O:6} xy)PSŶ).>R}^w3oKkBFA!d&EtD0@̡~{LT>#kW7ZK1@sYh'9v/R"4|hy\k꠷V\ⓓc)CH-ه| Rv%1+Ѵ3ޚ>ʨ9⯡L] %v d kIA 9T~#<9B&cxiHHԘB36ȝeDy;Fmp?TJ߽7'_uf`ɩV X'Sdy,lpT1P`"L 1I }%TW( nLS;9Xݫ/L2E#k 0"~!ezd7GD-v4bc&4kb_B'tb^+TX bEέ1 s`X!]:yl^Q8 K`*[X~fK3U$mTz,on(Ly]zpP:&9r$ 9l_>,RyJ&_^Pe"/gju?`tN\=ί޹G׻ ERj>ԅKJ53 $Th]8,297Iڦ iMXN !W |At&s[\S'JuZ3 Ìo&AX> |e!o&"MsfxPhR뀍sZ˃x iBǕ 9#ܤ^TgX5 RCZ #Ǚ@ )_r$Wm;kA5$* l.6~TzI!Le ГHʐRNN$~m{AW W%SY- zoҩ- w!K3dU+7 #]-Gym9̭@ C^C4/$lQ ?#>Q*R~ B%>NJ7qߥSɘZʱ n&ߜx{jr,L `L#k#6 3i!F=ӷ.@\DQneL !>~{^)wG{e} w2~ n 9Bb}7)>| W[ * D&]7* w;gIݵZm IoQO L~VHNW苪Y  a"g?_-*5ޟ-{To"rMgHH؃J]'vɧ"o]g_\0ґzoP2ke@h1]f3$SY:nSqSD>ǖ2U@VZ-_QGկ5#isD@JIM?%pyJk#xQCjBkAw\g*o xM( %xbyl@Tz\wfUKpPPl6D7U6 ` zLnW%طqŸEߒ,"qgS|$Lvm(7k@?S'v Cʡ5ՊAxjj1`"KUcw*fJkC/]k-AOܓ핻_L+6Cfۣ2Zq\lE@ZY1 )Q_.# i-_ BǠ+ST67`/;ܮ fl@b=(C"!h*ck\8'7tڒ0 bϾb9J&9wte]: aԨ.H돌Z _yj>[yl׫=FޱW ͦf^j@)}O1ُF.'4uK(xRA1ag%41z nm? F9Pո._(Ӧ&Դ}`ފ>[B<=B5C>-!%eo,ͪ\=sڸZ> '!H…GJiۯ=Iۘ W'h$w8m2qS8_c"4(gZn2I ).ÙI9+K*" f!M~PqUp6PЧ q%ESs [#HD::Lu_ľLĴCc)FOM1Jc*NE+Oⱖ()y{659bp2%&Qo4@>}=vWڡ+75sW,AįVef%3p-6/ܣ;6y۝k7WִDB9ǫ LՁ+T63+4R508-bW(Gd,أL ;q%Tpޒ>#|kwzglΒCk^M*=ŀ'w~³yG-/ۇ[xDjBͮdh .4)0]^{Qr* ]saYY%?XY86ޝYX >#["g?d +a@R& t0 _?J̙dDِL<|ܺDvl(FyN Ć!6ZNE>-5 %}vB2ﱄ%>qhu"גfF4Ԝكҥ=x\?b&/ 0!X*PA"hϙ}y^a",0Z9 XKF 7)}ę!}dwaM%`!LN `'tE-#kDfbI1'bq%TϞc+ V`l0CIPI!گ/cS~{-rK~uzSBLT6 Yd4-E]_ŁO&>UW!VsZ^BqS_:w`f"¨+DQ$m0#k]̲[`Bo" $g)'lpP9V.=(Y%F oL⥭$nRP&%roqJ߃$jl>.0AWVBf8_.PhP:7ƕRVڏ"gߑR !WEpQ^|ASj n<zLTB .kHABZ^$*m#j̱O0e5/0H]̇eMvd_Vb,U 9&&ktAK>%0,p M0槑E̚fF۔דkA\B+T$l6kHA*.EA 7{WKֺY/ C٭ 6Ob 7럦RvN/b덑gb7~--E|Us.LZZ}ŭvP !%b]q~ {UD;?݄V岡Ԝ~U} xaDΕVb'X4ϪVBǩ)ŵQ! &އ曗 @BV}x4{=s5Hj%@2zmoHI !`e|"vg=YC$+n #yk4C,g5.<` 5#j #%jOE j*> ~B]g6U]7.U k7ZA~!Sec+Hu_5)!g}cK+:7A50㞐ӫޫJ '2 }j"Vw?g|18tN #Z:0n Jn꓀;bW'O}Hw*ofM84FEEM72NPL- 9 D &ܷ|$'vmp>P6qV'%t"Hq3iۘ<ſr P?X"nnKL5^*.&Vr @AQ C&0d-V95U" fF|$ lZu#x^jh4|t  QOY Ib_(#-k~u{`MȻX3"f pw<8}Ow?&?EqQVԢV|s;Y9>4뻜Z%]#njJR`bu'`i :(61%A}ow.Fx|h/'Dw̬Ft^FW\pNR1 =T !=A}w\r筍>?K)o{O=TVۿJ0_*〯iM;R ! KG'[N/kMA^^#1iKRF\AsM!\&cs#9h<ʜ ^_#wdT?HcC(2bݎ(tCf2N% oS\i <5&+^ (M`  ]Y Aß9,(`y eu`7!p"bRg5պ9{`.q! (Ffenrir-1.5.1/config/sound/default-wav/PlaceStartMark.wav000066400000000000000000000455201317357605400232340ustar00rootroot00000000000000RIFFHKWAVEfmt (  8qfact` dataKsm&$5qV%r\Һg.dG -s\d&F|)Jmy/ïAJ[f̬er"&;0]ص9EZhls6/.=f"0,/ 嚢ٱV;Pr hSn$wO'( C7g+P[D;@Ai6󡊉- 4g,Hm*#9a[kNUy$SNU@~¨nDZPFA>ն<~1 TITc!zk#" U ڸ#UH^!`K xhЙxE3]4M3.SJAzBA~1av:㽂+ș8ɜ$C47 ׀ljy#ϒ E!^Dt"7 g%-] \!G aUY >XrNgV"u!5 1DAcEؗ!Hѐ2F0f4.{NOٙݿHLWmr-&D" @Xqd%!H>msXQ{HUM!7 IxXm}.d_ݔJO2^ZLssEc&U!!$]`atS SdO!6 짠:y9}B}< }"7 " 8˅nHD$K^': `i@#/(RKe  _ 1Y:{G@=Qp;nΧ$.|?d)C8(̧"DU R2]f309L3"`;b? ׅ=,rΰ\H]mQ0#ź WVIg. 5jY g#!Ogo"Sq5{x=iD7PO∗۠-9O6{)8֏H?/D+lr ɍ{^;uZA[<IHn6dN0 EAOCǷp%P" fw&|I Ԣx;(hZ"粤7M`ј <ݮ9$: u'^ X-S9ȹ=,=UhH"@W|&)b{2_)fĀSz.פ~]˜tZl $ %JUIrm.{$ԃhG"v Gҭnd$ԇaA f8"Gh3PG 7+#c7Xh0dvt [IהcC!0f wV_MGuXs^[5Yg p=:%F\Q۳息3.ӺK7ۯQ1۹=$!mzOPE/O!p`$F $ݑak8+y TNXo/Un.%: E V:h TD0K;38MkL1nHP@_K14;L$N췧oĵI[A[N΍<(GT_cg.=͊X)ZGXUr3<;htxG|m/$VZYshRBxo-+%aocv:%!ЛOo$B _aW cq/%_>J=VnPUGqNT% 5V`YiT#;QLō˴ȬB䂽5^WU~Ic!+﹋ftZ&NwU͸K]2jGf#1Z铫6D^: pV%k,^_UJuٲ{~-~#:Si?q;#R!rOq`{2?Dn$Z+Tn`Ϙu¾_ MYI;8inW$Gf0we` ҲFPڑp9众h H<¾ M \GImy[}N\H;P|t&Jñ^mDnzNLĚQpį.F) .Dy Ǧ(Osp&>YT{u8l$%a䉎؄7>1h1j٧;H *ݲJF"[ GWOZ^7h /WaǗ m\SJCnPd3U-})2Y6_W9Zs-'$ a#GaWkq%~,\H!ݔ i5Ʌx«>څR&YϷ)iP]L\sG| {>~u3lJ$hKx7Q-̺ h>";`][utʤ.O#n$@^kt\` KbG vXe̢-d K-Q=:C4׼Zʒk#D_J#Fa2-3@fGVrOّEBOlke@"[Ϋz+(|Q8F0ՂE] 4z"(#a4V>u'@UjݤZ2sCiW#M\{.~/ypQ%+Nco -]}U*bK/ xʡ1(=iau7Rb:1w5(`{; )/jxO^pkhNyܰT{q~I@d!:M晱n$5pS amY Z$.?s0ͥ& TJq$< 8324Sz0.pӺd% ؎z$Q Hj֨ W #YjZy6:<܅",`pD|K~nY"T(q W4rkZ;ާ-dO0oDs7Nљ Y1dQ́-2{[^~V(D cq4Ц!x67g1‰LAv }Y8 7 :ڝh}2) V?P^ŅgW+䮹yE(LjVly$U>\* 禋Eu!nѵ$]vt'L<80_l$ au)?c*݉@ɛIC,OL@ `k "n ڊH. ZP?j+Q* -c>l?쫿Z;ɹJi苖3.2:<85# `au V%A,a"/ +a4d IEO#O9 !#  rEvס}5U kY#ãV6 Wȕ3f5؅ ]YPյe!PMB&3+-bf,/d)BEckЫhPzx( 1eݻ,ᔈT3-D}H:;0eIm M +^t'V?VǦ|eO!!33 N>.j Ҍ_&% b 2Ifd7!ŝ쉤spzݙP Konzߍ{/)b}")(oA%,:H+ds{md$!{~::Cؾke8i#'cJ !'Ə*/ϓ5}r*C&4 ]Xh͕͙Pb/p{YJ)-Ֆ N@( * K}Г*ㇵv<F<&9Pb*aCpN%Af4kwWrj#ע0H6U`uKڔHudl|!$]:E^BSϥ_.IPjd):A M<_ZľX$_aQIEVlBeo;ϴ1t;fH\ERO-^5k8R$hNCo-.܂+b;2`X %m̀ XUhz"~K.nސz+~J C(3 \SV B pT%;_uYU.ssг*њjF#MfLܐwbތ˓ CSX s`| LFwl-'$mkyr:{h})7vRap #WH TAUKZ0k!$`ϲq;%Xܩ[u5f(Ww S 26HM%CapZ%D%Y\N.ӈo$ޏڟQ֙Ɯ۶䟔=L5ܞfL"VfO*rwP ޝ8J:~8_itU&;Ck4IHV)-ؓ:EYbs 2FLflNfowz~sM66rgO&4Џۚڨ܎XV2f"P2ҳfqZ0{VP>KpMP@R{&I~/b`hcxv@EPO`U2ul(y Zܳ<`_uVߩY:qU%j_#];<Rh "72EIl$aOߜ+.BeOIcG!Q2W A]^t-Sܹ5"ԏg -X7#rE &ee!wmN`zou컿䐔ڵϢ#dΈvq!+S{`-<# @ aYus(;&XPs7F$> Xf8"Zɗ2>>5fUR6ݢ:PUp|G¡s!{ 3>j>>X"`@I+qc)d ~^ts1{zn@)z]wn}$Z\snC`zH b2 HOXìoVܢe!NFQŨ;96ihg:T@*רc\ 󢮴V-ǹyV* ᪓~rիF&&;Gbڅa,;Wr*?$EH I٥a,H77 JXD\p' ^=F4]J@I0k7KMXOoTN]}_ۓDۙTƱ, ڨTԼ'%Gb l/,ϟ?L>r{g*wc h""S ;<ڐ"*Q\nz@墿?cMvJG_Bk\ix*--6SvSq'qUGmݪ[;K|ب)N&*b{,tѯNo1} `Y§ kA#Xi#K;d:Ew6U9rh90 -'c !N[ٞo'OC W9ChP"I ]NSǕ51PB .Ydv"R`TdvC2'5 JÁ1+vc'먱oI%n,$xq%bAvԱ:jɣ aր G < ~X_I*29f`b G \ftwcHvXcrvܪdj30Sr&hJ #C8+f*6B G€x@}HVã .PM[DOޫZ!98 ڳ*X%r ι1;[ N-`o7oFB% ];5=xPPpOvg|"x5@(mP?U6 {_Y9_i#F>lROa R%s>a&c8h fMx+SƏH4GHmm@j#͉aDp+ X%~H*W4 f-Vr"OaTQ>, .+zMdh1x!`Ӷ2T}qS: AIۉB YJU6/[V9njhma $ bN!5jly8$>хE'~b猅/K`u\ct!iN#N̎NDUK+[csf&-"~@jrᖢ,@26dL-S}G*?{& Y~Z9}21qf%K,d.d!MS,A繂Cul|Ю2I,LnsAUkL3F¢?&JbU.Ve¨(bJ#,W {sQ{pӖ=ibA _̕u:1je!}1)gUQw3UVBs{ Y `D\F`lu:4h mHyB[@7 U2I31Ðf!`& x.$ӧ #纶WA^OLݝnr4z{%F EBoak_z rmq{${_ d'uX! 3M/.VQI%n d(v !AU PkXȜ]XZ$\/=e_R@iUxdXW!]z=~ /SezM:F*ś/N޸r{ĶW@ArjTA#k7H37ѾAEA kJ)cEb 8kJ$ 3E-8Ѥ:ECتk*Gc&8aOħ ŖLToq"8 =^0UWKZeÜV`[VuڜR/J;C {Ҹ)FJ]ÆlQ$uF3^.ܻtbHּœ,f6Y̼~Ԝ^ⲚKuII|5T Im>G@Dh@ljI Y6rA&f+"Eg5"gޜcB!i Y Tgq"z[Q~)dO̎b!BͫD9 QHX芘ej2w#Edl! O!Y +þArNLmLn$=iT@U % aSbFq񄚄,޴AHG\gWH"&X@ mU$;i`# Ayͽc~D?!3*fIQk)y z"~D>^YjN$tqa%fqw%t"| #\=I-CNA93n$QDfQ=K"?.jmyVށIM*/M\V,`$m0ua$kO5ya!&>v`2R3ffc0B"!tSCi'q#d!Q̵-;KSjnxk5>9nؽ$=jI . 7Qbֿ؜d&&! _mS$5q=1AeSƪf6aͼ wYKo0?%P|RG)OIDe"rbS&v8me h$wKnrv&Ҏ>Mſ7! JOxðޡ 3$Ya. 痞 N<T9ĠqhA\Q;E^nLAz:|* )?LڭD1r2,&fnB:Zf"F\]4Ɏ =&g NK=oHz;>w;ji0#Z,2^n$7Kh9  2M޼JpfzwM7:o灇9`+- joz3}d\! ԙb&-v K Z֨aJ:Nىo&QrN &U^GDž׵5<ﱼ;^>i>T  CVRw(t8X7 Ȇ1%JX P})=Im=5\h"ý?@ʹFCU~Fr[zj(So8qz Zo%%jyh+"o2e@Aw p%ьFyp^(t(D M5Աg|L3>O*DqLC{K͵E>z<)iތH4r_&I9 F[m3s$ub|FmISxc:!Z/PW\WM-d0oʺP%跠L=n!cŃ`v(5!`11VP \pޯF KZXGKV:8ԕh33-0H%*bS g`Y" H^V2h+"LooQ%:R=h_U]UD Y|'ԷQm+.Dp za #bj =m)pj$c%a3 h@QjpCkܢB/\;>aj B k`΃kɭy4GQ`>:WЊE.aH Z0%K/D(l :WX1- M\"Jt DŽ0-꛰&HJMĊ'Ub/>jZb( s)ϭ[]F eujx5Øj^#Z;uLi|`\u:vxF SEV[#ptEa%y.}Ĭ81@λjspNщ%n_W!& EP'pݷrx3;T 6 K[B[wLn@ Y+CW-dP)c㆑<&-۾ (bgi͐O#2Y>u*Scƛ%t |_$e woСqyM&G kA?y _Z-ȹ*I B@ySk(VCrk &2bSPM=DbːqGM{3uY>űj"j9a#:5bv|̩Ląr,&avlv'$|)ݕU q<ݾ k-y6\1SthSxOTeEqK \`Aβ];? Ujو6h'" [\W_s]u&m Z$` T) [  ҵIFual]| $h*p#C:Qw'C\`t LxU)Tt'J.× CX:"AHAQ#M65gXKΐsnک938=kLy_`Lunߌ>.d'wO L;ď6DD?^`.uDATTCP <*_iGZR$s Aҹk=# *_$ C p'% t'틯.j._xxBA(0P8e$E3D D2T6FMF*i$# bZfc5M`o S܀N25b5N^/IWZiBAXWORR j[T΅*Ԩ77Q7 Nm|iz)# ;N54OfpІU?Nj*i#.2e TL,KV"X +ī0J 4nYDl\yp~z,Bd0G9(͓h 2?2Ga  _ڑ 0l39w}Q?؀9*=GZAP1k~@*/C=^ XF]ZYj# 64[kY y 4ZČ_iLuxg@"2jV@^OZ{s~^U+Od _ = UzΏN~9ihA#nUBfz"BG:|-) WVrR^J]Q,^p XX;0?RF No1޾yc?(!<,;d~V' 2 v˞'Vz r+ 5/ Rp,t|PvI}WHR 6#UUqkN2;L8J\n9Vj#~fp%w% qJfsS[6t+hqc%2;Kk#2DE܅3f)?1cj|LN녂׀5V\4ΊJE.nI^B"~ *KP3ptPky魏:f"'/8T5ӽSqPVQ=piyF} TVqJ$Pn4 6) ?׿)PH# q% jl#ތl/8$2HzfmŸ! H;m&Tbq:#nߛaϟޑ" bfE"w3M(ן <n zOhp"G N:m}P-*ZnL$ݖTY:1WW=k#5هElڥMm7o$>bjgɏ͖hmͩ$a Zs/K~Վp7߆fH'-" 7'Z hS#qS7ߘlTTΫTNE9%ͷQSMEn;Q$J'+ Ei^T#v4VfUFT,b:d˄~gLV".jNx&C1bqjИ#)bNc f^w}|ԝ~d!|8)Oy\ } 9WheTû2ABVk3fo3 mϏFl| )07苋EXhr"ߎJJ j.y@iM\xOP1B4k_P 7ݮg2\ fGmZ$r92&g?wEͿ'S1| q |~wq7%M-+2_)9 d vYh"3~@j45g])1;c'_9  D]/x(@6W) 6rnB=@[&sO " Q^DWA$8 h 6åRdH]!0j*e#tfI'"ݳ` ukqJ{+h$xaTj#V:nhh".d$Vܶ]1*W-0B7BaV -^ݹtq*x!֫H "b[ ڈ%d a!--KBPŔVAܤ2e!:hVp /z3Im_.1Oe6vk #=;5gN"v*1|cj%#W M)n$P:ޜ:ߔ,F ?E_ʘ2Ky}9g9M˯t:|h^Kl.ΐ?!s`&B7gT6ǓgesF{1f?2ݯښbH Ae]!Cl]WN:|Ԇ~@l^ ky8/Noݬ%67ZP.]>etâ.A,=kz})Xhs"*)>c;Eľ@iתxЧK}UQEUK _ĭJWJ' _4u\J V2JfKrğ{o~%U*('@ ]8 ޹^Vw0;U8Mh\CtZKGB+4k#ah "a8 ?46©g묲6];dcC!! j;x)2 c Ur]Vcv+ӗ+wN}NSEgv9w'lܛ*$3Qyp(,EP6a˔ AZ]t/|_HNۉo@Z?V3cf0'w2ebُHʀFOk#ӥN5o|~/eT a5QgCwV5QPg_l I$- # adn!z_ySjm~x$Mb KܶÞ:8iC\;oBSJSç7Da1v-/JKd,MB- sR|K4UIǨ(^ r/{P7L^Gnޓ8LZeIn!$񬉩P3-H7?Aǽ6\;g/"paz tFѐçْb vFF|k] #,-ٱI?6[4V롼,. TE ]- !%` FCl3 /_X(?K  Z&I +mYڸ#lI $GcPm4!\HKNn.dטG/܎I򲧀NOo6Mn$$ G(Pm .i_F#.`Z C/O@o_Buk[O WE3HKn>U$!g%;57gsӀћ;A;i3!`?~>j,I0,@[t0n!z`Gfenrir-1.5.1/config/sound/default-wav/PromotedText.wav000066400000000000000000000207541317357605400230170ustar00rootroot00000000000000RIFF!WAVEfmt wdata!p q&&!&1#4w BGXS_qИъ@NiQb;X %v-B'r_` Do={Z|RLTHtgNm9l9 ~F!(O1O6Z J0DeNވC|Q5qc$4aXSi7  f1%lcoYJR6BTGEDhxހtQ+b>   !x-2t)qveVm8wC1aޖE"^ٖG1Gj jS_*4-Z .WP!/RPڼݮEI a +4-; `<jZ .n_2aҤ#kGE[d<8 "4d:" ;K# KzyJha[ޑߌՀ@ݕ=K X!#F0/w" ai"Mz!\^QeL: tB"6.4(" 3G24wyu|)oN6 8'1;3$$ JV1I :Y^I؟6~kRf { &6-6izj  5m.)t19߼Oo3k  ,%/, Y|J ZOO&w*١<  }U`,5'8 _  >*K?BjGk# %!1,/%t  VQ&>M;Zx4>  `!U02%#  a ,\PܑA>6,oQA (|*c1$B{pQx '6GfxQ0o7߈~GF 8$/d5$,^ I jR'  m"|ݪclM ;,&/d6+5 )M ^/kdԑX& % $").D-a_ 2 } rEN jZ=@zLpFb&e12&D OLL D Is{1MnK8 ݍ-uO  o 8ME)#:,]xg/]k=U3.2Rߴݵ U)o 3 iX$n0 3(<" G  RgtX-c q(}P-;h&Gv FEP yW:fH8K[% w V! )$t40'  # @wU)6( "+7}#'45!(|Tk k"O(#&p@rKb 1. m  #.2!. * 3.eXsv݌Q_ Wu~YF7 Ak#?6K6 S&J12IRNz? -1*a80^c4I,sxd$r{nv :/k<} K[",,1( 5Fqm%!J%+T A] )n-)H rdH V 9pAb3>0  xR%A 9#Q0*V /A =G$25x:v߀G7WJ   4 '-)n|5 &+ٸgp'֛:!JЙ̆k*:*(8x8KnA]-_ y J##ʦd&!zs $k14(V@49"+/ 6?>ղQXӞ(vG 2$ 9" ZS1#.x ޶CG zL{ߙ 2x %k!$<)*P,'.w #E~zޅdB՚Ϫԫ1[kS#/}BDvES?( C K\yW ˡуҨېd;!((wOM, )"+q, I &c~5q z[:cW/'s# Oߎ L"YKk)KNUٗق#" _.]&& !(A..,s'h+$s /= OSE$@ְ]9;ؽ6p͏tK-312]>;c,"jC  ? %UzQҮp[͢a&1"N # bg@#a#2#, zJ!0ti1ۍ!~ AH_|8L _H`+ 2%"=Oy*߯ 3/;"'4B@8 3+X^ 6 Q{&}&,2KҼйҡژK +9779-3'\^+ 8 ]^Kֶ7ڑͧɲ݃9m_[ H:G9.5b ^ 9" Zf?o*:$Xa"  R#:&35+(^O=~z=w1P&1\W$y6_uI|3 Yb   9)049*]8;5Uf$F|iEJ(3GZXI0j$`U _JEg4؁U pwv۞A W",R3+I85;5"F<ԅܲ=y|cl %12.+( -[Pi+2 'Y?\ uPH|  mp!Y#D'><]ҤW"wS &5J!)3u+! QaF $ nryך+݄.F5s@08$ O  8*9DC4*_ ^5@DYQˍS9CЭІ2z.&0 3hR 1@C-3?-%> DxO7jҭJ)ʶv6Eg-S!ug"'lD + 1 2x w]9!v[ q!)/($E! a,ڈaZ -AX! VFGXy)D.EDO+6RCk  "^XfB E]̫+4d5#4'':BO"b}-4Z@h:0, ,~#I"ʙs@c׼4 l 8v+.2,1#" 4 n ,mxն׭x#4v>F;-.2 HG;{gnK.-\:"*e28S-"R$* '?.ߐӑh,̀ĦWs r0F==eITD!M w)#GF& έ /m 7կƬ`I%2(/( W#+)u,.3*T/[ts}HTٔ޻> "  !/50+%! K/˗u_ ݅$U(%7EM2!ؑԬ6 eKJ}y-e 2 :>GE)!#w ksБ·ڡݶ!Οh:t~  6EHIhDB3  yIp 5 sS(?#Sq C.f%A*3+@~ n1ST4' ^"::8+V#  P W~φ=gPs'11@$ `b!:6HH Zc ;.EVcO:"bIt=#P֐rc_[RL*>MQGg3FX{U{ 3̯ZYXiշ<5.CKn!'#S _%,%;W Qt xO-]l#eu 84D@C*70J@q+20 `+8A8mѦPmZy2!" w9(7n5H(XhKw[q*b1 JU;VK=&>R _?p{̸F}{ϙ;re T#-k22&4/=CK)UIR2H 3 {#ōqG&-WevĆoQu'; ?Y9m4@9N>:!EI3u4:"1kIßH \o)Qt |tmoMӜ3 ~ HXJQ %L?MXftnAsrʨVߏL+NwD ޭ u͚D$n v W`B]q o!J:$ V$.t+&0ZUuGUC)U!CG84a(?DkU} V-uJ;Wjh!.ܐr# u} ne`ˏ,GI5 VJ=AX8Ɖq~ꡤ% l.ݣ N 25Z Zn #a(jv` tȎ2y+0HS"&t#xيC~'"A7 Q2*#hMT@ 8_8ppQBk*D^9Ϥ>8-7A,83s6q,$!u{)z1¤/(5u;[8*, bjR "\ "I{ sZ ʮ| <1QH0llt`v%Ԡ_X+쫬7I 82cb5 lB0 0$t[׊ňY!f?Z''R} =1%v~ kGV6 gr M4 /JPԟTn/ O]خ+¬ney>ê!͇]0!v0L=["c9zλ"0`´ U:CjD\*@W&U|)༴P!mhGT| 3*SDl zfii`"UՓHf28뼿ՃףuX`\ᆳR*uj8;]TKr [Y01 \J饑Y x/ws1ė0\i~q۠91'ާwּ_3ѤH4Rk)r+(VT{?(8Ő~׬[\6N~`{sY7:GVyU%Jtb a~袸^/8)m!.f5.#,V m Wp! \j}& ݷf`COb;膞^Ȍ1H$NIGg ؑ˫P+( P; j@_ ם<) C2*sW^ѝ0TWs4KVMNY`oOr@G 8m{bP SŚm 0W߭ g]G:   U*-[]fE |W ֬t' LO OP DpaY ,V l&?f, W fW~ 1 JT|9BXgzGwmB#TMp-{m$dQbyyN Hd](WlcL)Ж$u! o&=B4Y,XE !j}R$QPo˄[Fv ɏc(#_?<50X >y 9Y;%7H$f߫ [$B#ߜ+ ^e!ʾ'wҒ#y"vk!#T51 vg7 p }u'UA-m::<4|5S-te.aG44! * $04,e0@1YV6:5mJ*{ d!X"{\A t_H>UaHAf+B uLf* \%#)J՞>OqFpf&QL)6B!c]|{Wu1E.`i {4 lۊx,&=1yZ 0j'HNSC~ah.XY^c#SKkӨkFėbz9גr(kc +ᢉ܉3tڗݴXړCyF}˦F( 6ȣ'#ν7" 37 -H8(/ϑ oxͮl%^ڄ˝@8GT"""L|j5TÙȵkн`AT$y-Vޜoa'!h6qKM Q#x._-Mbh';!&k+B NVP )C"C #xWRA~h J2u-L O'&;":ɠb #/"g 8!&Ð"zS_S  toGC9$g=AAq'  [ 3Y{>\d1]'@'T~#f Q ^%= ~i#$<@${!Û*5 }eG ip@رzgRTS {*!5a09Lh:3M.}60Ƅ4 m1Ƒ( ͔&e}-0?27K,9A2V'/> *r#-?jlOG SwőD۹e#:Ti?sk55f'#v YS~J+n;fD^/<[_) [*n ȱ?)ˬ2) >h j t} |` Nsm6dj b%YHje<_y) ,'9 Uf-0/(ݾMsMv  e 1 s< +I3Fc^vA g:E @x{?9hg|][4p@ԉ3^=ր̖sHiР7oݒx=CV6݀W⬵KHVU3”ߐ}.@#RCwY@y<.kG3˄Z_  L9˂tĿK4#3VNLbuIif_jIgR20Ep b$-b#+fE#1pC_U F]) =( iS p)`r3Ծ&r Ubukc a74lrO܏W޵&|!+79kI9.Т&Ou,L@w\:C] lt7ROJ[w:y)W /9NN0Qj ^dW|@k% k% C0@ 1+ Ok sY0{ Ir2'j"$@J\r5  p`"JYs !ӸJsdϓz?lrrx3a<c?#zgD^w `-p%z5dK!% |*Z9 co XZ9 1ZVg)"% } 7mÀL1fh- k|n ~ r#poTZi"V Y[S@qy#z")K # >CVk ɢakEVh*OFg $1D 9.#82/뵯1WM3[/g((]ZD.sUy02OK3{757d 0C%{5"V"ƕ7;2Z19I:1Hgu4(j⊛ [n%NvV?nꌐ L ]Yfdޓ4$ՙ < grW &&`4 ai}%t$o dT 3 y-d50OrHrn$ #@V6?=MZ 6pMz(iN\re,Aur0P>V )]Ɛ O:g  l%D*12kg%G~7OkKR:L^0נg5|pڲhBb!1!7˘gc܄a=eIO/ի)Dž}˦lַH짱:jG Fw8 mu_N G|׸RuKs܏܍YڀCm%{FE[*~Ă3)ߠ 8s]s&CvY \`H~| ӹv=Yh8(.3t4= &,¡(/w0YeC : j K ǔq9R Lb󄫥|5٢Q{ y - sk,j &t y^pZw ^[#RE[ PZ%!HW]l[f Wk s3ԃۦ J^EЌ[tB~-o M.+_Lz7'o 5o2}; pa!;#%>K :I[udtԲZCcU/BH h kaW]nBz\鈯 詛M\q(n  fU33=zh9~c,uwe gfjDY+#v!!" ,8~<1V~2l¯f; :)fg 'F2u7S6!91)/2%2JD-m(*@.0s4>7 5 \-[_$#* x@hgy!F6pRƼfus ` 6UF2{O`552n!#u=E # Il9en&nE'&s4YgJ:% M75BZldBl&*Z/ [ r tL_OQj[sG+a#HEuKRb̠ 4fc<jMnn{,MU6Be1y d깣 -D )}=K2t@$~8 qLnD),7U>)W UP_Ed9m܄Y/ݿE *|hm yM*r%K/M"洁}k)z'9\riigڭb!&+f N )\jZF;孋- iT@+F@m}9L4t!~(,$׿` ~Es-d4b+kI P f;('Ivه L + YE , .Grb Z=*l$U߉(|!$}i2}*# *:=A\),QI#V8I#ue&~Ca  - Eҡ~3u 6bh#6m hi!9| d D1_ߨadx0HWX* (_m3m `W ̧ kvC}^^W4YY#TEo  } .Szλ:ߛNb-_L?B0oD b >0M^"G h|!* "k%`+-xՏ mBd DoU7 TC ){%3ڛ6}i40ןC0H1/0̫+(J+.ub0^4C66k2*Iu!e>ebGC }:,3 ?z/5KwS@&dcߊHIUYRuP;:< \g(]a;؂0FrG ^ [ w$BHnUVru Fxw %Z>bKN,.a-ZKvi*y:?l7G CO'bbKfuˍC.?3ĶȞjdP 1K٥ N  tIU W@-*[Zu(W1%aLTѭ";IԿBw߲IV+O0.~NVx3 +rhkW68EpV4I2 MHQ=ϓ+?8ŵOЭYՓW D)$f J>HlF#'T5E37rxMyiOnٚ$mͨQtfSܪuآ^EQVɖli\ͫ<h+mr g*g <# %&Nc)P#D,OTC LL  7~ B KuaWiVDG3 třrHUṳ&`Huy wO6B<D|~_Yh]&d?mxU=}-(= $efl~h:{/D4,kk^^ik*>\=4ImC3#~uBRv-D^C ̪ 3  6 2팙 1c 8 #!!m3֤x!"iq[x"Z / {q_ +E[1xBut; ї|! [ʠbxj"bV gw F| acJ8{ En޷1c `n=??DpB{hy7t} iÍ k)O"466d@ .s?ܹ ?0HmO<  Y$4?z}} | ~m!* Ɓ!*f4!(Vk| 5e0jj61*q^ _ǔ*Ђ3s%5 3;t_0@|0831}/C+l)u+.RE1dW4490&j:pY5F؜Xl(itkNcfWw | بRCO0IWaMkF 8zǘG䫂Z۾e^Gu ]|@6YZ0M)GI& t`mytG1mv  xsܡ8 V"Y٘x {뢻`zqgPX"-fp?;Y؍ Ma[:uql޽3̓pK]uޟ=3\ H{s7"s4&4 ɟnT~wp@iթᴺIG_ׄQTyߪna̢qZ 9Q;K"NB'OX;ށ7f|φ7ƕO-NbFRrʔ8,й>5iKD5Y(4 ~ j!(*&:p'd4!.)#wS~L ֮ %Aԫx`*i"ZPERD+}r֫PE& EGTyzESd~Pdfs_ņ_#* "O {{>n@ 9d9 ׈[R2R.i񛨔Y'q<h3Xζd+A$0Dh ׫ ' l  uL:H O`9/Q`CD6noHήx { 1umg>' 8V Y I/u@* 8RUth,`p'2 "q!_^JB Hwt9*IØj;ΫD8! poM? nJB ejNZQв˝ŝ{ 8LY1Cj^tN9e^ LA'śZlTL iMj8ʄ  )`Ұ>7uh hv F@!n _ 1 5([P}N}4DM _\!/+R2 @3U1,*0:qq0Q\0R~-Tz*h) I,|T. 1x3S3RM.&{UG]zmIS*ka7RmOI;{ phh$S8z)uW ]/o|mr?m]/B ĐĘ/ |\EҔ'CuxB-t[o| { N?g% c?FɾPh n9S< fD\sv;nua\GTQώn609!Em q/1qb.E6~zprf jqwIM $ T?砒/]S-xmg4Ѱ} T&9M<e^ɭ옱*}F޳0 ٘)D-qT W6@>7!x h\Mߴl8gTv7? 6|Mh*)P񗐂ja,+ 2t0{QVWѺ_҉K ف"zJ>zzV]ܛR8aJl>+Iߵ$ҹfk㪡|׿^Cգ!qǒ\@Œ4K}}>)mV I_[j[t G!&o%6 KB㾢>rQg-n &^ > vvْhikk,\p 9CukdG2Pb9GG-14*\*<2=g-z $j? SH(H r0cfN0`Bn=rt70y2 k;IfDW^ ]r,u+_ s 7D&0#݅cs6j 9 8 P' n^DX 1<D׭=Oq/ ~06j 0| Nũ+9i~ QZ~E3{ ;  v^ I^y@'xkn2 &_uv p1jĎl6Ҧkvv Ñ_) TC G7tSuW?5)tdKf\2Wb*I}.X}t6B #ŧ6w ty]u-ש|ŌJ;Ǐ q׫9xE oN  .v#O7r"n8Dy&xDp#dqH{\#[,4 22X-1/'(0Tg/), /*U*U,P/i%1RQ3@15,&$7+{NQ1K#&kW 9~Dx \*R;mHse'wWV8{pJNa[+yp sa-H ڃ)"m1Zm' p- ?a"4 "Y@ʰ] KA((ݏ#!+*@-QW:[q ^ # ybk19_(d#,X.W>26)7N 0P" Eۆt2~V0Ӣ1%NxN$^M>}dI9// !]goT̅VHL&CGHɜjppӉLm>SGw  XsH AA*Zo`zL s̩uEի# D7tWa|(2=tL:X9{&CPs#__ӕ93oG9MKb~ER񽚰`%K2lj8f.2ipJV%DA!0f5%d&t# \u r!Qu&o< Z cLGGAU7<ڎZi(='_H5>E5@m"wp{\u쳁.I~o~s'i i]sxRf {Of7# w"/]s-܊޿(2:޴#9*m$~/'%*7Ե᩺ 8 Q ' 9Ug e7U>lȪidadQcYh'}I[;$v ,g jxiU c.jH^5H=!~JwY i@yK$IJ PWW {&: |U3o o:$ Բ C\ oQ_HwȜM{ZeØ sgt]:(fV.zat  Å*Rɑkh9!\Mq֓Xy9 IEy qW bp*ftM`$  tCg o6<@t9p 3$xs,\1Į1su0Լ//l.y+: *ʮ*,":/N1$m2/6C*Wr#RhBl<Z@ @- X tk<1JNfR-3"^] \!iiX})|*I--&.Jk!9~X(6.:Kx6:b Khu*48XmҼS@rUӞ:Cc>gg-,z~Mtp !WQ.uהi7P I&jLwy N~N#v iÞJm0Ccvݯ2?ګ27o3v7cKngޟ]ۥA̗)cǂf.w ?=?G kI*ぞ i0(W[Z\ @-iP_R#d7-J_n5ZE\8a$0-K !!$1!2%y 6 0r?+" j5 VE qOMǔ%p:V0 18HBd?<⠂ 6E ʙޣV󾖏O$z#E stXb]WnR:B (84 P6Z+FO5|S.SyCު(Q,2{_}0X )x- p  ބ rDu{ Ƈ ܲIm[pI w$댯ڏpCd \S(t+ 1rx%A.bg.t" a2!sfk 1Ue<XX cE03D? b0 )' P ~ނ93?Mov){Gu[Byt,J>[?IyaU ! ¢r} ȐxqIC"ajN=nM.{<,VX"{h-ׅ| y yl!J g&p/ Ԡ%1(-݈00/=m/?/+}-/+=**̋ -O/Qu@1.[178.}(kG"xR0hBkleKն y6=/oL¥(aO(l?<0VdX%*LSaB*qjs&BjU%(G+֠3r;sI_v 94%XcO†'< 65,ML|Uv7Zpvqwx#A g8~#ߔ2կ*^XG cD( _ vBb2t9*T-㯣 O4cFEHP=V'wy?X{E>8koBOܱtsW,s'!%5"1vCSmqa٢ [(U  K/"Ġe>í|DfҨ ĿZ | 1'}V熓ꕣCo0E}ExGy_ӼM7.=I/B{ͽXR{/Qp%ѺD~ڧ^%*w4ƓW#"eg򘜠򠺧'q~@8h]*K k' V {B ej0f;( ! $Dpd! !z~E#13 +L IkC`_ Bп`X{2ȉ25|wm  y/ok RB. HC y;U)\gg 95  HJ S,\Ss2#*"dqb,9ipN{QwhdArh;hj Ř X461fII)r6?OcG xjo*.G`JDl~s: I ,|$LWa`E mrQ&,-_/05n/p1/ZM_.,* *v0+%o2-P/ 0(0?,ii&zQ!@)vͶs/ {S#{ }c31sڒע5zs@P'Ko4h[5/XTx/ݻH؈V0O}@E8=|ەsNNtJlgbG]n fV^9h>}0¦L%ho+ 6Hy&o@[y@tT'PQfI%C LJ5FOU/#:S/w%R.aZ)eAdluE<"8VBRp ?>X,}gގ2`pUEBp^X;q*|b5w\uNjuJ4T) c}P`Q(`, ߨy4oTW !YŽ֘cٻR'(^NA߸.ޥ[6DcQ&Ul!2<߄tqq-_1/MGy<.v=j)Q/gYGL a_oV>6z> =R}WH!i:!O֦C*Uvٶ)rF 6:' eysDOdLVѡoFkAoA/q$ӈc{2A}-ri Dl{:d Q[j z^HE;pYSfðs2W m_&;l(9WscWQ*Gv]9 ʐOǼ>n|vxh 4 q J ˸lS”* C Z;D.S -}"Ee- 4 y ֌7 W D ax4&7w~56VKDC¢(ﲓ#orh 2"<;oLaIl}K}o+ >6h\83<},e\AAfp5/hv-0d>. 8*!% 4a܊d#Ԓ8{ Kj<4  ?bپx, ]a64h ws4:+:h^袈&Z[jFBd")< ➙'u:-:A1hFQܓ4!V6)R ]_&K @ +sS.b,4 Rzׅi0C^bc#%g)O-dV諴2NJld$hVCa ;R y9=+wI"'5Ỗ5H*+KWl~Yy $)Gd*'ӊ)sazZiЂiMF\w]/ Z&_(@Au,g YyGSE3j f}% _ R @Z9 MV @.;&2} ot`P(pwHerXk ` k}W$':gJb}LQ A Ь4O `  I{; `* 8sDU[*[ Ӑ p u p3M ο>2&qb gAjpa)|X :<J!]1r?ы5:RL, Qrso7`3AMKuh7zn&5ugϡN]*Rw/H  |  z.i '(s,\..Ղ.4.,<+;- *)*T#+LX-.@k/-Ih)SA$t)Drl ӵ T0  !\Q=&M^#Iؔt5s={!Eh.tL&;O8PtM\9!$=e\5Kj_=~m3"|qW#U1y\'}BS? | }GN] nS 7,{ H?Bj8"?h΢^K97 ţThue A5_ 4]Ý"i*?kJlF50b^5 ("k5E"OEށDi'p[6+H⽝"m 㰮*E쵽JCŢq)-nv(cRRm1NNKzauד ֳoKt vh9Ŏ)ற߹[\ > 驻xh/aq?㹶ݬpDAqERwGH\DgsC2j`4\Af$( Sߝ45 ;,c@p(W q=0iZAS3#[0(̦mt)AJ@g s{N?O3K$Z"I#KY写c+f^&潬!h$j)ժ@^0o0q]PVd(8[CLj} 2Æg0^(N8t2v܅ 0b7qMG&j=$JԼm4x^#k7-I[ I ` X'$ TFQK@WX8sg]{:/\vSqCq@&A0KkO9`( ge|FVфml\JL VGfairA RF k2(" z T#}=>y ?< lj y 4l Z41JD=is<Z*"ib&q` lf!8%юpYf>u >#rCbUh2E+RpO8 E)z;_e˱Y^ݛ_X{a>.-x qP] £# `a2 S]nf ASk!.(G,z%.O.HQ.k-5,Z`*q)~8*U+R-.@.:,r'(#%.LmWJ+V ͝0 UCœ.Svt核Pf=m\^|:v NV - cx:ߋkט^SjP(YkBq7-lYy&,}joO!V^ L[zIV6"Rb\I6sNHSmx 0V( tQfPjΕl{WJ} > a|}^):?{HuZ_xe7?^GTQ#wI 6q=U =:~-HT$j zS |Y妯-,sU} J( SV 5# U (8 ۶ k1P|9A dV S%6B@EJ* j 2i L IY3 MU}#f9GHr?7Y[~)⢈3}2ywu$Xl ͠4m1P aRUꛏm~$p(}B܆EAb_j" sL#;I XM >$utA4mlFlB lILdv"8X(+E,>-;v-Ӈ-\,f+<*$)j:E*'+h9-=/.O-g*@&."Ctsⶬ޸:9˻~,U$ FB~Lſ5OOZ=B]rO(6] G\]'ՋMu:D5]i ?^q{EC-12(g2yk4v\,WPE)Dbn^~n ׻y 3 3qPS3f<pr/E&@i aB Nl𝹛d 'bS@^kWR^puHr\- 3MBdGZL9 H5g wXj=eT(i4֣-\ON&L49\ cN#I*H"4{ s_Bb{ `F1 XעMdؗm]f߮hbc 22 E8>PN9 Jrzԧ{h'vᒱɜ~ئxRG<踲(:y)t{dmR J!_Ȩx?`6; 4;[lJ?6 iFl8۲&%mJmU J'Eg;7=7Rne@;匽Q7r_F%j};۪ 06xhpz_g|k$1NAs8\ HRl#R`~1AwO$t@uM?H9F*g:~:`ڴ#~g;SO?~(a&Z@$a#D}WÚ.  &  Xø -φ q qTB/X;ӢZ`@9ap}tkE0 *2@wEwKB,qˌ Xy\ Q--  IV 6}` luc yhz ]meFpE`Qd#ZYz(6(S6-rRi.(2 y 'QKyf( d.0#S(e+&-T-`-1,*))RN*+0 --'ʓ,t): {%A`M!"ec?'\ uB] E J@߁NF,F 2^Jag'Џh`uJ)t91@CQ9>&aBwUPY(*'vIe`+Ƙ7|(z$.ujfw0TT>?"66& 7 *;I]&D*BHDA/}% !0ŒAlY , | 2c-h|l0Y5h3lL /ln ̺ LCzIs|c?NW0:2%76yYhE|荨;sx`1M=m=5nR*ölPE.<(g7s$ə_=d \Vdsy %OJcn((HF r~IS`] ,.WgNjk˯E3YӕOIN7 ʏȗ.Ʀ";jl# اw&QE7i^z5@[Dh𢐬!:D 5hI[^#xC5Ҕ [㧹Jub ?>B96:^o%9L!}WoC#1ORJsY4Y':I#4aK-kTrx{t2}Wm;N$)࿬ۇ@W_ײ ݔ}.㦞j7:|D2-F( ~Jn5Q %@:LO+ o ~n[{ׁ%ĤȻ9AVs|2?#~e,BX"{9~\z=(: k -EXоwE5fpLT$XmE'&)^lc"oߛQqVRБ{obTk!++?dwIvs(ހjj+ }fjpf{ PL $ H UB 3&& `q@ Ʊ&ҀZ4dxH!1\ | >X'i"{|a#(OJUߎ!&M _ / x G   D_]qe)Qb > 7 . d} g <u nRYV CyJ #{7cFgk4N@#i ؈* ׽;%H (FUiLާ/13`CM75Y rddK;]e^4i .y@XYr-Oׯ B!@$(kO+B,],ȥ+)+3G)QOH)Cl)P*2+I,k,9=,fw*n='Z#/1@&xr8i!|n@;^H ~ EF?~}F̨[ Ԟf|AP e;S ¢{hv\O7w5&-c&n{$LUߒ=lea^>?z>NG`#XVvI} OefjVK1J ztv  vYd)@ S&JȔPӢ|c Bpqj؝BMo≱]%T;ϔ6!䄉R]y>!d2ԏMu\`rIF>:}]T㮪V\ja*blޅ 9ݓ@p J|tt* @¡>2-!Rq:O[a sEb$RE~==oC"z^zHۻզ_8F"bw!gaoe8=#/ zd*i һIlx>[(sZ tu  ^J# H Ȟ $plB-A4j%#CpEZvbW/R:QFZ e J I|pAt?5{H TLzQ}X 1 EA OQ  i V Ty  C k@Q @2 m  7 ] |xE*ܛIeT8Z΀!Aߢ1Jn;p5 5i!? ~ Ƅ^|M2?IeH~zH R$1W)oҖM1_W/q8B8:VFE0 Hk ڕQ` yZy5p%Nh(*+O+W^+u*')G):Z)E*]++&s+g)x!&,i"%[BNH'zH\` +X6 zX=&)R#%!ۯfh }>a;@t-1UW[g30V.u 8گ"9+0H9;HrEuG43ڍ?ao utyT-]SeLG@o=LWfwM=[ɛs3h]TG$k޹eM"q2>7XBA ,K7iB/tm. v3V_` g(Q>>$@8)l޴لUOܭNG$pP/ݵ|\ ['/YS#]pŝK~IWe<we6 =~DEs4}6ܤ)˴>[~:MHA~id31UiQ R~ <6*rC{hZ !Mr){Lާњ Nt٫H] @ -) S6m3!aP.✑>|~)|uw,'yWYJH+gIek*_u23=!γ4ɯAwha0ML]z42vp9b&[Ľ^^na{tN!*ވF#x7 B RI2 -H qi Ӵ½v[g;@H_9+I`0t  :X CfDkOMd[&Fuܾ5Ώӯ 0S  nɛz=" ]\gY w.VĄOxnc^:8+V#j2WB7c|=yB =nG R9;i<vR T 8$:Z3 P%1p(*:2f+a+fh*f)&)(uvH)2*#+y+*[(u%r!VnjkSM)QJPvqGYc _4Lˉ.]T뺜鞄!w¸eV{LV޸,NZp8!u]*_@7kkL_^AE5%Tqn`pyw{Ȧ2i*M,tTLDȓZ~cAx6yUce =~g-,yCN; #_Yȓ<J WFU qHE I =CgCBt/ ؒoO4KwH5h^&F# kqwzn_!glmow&3% P'jǞd-!丏+2ֿ>f*<9? <6PGo:{oW>I㟴 ^ * !x޷AiTU@[h4׶qs\4jUz'- vadG[u]ۥٰצ+{ݍ@LKGz_{C0VrFYwiLqXoL(1U Թkk_Uyr0 ; 7TYva 6z0)$?4n62âYć:F?{L^\\$ 찐D95qR2"AoUvzL:)rj=:\u*VSt2>"O M#cX E!{6 /N /reo,^* zu`  *c ࡒ 8 B +,^0&w3 [fTI9o8N=)Q'8nm 14 !zx4$?&{T17赔J\! _0 $ J+  : x oL Q  `j/- ^`:9{; c`F $ @HF o2 hݍOAV,ʀs{ L_[!_? ;˦tK+u3b(o=XR`v@`:!_[S䥽>SuGFyBh?!`{@Q,-`E&r "NFpPm5{8CFy,j {S *-!j#1jWp-?-eKm\Yʍ 1 pq NՃ<4](]crEu=%CA*yR*L == (CE4䂌(2s)Y; A! rK  SU8 bO  VFxVc,C i. f` l C#ɏyl= K( Mwe V?T!toߦ 0:O~! `AKCH(Ug^%nnwSջKIF"2-L?+`Ip?syZ= Ff ʵJ)Uv~6$f 5 +E [!%(`*4*d* )V )M((e)) f*sF*:(NW&&#IXS}:5~ G* J au)D [+TZ _킫xJ t̮Gv7ĕ;!AY>0GT{`K^{~<[LL3'p0ϊrF8ʱ?4!A%<% x[[kM9;#Vۨz  8Azl d<d/mW  V1 cIiT+KMg{N!j}HgVaR~+s"_k.2ɗ>/x0r\=02l,㓙RXz~\װ>GO~h{An)3,qK:Q!pn-HO~1T5 iۛEy;v݆ }ߛͰ`6GCd⟢ru䡓s@9[+3{K?0dIL0U?,wl$A50JMPo!fNQ.h0rR<\k xOk]+> ڰ\,]3 8a\06+g`j %W6p$BE~ZL /Ӈ h7V3 P/[O6EB?c /n=KJ/BM!W5>INI8t?5K1Gc*>hgS[ HH=;RyUk\]HerG a&>2 .` 9 Gp 0|mE[CR+,/^ " ̰G i< z Upf{5`>:8G^$0ԃIl 6 / Q 859 MN ֣h K' TD 3 b\@L(t  [ t Z N1\۳ۂYJk=T 0R7`9,3y]f pN'ZOU  e7F/pSF/fg?Vpt0_FT3'ri5# >oGdRu ~+I |^ R l7,gryt ^9 KxU)g9 L2V*CVImC6I!8bu>+ c}ydz×ً0q;LQuEFPϙ'ROJwuVN8*]o$IJ^/X]9U 7ǠVbߧWR܇!o!kbzm .RdOG0Wɳe7L*- 筢*{W$RTå"j#|oFFd)?r~ZN|(ݞ.9eyx: qOZaS+9~ &z Ѳ 2BSE!'J x0u=&NǣdX*2v`txIucEQT ySM |?^`c [굵DlF0ZZ*W̳~WUïxMxjRo[ɆM2o ;8ɵFmIRG;a-ǠC3x9gH,oSvsƞ[TNZ{ Rn@5B# Z ea  Qbܦ8)4x$wo{rrMqַ`j2f ? yT ˍSnK/>8=ZT+2Hl.Ր  Ql !D :  y 7 F_f X6/'IF_O i K= ) O &Tv{F,Ba{$>kLZF<#/5N GBm\ϳ&+ / Uc~yO 3nCC<3i^sن2\f R}vO5ndgWXvf?U Ŵ(e.c9ES ?; ӍqRU."2%9"(6jS)qP)m)(nH(n (A(3(u))(A't$i!ng9Yi44fSUBϹ40zxA4}p !a1WB7#S!w[`}N-{J8yI>MFRp% &Қ*jqK;o.n(T܃Z{_Efd~N TLOI6]{9J5ee@|AMK'6(0,vӠA ש#*Y T+ -J/5}4-:0v"һpB 4FW@  2q %g2׶0_:?[N"$f焁{/Evx+ (-?gF?Ȫ$UᨌhFfۿ 28>|ټ@ؾrBpF;^GqRRmGT-SMN?SaH eYfĵw}CU,J?"KR7V2E2ɢryF|І4됆f;<<8L T Pm{L  QRJmx\1aMS(&>0Ͳ\f*+?N!Gt^)鹞+xz!mӲِ2:-C50- $"eyc.zUXT1Qlņ;]{% S)u l^J ;g@A#t1c R/-v.J h 2ok&u`!xR Z^ .j׉с;oi4]-qJ ]~LS19%yqX= ~&y %+r.cM3?41n|$~5+.$,6t*<5,:C2d2Nsah%m!@5=%>a{[Y d" jil+Y {-Yi/BzF0% !P@DWs}. OUD&(gg= Nȃ s{%Y ƂB~+M |knѭCN<[Oarϻ%nNaB³4ؔg,`ZtC>7Հ~klºAG;*TՖSuVKhikQuJƒ4OZr^|t;OOLjlak Jizp!ڐ< n6 uµo "%JxK@G ke2.87 7~Q,ܒKºƇ'ԼP4яᣣɾu#eiZ2Zd\7q٦a7~#:\1VRdJdσ9t3nWWYu :Wїu_\dA-Ja>oL/9QXx O<) I`ˍM*2Q5gOlܧ޽|uXΑ8p4ੋtݫmNk7y{H2œџ8ÝZЗ\`>G/G=wW$&ք΍m˘̣Vv?uwga*ξW|Vv@M&18)w F/L$e_T̯ ̀az[: \(n]TBgOW &Yγ7lo0(T q YҶ& |-N}- ~B-}_l> bŠ gʸD[~Ki7WQ7ur7OÅ"* X&e3.U1i*n*(UC'q3eo6-1ôb\x ìw) zsA /dZ-dV"rSuUGX9joCuH6kUm1 :9CpD7^N!\k @sa J# ux)rO?U ٟU[Yh!C?~vS/3ɸ;@!~ t΁/đE[i6I,b)Hq V ݷ ߈N8blawf9"/M. (12ڱ<'cMPIJ;RB4S2)o((- !4zL:<,"wP!qϭjz|+5!{`i ^}Q{ګА{">| "G7q@1EӅ%.r[2͛ehqa t E]"<Y؋P'8# $? $P'yoL_  v l@iePG!?Mr03ߡr3"Ò('! -zk3nE0\*M07g<.i=TDKUtLDU:p-,T885P,#Ѡ% 3','L?ϳ &4 FB+1xn[єjԪ1%yEX.EԧK gsHZ|̫CƆِE o[]O厞qQe-T7aUJ|2Yo?3KoQZ ~$R4@o U&cŽ8mi֌ӁՎ|Dc/fyw1R.DX? f~“Ã]"pW\;LSۂb$v#7b~QhwIV蝥H{3I/GGUȀl "1J2&ܮb}K3*}zHhGky1↴򠡸R/Nxңѷ޿` 4AZ1 =lS2w.E'), _;.m]ipa_Ev7Ƿ#G]Ob0a*vMѓ[3 }l8GDR U =-| *x/q]=j,=f(|wCܝ+@Yְ(r7eum s^ٱM 8mT(Ս cE *BeyO ߏpX LJj6 o~ ; }U ~˩xҝUuYQbE u8 Rq98r-5/i{7:yb 2 @M):%wk' Ȑ!wc$'._&0Y-2}q2|cK 'g2~/A" c( nۮ A .K!/Oԭ 97n p ^ Dՙa`זj 1pd ty5)4$E*,GN *VW/ ll^א\Z)M6_$Z~)R^%0 ,7MÏL# 25(e/"G%!>WE$|(ud/%f Y}, s0o B[ EG"lw޸0g&n&$ƧȁbcRG䭺9 -A-l<(;'抻]E/G"Y&0ގ$i䠦<%Dr^Cqcg(C)aPL#Kp]vHƉAgߣx͊ڇ\:~V?AsA0/!}qs] Q 1A (@ ^/7;7 I i O$$)HvpNχ5x#5@)'DVX HALpȒ"Q*{*0vx(i{H ]8/Z #Q!HM, 0Ɇ-٢*Ҩc+k-i0,]0V1~i--S"c# praL`_~Zl/ ǻ]mZ-D0% CK  7 n7 ;,+gЬ&*@Ƴ/fʄ ȭh lN?% 0 \ j 'w wM߂phP5ͣjBp8Nr<&+`̩ۨO2,kT\աTc|G덈 ݢo=pic1C;02= Zf,ަי9jpyog.Gs/8)"PNpuiܬhP`$cÌb-剽{hm |F+&0A~9 xy36!3q0 rdx i%>r?%XwCr^fiތ\2͹7r ڮ ԃ镾Ǒ*14.9Ѯ\~IK%U;ґNRcgؼM-߄G׾hAE "9^][Hoί^T1:++6k3|}hʍ3|#!c ީ֋HoPȲݹc]S|,&ur\dX&-h!;LtKW"~~bt h'T`/'x0pۏð74F_ yۃJЅԓH#\-pմ'P^ޙyC4az 8 kjG .+  ٕ+! ͯRОʛ{#~:s%?+ yuGRG] -U\+" A0=r 3IW p ![퍶Dįhhӧ5 яX{]Yf7,:}B =+I3_e-Cs/"%0oHpe "`-m"mT8pۦG*}$& ;AݼR@x8-zt'E[~Nm.ԃ ؏  r'ͩCbkP BQ}Ϧ5Zjd W\b `w|q Sh_1Hݕ o&E~w?]AD ߉GC+F:Ld#{5+38)%Q$+k73G~8m6+5ah)' #(&snh-?3ړ(4=$(Km9 VDT2Aw*rg#"Z'g+)n/W 6ט2# .)Z-3=,`F LvGl@w4D/0zf6s;t48N)j!!kmw ]r:*W)P R b.玻&ILHihB_Ne׾^5P r|W;AX   MhҦ3/S *] "6$"/~ȵ #p 4wQf ]d 68 QwV -"(,k1z`/ȧ+t)@,_-z+}*(. E40L9U@# FFzB9_R2uV15iR3s-((q+I])OsTEyqsv,%g6ܡP|Fr:hZi:3aoB !-!_C>ƅG;0Eթz$<-ބ(Z@}|adi4ENBuvRW~yd2;@ITDHt]8c܈)JܰؐF˙Vff_'+~ +fgء9O 2SҦYk5; چNd8IYP0< Sc~lkTxBWRေ";b()-gse k짪}l(~/¢]TwW=N1d) ۘ)ܑ>mHU^e O@ ~m,vs \ y] s 1 & { v5L@ X 5* {k[NjQTcz y6| h gkLFQrDm&..x{ו+$ؾMaߚd6\x0pvQ|m*/F**Z\,A\,/(/y+%"$<&6='c X<~ y %< |+^ ASRCD d@vun a  'Y H8ȍe` } hq ̇ 5 #?Tgh܁O z wEHB)ݙՀp!日S ,fN<ץ6p͌+J/Lԅ _زlqڞ%lCrS-gG\ꁻdEپ۩ש3] ˮRДvqoNl,o* ]"Lb;q/Wo/jQ ]!*k-25=B]C lS/r :S EP y A'QEkVb-<]gM*Q:H/WД O!x"Cсy ɤK=3'k K7- }; R9 dHi}W S2^z5 HIZТJȾabMida\D/C>f2p lc\ +¶w8RD BȢZ! ( b%n77!q&,&-'Mi+(ʪ1925T24,@)@%O#^&% *P/$/Y("TIS0U?O EPM=ƭ $([G,W,()*@)T/z:BIF_DK>L6Y1\͠2= 069O6>ķ-'-O%Y"I >n p!Hgynt(@ʒnRWo^JJ2{HQ] D]}0`fF >h HxQ.w ^zx 6#~,T^0 .O1qd h P;6 (? ;m"If*V}. .,*@+*tl(d'!Pa*.3:2[?6@:=fZ8J_3^2&~w3IU1*@-Ŷ*b*<+9(!L# :@ yt3LT42i!vܲ܀~D6]3ȍD0]"@ڀA,ƒa!d{i?eF(ak)PwI#'CU^^g9I*O% *Aj:ۘ@g6d!퐡0%s⑜8,pD? z+b?]%dƹEe=FUpm SUAq\@*i"#~Oј"ոk.^(#K,ReݓnJ(! =n 6[ z&8Io00r4 l.82dB)?mO:` S6fNquU+uXR/CGѣHwڱym2|+9qIrB88b޺T@e \걧٨f)d/-rW0ϑCBD@5&+3zrJGz:Vq⎇Q@m<~r⑒:]2ZM7掻+U٘0u-1&е-sjar]GqL,>}@rS#QgE.bieЯHLۨ,F?KzPZ*e   ?2 8ko\Cx:e4@sܼr B7)$#nR{q(S,0;Yd%Ne7:G :uRlF#Q2`lRS:}Dn`}<d\ v ؋ IXGHJ,~ba tNy:]3uJjxD&;Sgih5 TY  a68IhQ=pkA 5 _`*}*0Y00g"*PV|!дe>@ MY‚ CLjﶭ³jiuGpilAwrM+wFB{v wdZ<8,  OXy~*Cl Im<.}d^?M6 ԛEcm q a V ~# 8lY" *P ?wgt^!%-3'-G'y&|'rz(N(%'8)A,'0(489Q7-l2&,r)5)9K)4m'%X& .(s);"'$#¿ 3伾X dlt AP&@ 1GM9AUqc>g \!j[P5aȟ.bKv &RgR ޷k \&O1shmX^c5P (mnxX @F}J s6ksk) 5H!#^%N&I޸'Q(?)+D-+̵-j*u&C-#lPI ,9y% K` {f j [`i l} H,l8hR  mW0 "0 /:WhWj  ͳQ o | ( n Via{[l\ 0! 7 6x@E蛷yJvdZӮ'{D$Z#Ժ%۩v5#u绊"! r.rpZ,kٴbUڪ9u̦z֑nqW&˙:}9"zvA[vc~H{><^eLN0??!,_~vD0[t w.-u Oy! ]SY^aFo?:$@]B;1 4Q]g#> 4bʆN1lvضHU݇E_-ʫDZk\(^>ۄwg_fRdgġl~o[vzւY֑5z֚9$m7tX6W@P)?6'U۫+ݲȖGۃ.ܓ|l~!ߵ%ߵ2܇7Ur/ҵqY0(9dk{٧VOD&/iS?{Cn<(Ul2V 'ch1ר5 y$^حxPEx""_pB / cf|@?/*   :%q603˾BQKSX0sHRSll •KV ;f/\~jow*`N(kQK <= @_|:/>9?>DHK>CSZkZSWꞛhȧ)<ƃ:[KPߜ 8 qfk?sʿxa|EH!wtzsG^J3 !cW~Y d<Q_ J'6) ҟ -& *b)3NL p4{@#-D8o/P/yϚ0PGBYPJ UHzNՁ [ciD~iV_ wIbi+~?)r}N><u|v-vJ!;E  ' M,_ּ!'#x3%;<*#1,/" 2X0,;#&):y%# '#Do$'+\1**,n'N# (h/PVʣǠί N 5 {㒽{V"$?(%. %' *-d%76= B\XA–A%3J^pâ%4b-N=7u)c,>pKnB)f8~Y ԯLv❺6*8;Y#(w^,RE \fAE¤tj*>zTmSu3d*^\oKDUAp.n- Xzq"?ϕcʦuEڦ:C+A 8ԭoFLҫ UE нj솔:zoFA~9*ŏA#Bb$$ZtLx%,w 1 J >uy"ݟm係@ M~t!2a,o1f(n /YR7'6wATuz; #LȚD+88sxã^iSݱ`nB;IE,㖀v>܄T 5OL%a h;4lz wiR֭ 1_V}t^*Le ?jS*Y}Ox+>z̀7o- m;w9-y9 #%h(v**c( #4e K* l!h0$x&S`&͋$ H5(f 1 ( B P(%FbnSiSU ? 2U Jv9 jw l@(*EԉXW= Rn cr1'u}7OJid&-wX /AfMaY^ W9" "Kk@i f@Htj/f *o ʹE $zs t6 B P216 quv *fωW1 |~i뵧)KtOw5K:T?_O8hp7a^ĠSM 5޳prᵌWWf<-JqN=N-:~J4Zm92i^Hg{\kP̑szahge'PL; } "&c|BXQ0Y+{Jf\xAoOx]p , Ւ B { BJ  T(5#%K,&$&̅I&0&݅\%$&z(q,F04M5|m40x,Z)p(,'8%#_I$ƨ%۠&^$">Y c_T@hV;QsPm' ,i,+=n{`jv*],r/# Cjk.paES|_ q1oM^(  e}m] q,YCO0sk^33 PP  .rE*"e$ =%={'2o)q++=rL+Tl) &9a#H4 B vGZ< " R t$ Lj  >WRm. hPFIz)axLHX-s`vG'} "  | R R /4'ru'r`=ƒCT t ~& 8k2NQ|폢Y $Vq*8ע>X4 ռ(\/`&)ݎo'8rlS\ Ơ̖ lտЗ-KU߮ك>ć =^WLDIPb#"FԊ_vר+Qh FSׇzDxu)vT!TN]{SF݈ۙe>TIիxe +هu]،&=aR,/c>5X3_}j Q Aݱu*8N~ )~F4Y3Hx8Wu^"f/^ф~"ū߫v^{5 m DxpNcbQ! /hJFU*j֌  ={!E7yYxQ/NIa?ZyZ=^֓ @q\2NY)sis &"bSghY(4"c{6?<r0 $BL ~sa '! oc4DWi(dH?<N  XtradW׿z!1aQ y|S h!T41 {E5lo2;q }9`{xI=j2IU? b5A d^Zu¥5HwrG ) h +n8OW1׼y<eE쇘تf 6e2|b  1  {c6trl E#B(A,?.m.A,! )Y%#F#s%?%X'W/']+%a" ӛP@c &N8 EN1>!c!  P͛"n(F0q:8Hkg[49Y~ H 9rp }#&(P(i&v"#%!# =|"`$ ''?%"$zNtH0=%t)%Gy> bYcw>8e 0Y |f= $ Ǘq ,& xO S*t784cf;lj=8гhpql!ӥ@h_.;q2qfp{ k{sNk&Q 2Q&FӋah&ixS>.htϦ,&@lbχv?yInxbj:a$ D>*XP*@Z/"Is#@ZYo)tY٣4 W =9G#$3(#(J?$)ҷ #LaW*j5 ~f '+)m6:ȡ2t /cr"7o2W!kgd V "_m>ExjjXÀQ@4dWfaS3ŭ٬ 1<ȅ) q Eّ7P2 _ 2 mfE"$%E%I|%$"#6+#H#"h%HL(ol+v3/0'0[R.o+).X'_%f#5"[""z":"s $C5H蚅T7 mVƥ7e!vW[_h& /|T%'$yZr[\ uK>k.3:( gX=ڄb-c,EywZKeBEܱ okE-sX^}"ej+j=i8jjK# c(A/?\.wI!oZE$색&D(´(T'ټ%#qaCi.U PWĴP b Gp5*O/ RrR46M v񥼹?l(6Ootn < # \` [ + `~6Y'8 b&;_Uxri "-{k_#!&_#Àu(#7k?#)uvE5ѹdI/˟)e҈L+bHX;`yԀX-&#!)>5 x_즱\R1@\'$r*a&xqS]OU"٩" aAk4n PsZh@>8 +3Yh #gJpQbĥTYP޽u/+Вv+[ː.qt]1M^)%|٭lHN|62Sߞ ttabˮˇ SzdbhH)G=k^6gw,մd[b77{X쟦yBYq6,E#v䷊;bJ!$?a7s&9N!waa8"{慔-tnO} mWxK=P52W|zͳ ‰7ù*B4Fi n[ {3I>ð e&Be -lXՠ ,9 U{-#k!ML"Zs"F XZcdt(v iD $J.㟩Nɕk $(4+>S ,b*h~(@%#^}#L&$'1$)I$$t"f/!>$O6..v]`fr?sUsM;m46/&Od#OǴ*1#6]87 }5D{32~2c2|1/%{-nt+d))(n'hB&wY8$!&xK d K"4AqG0 NVS9B %A Z>Q%,bM~:^ ep 1 ÿ  2; f H"]@ig0!Z&5h*{r$,w,G+*\)vE*'2% a%B%&V (*n,'. .+- r,J!,o+*R),N)( 7(&E$4!{>VdFT jo{WIA `//H5<5?`+QE:Z \aEai*;pv,}1FXT;a-u5ĆjlxS@UܸYqot --qҲ򋂖-EH4?Q.Vb4tPFn|v25Iuȝ5?U61YLW-\Mj0790MS؝TVsN*S}3 vB#2>UC~M|"uNLW&Bdw;A'!)r~U/$MC zOEQFn2ZZJ$SԦ}RxВXA?Hl9زzL]8'@chӡq4օ?| }y|&tjT>~9QE2rG9O?R2I׹ڞ7n0xnv$!\3Q}{Sjs_L3Nw;w'}Sg2~L plafXoUy O|em4?b?2_tV(V*nt8#I 7t,-ɲF4Kגk ]=q  ٴ{_+5fZg U?d~9JChC^Τ( 8*%mܻ@fe^9H Rx|"ujgKj{721< (> ]+WC* 쫣 MsgspoN ]\G~O6gظ 7BLeQ%!3@vhc]q灱 Mt6iR $P&c&%l"$L!h+!"$XK&W*'&Ӓ$蔏!b =kރe/g9\hTWXU [I 6rXdld(ޮ*J0d8m?ힼhSNILC NutdvAy5 i <F7CX!"o."V@( 2PXY< \̯ D I j+z  陾 A MD n|VqBqȀ%3[aN~Ջ?"Mw FL!d©9%@9"|t/]A^l&8z.fɎeFj:EUXݮ) 12 Ii <Z&3orbτprd##c!LZ,#}.BvύuHD&/_.AI[ FI1[gv^|p5O8 _j;A4Cs.pH3 Wj yȸvX!Y2V#g"{!\FC,@ ;âXJ v v _b (0X--+0\|ZOaV(* \ZeJ{D#) Q yצ'DǞc_wR>b[osoN)U #dc?*Go\ ^n DxCY! FE!#Y1%%M(%zC$d`#b3"&%"(#F =%R(8*"7f,[j,AR+0)L'DV&uO$9"O! z F ^tr){sJl 4WBf3Mo~qgv 3gG  Č؊d,;N{'hUGqMC?# hE6HWb¹_=Qf,O_ӎ#B R 1 m >&Z(1L^"XGtݑHw7LXpPK E -i`m%t8rd` -"u=$;%r%?1$tR("eIzXyUͷ/( VLk^tyƲ 22l;#wR5 B]d`4XݏdBe8 X ^<  X C %{T7ƶ+(!Ս12uAm9 ۾s0(5tS杚-ukww*2\ܽL}$ڒj1Pm cJ6J̔6 s՝׍Ѽ\stڅߞfQژOb zBpMpLkE`tWo˸颒6 K4H.1uNK =b_VL^wl@ I)/wEy+P+VՌDgD i``[=i9e$Sl3W`͵ # o_6{jX✘VV͑]H׺_xҹΌIIZF8\ʿTvєΜ҆$߿_䈄`聨fԿi꧸1,aֲ0KVX6#߾a|J١ᣜB׆كXN4(BՄZ?xRuا"RoKT1RݒAۺy?QvuG l&y<ܸ H:}H)XJ( i 6@{4/# u#U.u} = *" C+yhG9& W! œy[\~a , n 7! 8z Җ OY= x{L^{=<@g{ȳ ;fxkmHv8՜FH` K,FjT9r tǣ@W 8R 6%FU1:[B pn * nOLUioddZ tO;ʷ=v)º) O\Ovx2]Z ҆ / H 9G ҝt?6a K(zӚ  B ;M]&$  HgZ|y{nss05kQhXQce iUn u (@S>Ryl-!:%N(q*)(X'|%$c#S# %#P": al-J@$1 RyuV/w=> #`噾N^$ +I=0i)33l"3M@211k1}Q0ݼ.T-¡+Jl*(֚)N( '`%"-&Bf {}@v7{ H! :( Kھ   ? UY2V  B :DmZ@ BcsM!ut<,6^ SU  f { t W i<JY{1%)Rd+U$R,؃0,?1+>u)'?&cw%Ք%T&}':))r) (W}(SS(ˊ1( ' 'V')'h&ξh%rU#`} ͺF˔g2 J$m7k ioﻋ{ xnL\R4Las2Wg?ILd N[1T:,<@q$C# )܍n%ܱFiy> z0j6HvStd!M&3W7E8$Cٞ$Y|bjNEoL@{&K6KMmيf%(@? Qo 3J @0Iin<䇻ߒ6R0m=mV1qZDUIӜwo`js%׊.ٖɧRU.*Z]W yN:W^(܂ojڋ*KJ@h',EN9lMyhvPg/@-^ p2bRKo34#r!{m&2oB7q@*SWju rth6ݦ{^0܂mF"QUϏq!jh9e_&C󼳇՞\A`8zR`g Y .9,?_p<} %c^+&1ñ:N^g;xZUa Y8q #r p8 7\^5b @! u~,ߣe] Ұ 4CzHq bWlRDm XlX'pDsŋ+Fq17Ts iL˫p"w ]8#)<$#28"!!;("$t$-&?''%xBr# ^ \\&6#sY|l9GA 7MR7MYȆVvr;Onuf4_  ў]g"'78 ܚ/>:N.6ҢQ{.Aﮑ*-..qE {ya Ux h(Df!7["40"A dk)E SaT: "m,V됭:^Y U's`C 6 r +Xk0U5,_v;n)rB1k 2 }cf0]Ap=;4x0w9&?fשUJ%ao|H{O\;5~"W^;9~1Pa= RM5Pű$K(|5xc8@iXdz|)U8+LEM$>VshS2oaD,6NR3<#eɀ*Gzipŭ<;3"n6lʮ(j=g gju^j-c5^?FٸQV['? )} m X3Ur򫪄#=UM[i\=۫<uWcUV( 0j t\D!U$DC-\cN!<.bǙ]L[L a>{Sd>?(̌ .A $P/4Ia{ \bZ#$q%%%7$"!tk!!>#Ӂ$Ÿ&p|C(({(~']&%QR$"i!)8 3mWa4|OV'FlcGcFP )<RZu*  n^f}CPM.< }UUSxoiLr  %/{ Mns(GxJ)*_e"SMl 8nvC K0@F _ # 0HŤ1Xl|zv*x!fT""x "_ Ž5;oq$ hϖ CN)P? ?,s7}(OW\NkcW Y<pN&lkD\Z񡫕)`#m[U3E#W ;m߃Q u +og͌Ήug+Գ;Ylxf]7 51~ n?꺟u诂柳䖺\Vޮ=LC];ۥt]ܻgޛI墒M`/gW:jF\Ԑ$J&ؘB^PU <軣il.i]& 6>s)JL5BlU˷UZDF~d¾oQH@z$=nuJj(Na/lqY=-y~~IةP@H{i`zZe]#E5;poH͇kg ψx>V; ۵42dΙ61JmIu iKܿײ"Ӻ1ѐA*3#(›Ԏ*&fҷ{ѽB7D 459Ys*oP긙B9Rtbu)k6>R[6AQ,ڇBW߈ALc7?AdwcZ?K {ld愡 殛NW%c@X,(Ʃ2s:G(:s,㮇2V"oA[b59{: g2DJ0 &5 5B Q: \ m |[ F- {m$G>0ěT0eG>r'8f:Q2P }ha t O(W*YXo/qqwZ3]8kgc.*JQcnr^O1St e ӒT-Qr{' Bt!A6${˺C Zy9 ;rwKJ}E&m "%WFOzh=>Ko;a'oJiAbtI%xF6 Q< ٚ  r& ?zl-S>6; )cM;:Sq!/ 3";5 dMMf!Uju /W LbGsXKtk$6O+ Q d ryCC  +  0`n- !r"$N%W;&%Cf$*##n"˷&"|!́!PUfuKC>a|4PP N61${) -4.⛂/1/˧0k}+0i /' /0-3f,3+[*&)#?h):(gM's$߫ >' ft +, ix 7T {O0R p 8p ۴ e ?w P I }KC.`5aeWaZO~ W (0=yrE  l ; >"gL /#G^'5*Kd+b&,5h.ljC ܼtmN$s+=#}0xKAۇ--$5K >=g1ͼw@QvuM:4f^87k<ۉVxʢr~ ,[/rcS|S+巸 *jο% K_d鮖v_rS}5A1kVHHW1RFgstfo{&TkC(+PDJvzVX8[ $Bb@k2T5{],uOjSօ|?5W$y^g՘j*k_-yؓ փGo)C+qjT`K߱Uݎ ˥_KXGCX> OaM?&?)x) <רs`"1A#7Z(?[𸸨򐪙2Jr_5fE6@BW pTZOG2C8&_t-Ty*KtXrR;mrFekQ8PxiLH=' {ྖg hrHxW+ǿ\j_|Ehy@\@G^Mci&FR]\2^uR'u]U8)1m'_PhSK7y_Z:l;  ) ̭ CB 1 >$ z5w {f%] ~^ 1 T q zǛE)7/XvHF(9ձlO $KTGs1 !_s!}(!N :` %!O3>#*%HN&ժ&P&&$X"~ BqTWl jz&w?ʆd A! X6]nm 2 WA` ϤIwF|&6V bE3%:HnN3V{7@@4 uJSCx$ G!!p nDi`r 2ۀȰ-rysS(ۉSISRT|B5 c9#ĥy7 ȼ2.;>)p p45ȃg{?uK%y'TQumh'8#;^Z4>GM5}s5t ̘1|I*LG5$Z' =Zp og%1 = (v &}Sk xu׳*4',k6wR$к[qzqXCPW^X5"![PթIJd.%Tq$EA#W"uN!9.!@!"n$-$%P$^"#9 #Ae"$f!Yx%zxfdk5,.[f60ݏ#m [P}I=H5>B:/2Ť $ F Xn!" royain RG.a@ BUCArףZ=^  eHŇAZ8nK%2 .@ ^#И:TT+f|ACJU6INlAh0 > nv x3u<zRpWG { 5?On,;[лz qZln5B?9D٠{E:v/) X 9@D)RX=*mlr˕cW5} A ɳ4˭'#Q<0ڸK]+b넜誮ej,59 -M'4斾;4l:S+E߽'rJۼIPݩN*)h+l7_:kn,H66\=LD s0/kY{-9^W6؈n~3Iy9IR7W6e}#x.@YFvp¨OYZ joɍ{pDI0ߪ 'n~?Z٬US3~eѼoMҩpy ܅h A^ܬۨ00C+ծ T1Eo. n99UxUB&kԾG[چZ,/C8#(%:eO N jT UgT6Þa#ځ @/ܶHf&gAt晁|5,EZ9eM@_Ǧ%2{F`d9N9 +\֜Κ֯j׊m)\) ]޸uH +sL[OYU3<w  # i yJ J6 %  > # %ӻ6|K V=v/,q2{xwbU/DR d r#w rR8l*HFJx @Nd/3qHV3)zTP 3]=H%ZtCv_rCwܔB! IT&yt7|SK}x '3jG B½b H@hKm4 ("~8/>7v=0- jJY;"=<"o\} W[o R 9 bV q/ jF KewXiĤ}FW`;"NE*agFg4` S OĿ{  u1 O P_}ٴl)/gA)a &R K  .1͗ v' ktv1`MA+A"E&#D#h"tu"*"!N!? c d[i*.6ͧ҇J P_Aho9ÀYTߛ(e8dwQ#X0&SY)D*,- -Bf-Z-|-p,ۈ+Ik*)߄)|E)q('%"G"!W|ESRN27sRsga"BR,z31ܑ;\t~פ #  n 5 ? 6 q { _ U8sN"6$Qn$VZA"C k Wcsh* a?<]Lpx " u%”/h~5 'œ:,c5fu`z0yFXi?sm6$>Қtvu2F q[cqt+9 O[ l.|EU 8:!;C $j,J%T ()a?/ 4? #cLvwg:]FI}$~nog} !NpNi^U>a{_e-u30 *韟l_Fg?aVh/jE/OUЇ=L(vcPOMG$lD4!Η a2/G_+LL󳶷۳1=dt&b"@O>ػLN䴆sėBX?@GXe&u77 Ug}FFK; 19>9F)T P%]ss7EQwoEsk  jB`MazUQbրnk*0F ZJ !w})Rt=&qFG{7+P#$+ÑQOUUQ 2b  0Xa1hMvpҧ<#'oc .d[ [-1.27}5C Pvvl?8!5#A$8%A$߯#"S!_"!AY-!!F" g"wG"cM!V!YT DzV^W ʌ.þe%O &K% jj4g)zQ$ & L L Wfbyu5\:Malu]BHU N%8 9$prkdO9ܪ]_ON ( 1T,F2HU;i6۽: CP ۧZh  |tbXz`h wm& đKe JRnZR=]Ѓ]8[4@B?hQ h0A )XspynNg_>%v#& ^GZ{. H;B, IaR&O,Ѩ表!/ ፵jlUZB>p6g^'HRK%Y¿߫ӸߪĕmT+nTdT'8*K+;aM?azOoj' -)ZE(rYtݟ9V7_ܴ؆*0αZO OJk /#-fӹ){ U]c lKC #LoA2R՚T zF|B|gAԇPۢ\Oc"Τ̙i|ܐk׵/]֜ǣֆ:іlIsӋӨV p/3ךڀ*uीT7 ;Fw8ê?gpVw_~<#25(&P]ڑhH /Gt^$uL (R:sDzķQopWK:H@b~ޅ9x(lؙ(\Wmh.zp2^u)W tDWue8 } 7I O 5 y U & P T, '~ sS%vv)\8@ <-E3}TKjmOF̶# _P\;ODh&{ %,L6T;,l۔  Ck!@i:k;|F i`bznn>'qVuTYya'k<1:V^Pģ  : I IF`  D  v_f/1d1&b7ڃoV]yC/24"M s D~.)(*,%ky-֥U `N ǽ t B quw 9%7R\-d@WCOV_ r *BςR6~ڪ# ?S>~ Q#&v )u*9*{*)r(Ŀj'&hV&Ǫ%$#"[!: 04E Eyc;('02GFC 4AY ad)2Ca?@҈/K*e"fY}1B,B$<oN |rAz2Z l#IhR0ԮEWZB핼헼-@U; 7;h b>Y: }t\4"1+c/  |kӆ~z*V 8{)?KCN)9:d'ÔzhRyk%{϶:oKsCV"MKQޕVTߛ^߱!NB/b#qt,*°-S_Ln54Ml ~v_a;z-5j&JU`S@n@"EU 7kh9yډ۷%}sHsB*hvW g>P&HK?fO O꬟9 fwY/\_i5/ 2~4bL0_4Sz+>ysŗl_TB̠=(xuʁUէ%P2grV.&2#0=pM,'.F2}0Kgr %t>PV6j^ M$IqLC4&цu9yc%X†i 13"}B 8/pah/;:I7,fqe!/\p$!\m~d;9cn#gswJ90LU,Q ?K(Kd\Z-]T8Itysc%CLlSwٖ ln x9 Ҥ|  ."3 oIT3O!w m|NGg&y~y׭ '|EZ fT 8!Rr1 @"#ע$.-$з$#p"G!f? *廍⪌;O. @Ch Mrfڠq[ (Cme(w ' 5YeC/SjhZ̗B 393`0pa)>d <8 h:NMr nlYoqQ4T4?c?C#Ugߐs{27Yg6[x%}Μɴti?o2LdQ rccA6w:.SfZ$iMst9sl9i W,Z^ǝ>5JMM}:gCpX]YS5񒊽8J r&3*(Gj bGkƴN4h]F Xtuh'5SVԗv,'0Cxjʞ9QQ"$$ȍ$ $ަ#""ϛt!!!U! i X"J qRcX[t^l"bG1Q#b u^ =reGOTE(`ۼH d7< Y .; Խ "MWXXH0-:M"[ $`Q 2Ё)V?+kSL>e "| V ' vIR 4/j}   Yd[xs*B:e *M|z'yƞ,RJ%P.I fj~ t V 2誜? A"W `5J/S@cO Vp:VyçQx L8p Y(LD]0 ,$gxZ"z+~[޹dxu7sjT[kXK\?pu[xe*e`J]8 v< qヒBL DF-=V@{Oy%?A J5?0f8C3X|C@jI!/ˈs*?sus8~c8ґvnY^t~@fxɉ8Ƨ8ݛXM%$C܅./^3uطIDw whm$'%]V n #WK# Fu}u ȳg I2$ '(y))X)('m<'¡&%F$##"D Y~b4K}WõeGX m = Z('UJ#rM^yb-rP\[z:\ XGq`qɷE0A[*n9#OA 0' 1x!, @Z,9k2>ĔC&[퉢JnKUfjfV+?Xɗj~Bydr1فx -~(Aj{p#CWST$=aa~$e GQPJM ۸hPVQIYm'Ilw_>UC߃o^Il1 լtģwnFיaɵϙqiBKXUe֙l8}&,#E~( ֲ5&L 9c@U-Ƈz(U@kE!mmA=6' ۰~D6\Ig%sBK&2et~2z)aԍs)v$i)=M= /XA)m4HKx)>A4ߔ !  s G 7 ŸR$#y> -}Sy 35Kb" ?;Pfkv#K tz [H4|@wʴlZu}T@S^ X"^Q####Bb"u)"9!0 6+V_%>@ f;)5 '!az!h2!/ `){d=c H/K>^oSF x04aXpK3C n7Z_ͣuDϣsh:M.| mO/P~օ4ϖGi 7y 2: Y5 cQ Y?$MHZ]K7ia.߇[3cI,^DZ[%+PjRTŦu+nknP1 V8f#c#gBX?Mm+MY11gtcuS3'@=@"+ D_)ユxk(;(>̀D݉xjw(BSQ,zG#?Td YF qO#gSbLM!`#CU7-h6)ѢN\ǍO b Iv7?X '_ wh arMoP5qIERr= Nxy xb ve"΁:BsZj( {LA:( .M:/ -j@ `mZU!XLmv@WM!' 8 }&Kz%QT8\>k \mәo9 K"y#D`$\\$'gu#/"s! b!b 6 <ʺ : +Zx~& 3BYyt1Z Pdx o h8]-[ x+a H  t { & Wf @6\6Op4L}gyH%TIv? 5 'Ѕg#f0RD~ r mn ctWo8yx{P z ܪKhz"+Yc|Vnp0WC)X҄&+pF 9LWLBY_wI}s ĭ l.d79 ۯ uaRs,@j27L'=,lN"q: .2+t+ Gᯧ;-$!UKdbE9` + 'ceKpQ h< [{R}Rg^婭XdkJS%ZT8 ᓜDzb.ȲEK$> %cIP(f2rN]:_EM;/#0AƃYA8,GT|F 6  u>,y^s?]caCZ$et9^| i@ڪ^CIUsH$hiDKu +zvd/,W K8] @.agNX@썋#o썲ܕQ )& *-lg.$&xZ:%^?l@)'a#>ʕ\ֶf}䓚"j%CG/=AL皎yd1E[:mkLn ve[Ɍ_`xE퀤jmoy*͒,,±L~kMݏd^Sg]6J䭷MUÛ߻<}mިKr fݾܝal܌87`ܼܻ@?J 㧛*, +{lc㊠kB~ķ:r#MӖ VS[1#68)H5׉" a;-'Wb3uTG+{o%PSjBwvxX*O*(2bax^pL&8sv M5uB}7ΊIw>1%0@^z!YJ<(FI/)B79V :Aa~;^cO9lO=6Ij,l -} U 8 6ů %o0m%L}l  v⤶Ilۨ?c SG 5 VKV%e,l]h,NsO$Xzg j y>_ܼ>5kq 6K z/OUj=Wşse`A'  F y I[Qgl%2}L o rW9X "n"(Tp#?# |#g("51^"{!)![x y*Q+hW 1_4U}(my.SC=d{y3{ 8>q g5 \z& 6q 8k\  r v|b [+Fop!x2VАb<~eyCPJ&1ND _ Ӵk NNPZʱe;6 R z g s&B 3n*5N  XM&dQw\D )9˫fx#VaM b  k(:IBc x u!lXc hT @sXfȢ_9ȘxR2:d!Igm  anFE\ 2~xs}2C n_ ©_[_mjmWUvo*w&:΅9,}yI.v1/ḳg>`U/i+rڃ쩬_C7P–g$s Qa g=|2"B2EIqTDi3j^(S6l#>gr ڴU۵=][L05~Ybv,Ɔ|G1B|ދtݕ4j$'b!p顑oq#g!~.,l vG;,B݋rۂplLث sCCjѓڊ%.݄<ߤaF7 暜:kv: *r^C`sH90i乤Ð S hV4{>Ӳ]v g`41縷C5)S~%mt硉s[aڻzk֯\7Y'ֈθwzh䉭AIsNl1hfG )&`jt !k v:F FoN@  v-V V /S{W<7agP~h8 6' 9  `4 7E eS5#.i`KYmFhSptC:AFԓ#%N+`0#[cHC)Os ^L36>~`x  VeE9GP-fR~v?  JS=!jb!Z +B 7IpwQI~ p }u-k59hOW;<  A rYϪ g aZR[-y67F}o#*[hikJO@ yG^ . = # P ,aCTGݠ_Զegs.pf r P< { Bj :f pZ i|1 A Qs w ƿ5qss `=d3OTfm0  '|YIhUKRجM8: ,=*9@ϼj.&wʫ{`or, JL-g "##A|$D$nE%[%>%[$#B!JLjZj4G^U]ݗJ LZ q 7D O N ` b|A#o  ߡF Cv % iJFV#bjymda 9<3c]4!;f$Em&cɈ'kw(5)(|(J0','u&ro% $1D"Q8 ƋzV<C,2C&ev#  ,^-'<->bP c_kRpmB[<:OvAp4 W7s_~O7n H4z +v"Yޥd#VhTDT$TKzFtEcX3G2Ңb8Hi'JR&>B jW/u\(?~ޫj Zt ޱhG/E1緆,Q>HpzF eG p߭$Z/3yܛ5-6K_#A p > u3;ӯEnr 79[pXCi ڇ#CPB:xɤpk=W@'AX%$3,cMޒB.ߺ.{xᦇ"np\USg19+]fڧ{[䶜[ ).8hy`:ǂt>J EsB iswKoOu.rbcqgI)<&C1ۈ1M'juM&.#7W> (< 㠲 ) ( :'TPT hϘ@%c+v 2uÁb{1Q~cmby1t ^ 2A?A]c\Y-A'!GXaG e!y!Cy!?&!j_!P! N p & *!۩! g"###"O!|ʹOo,@J 0Dc-Տg"5`b3 H#甠FD|HYFk_">\ xG6O'k͍ ? jR)85/ UZ}eYUY7D O T 2`9 M^9I[$P=fQ`*|lsnz[k7W,JB8N5Ea G)Rk(6B y  :dK]Q>)d xChNaJH{^4 ۶!z""C "QT"v*! KndCy'*94xldž!3 { ZCS<Cy4'L~HS / d `[uGm2\ ~^U0bg?W6u"?죲Q JB1nை93lc$ ;j[UC5nzڑ xFI3 :0@|P-c@pnr fLFUD(DE[PyXJՇQZl[k4)ètAsq>.Po &+G[+ @T`D GB:aO~Pm?8l~kkz\8w*V|2arg 麉27Q!wVtB p)!G}$I7I}Zwwu@Q 3Dȍ b IU4(lxeg ?^Ry1^`~lqUK*Y8〧.#;璟螮SLlJb1YԮh,@rיzش3Rξ0鎕 T*6qm$|/<E+[  V cQ[bt 1~ `g )6Q MV l.um%AϮ ƺ m& ? p k_ z dW> ?ioIbK.7Ņ\:*Sl@{h CDk#`Qo>`6 X[rWD*"TG`6g*Y +5Vh'E&i75 F *$2*3ڑ} h&29=s3$4P8C__<~fR,sdEpr:´@ l  Vdx{{   @'2 } _`Ӻkɛûg[RZ ĝ c{ f9 $~I}B>bFdl0ssQ4l  " Ey + WE w1 -f: 5,   W K )jmI+HQYml\_ 3fVJg-NLd=gFWB4P#. ~nܕ9 %AurXBif'j d_Gfux(4DJ L!RU("s~"0#Z0#H"!e[ ʞkLKa _b%w&G]-2>x!Sb F; ~1 d @K C ~ 7Z<4]#!F_  5T=Xn_th+ av%!dzD(2x,j!0Z#.%&n &Z]&̷&sv& %z%{Q#q"" e~Z ZG_ =RgJIK+  6  1XoQyz4PeD-|Rg %~"CIm^׵@3#=;yKY$4R.iP9L#@fDm%g`$]`5ohZțD,JxgsC5ި3?l%ϛ:LߠdXj@ >Pbw.5||*m"s[Fs)dWʼ( !>ZWURb|>:m#/ F?S Ej%WRQedx|]'Y͢"˃O0G 7$)BI_h%XeU!DBALR蓄dptK$z!"Jsጰdn ]BnQPXRaE\: 4 RY4ds^rI=Lz#\Q PPv,6 v$MgUA%Iv1*-'BAOD{:Vf"$[i" '[m/8# 7gB7yakG֗JfI,PpOJ)Sn@KLzt!/N%s_18ZРBM>q9j^h'b`4b8(DNRNuLgi|g?180,fc>c%,hG{M ]w5%,fXUk,իr}̍^bQ+FtPx$x^-tYV=J8\2HA 1| kr 4+wxK<YSv&%:_1 [MO f N' 6VQ`̺js %Σ  7Ԩ~|# + D% ! 1 Cb ` ]jF!.!f"{=H##+p#5A#J/"q| *7F\("'+l X5y~CeaGc$QcpBwQ&{_JȦs OON|G:;v*=  ߏg~4#cc+2lW} ^b7ҵ7 8 ;d6vzIxtG123>N^ m%Qgm? n0+AJW* 7~g _ e. ` `f5=N{{%"ʂ'?5.[m:۸kZ6Q#`W~)t|H Y!9 xﶤJ cչ2釩 aLoA75TnAYg,N<r+'h\u "f޻{O} JA_ @.c6ƹhނkn(MH ymBO-b]8c7.y3h?E Yc$$ۣ|. Ke a N}ɐ5K~8 W# rZؘE{O48)z!_@!! dNךWO_XQA LLcDgp-r79ۚ  np >%AfY!4oV}< ">K OY ^  g ) c XB:cbMQ-NX߮,H{H P   z 01 x@ ϛ ێ K P ᒣ ) 6@ q+,V܀(+ &  ) 3^;ة|)@RN:p*O " X* lY Q ՜F%VTM,յ\* 6 x r, a  >; VV?:=U&+p'ne$Г_-ԭQIi OoFA2 9i 0;w xtf>c;G M[MgY2,wz Y]pPX6<{L28INT!<踉~5q([3 sNo&Ă7XQʨs!D1ž)Y󖞲"CCβ$DP//xZ(No ^HB5r]Z^{d-P'.4xZժFD0 iJő&5AL Lz)h4WosC zD #[Ҹ`nTjGUA۩̏.b4&"Ulsљ%)r∠ |2b#60"˜P8Cu]P`vhzRn=Vݴ/sB<:&9u,Hm~8]޳ 뉥[ꎂByftTuڹ3nA;7"B#` .uyꡊSw龘y喚d1Vh{Zwe-gT[H\/WwzZ7ùcC$I Vcd}3V|v  ũ *Z dQ y" L { S b P@ l o } 9R V ] |G % " N >X}#{XY$SarLYS( F-^z鵉"+Dirh sH=M'*t6P:d`I ? A"-wTГ{sӧ:? r GR{^}}F Lj.m$R\yx٘Bf[mw`,t' Y(8]pi.dNp/ cr CS r-z  p  1 ZmBdc`_XZr E~\@+p #RNu3#(0 n&bO?V@mb0_o X& | A Lu ]  9/ > 8J q[ Iz &] p; YD'&C=u4H ùl\/Lt|e7 Umu~ΠJShUpKXvg44Uwi,Er{%aZ3)"\TP}mg.}tX)NF[eI iv( +WoV9ǒyk$a{^%E">l/jk%W!{E{Mqd  ԟ x ^ )0 ֬RЕ k ܎ q4nr"I8m$q}· /lQ|>0ŭ!"f#A[$g$r$]$ֺ#v"@!z{uFf4]g#~jCFRrdz_3` Zk rU E@#mmk]@ )TGHl_Fj P)c @(3Qb z5@Ulŷ|F+$kt[&)S:8Y256/L7yl=pRiN~J7sW`Ix" G!R{nt< q .yZQliPbRHJa0|=t輖9 >rVBn*j`Us0Y sئV@%65R//\ )ݐ2ݗ5cfm1(/<;@Y{3Z3蜨klė@%! qB Q7 8ZL߷>L&o*}DթZ+4hHV}s,D㤓|A5 0/}`0MՓGRC;寈5%t0L )G 򣆎썺L򏅅[>E117.S) J#Fr 4Xҩ{φI vƠ{c+~j>K>G=<6*r)Λm:^F \7|lL1cD󔠟~4R{ǖh#I!9oaRo@\6V% vuvX٣Gn^/bJFk YYO/r`z;1q16)ՇWP%XnD+tn\<2aWOv#nT;~ ~rx_8 b 5 FT]8Ywl*.[7E 5DZu~zD5ӃNo c/!!="#I+#F"f!`BaCX]궰R0BM) mdJV,QBf<L\yV3hh_Omnr;Ut|A 2-[hyE> Noyh<(gGpdǃjjlռ@4\ZWt֛Kz>=$qvZYƔy! :8M+M4$ w*  jY 5ea F - ۿ ^@6* gU-d$IxgvTN  YXS F׍\hڬJYqj   Cw E/.A" ul ;nM=^~|N|:$}$ 8 S/ߴJ;Z+ s _ cȹ_I?*rQsB9t)Uϋ\ji`7j]u{v{q  i\ e '!8I`; Vt < f$ # %԰~=*P }oNJTLg Ò  o <)_ G | 9* o L' [ MNvt2WbA l g S, \a/`2mQ`t]ck (c q 6 arT%)fpUɗv0/D/ Jz/Ni %6A ESy2/SjsSE~X{Co/y$0N":$AYwE=>eErm46-n?O? dzёLɀ0u^v0duCv(ܭ<zn3_%"Xx\}}͂&mNb(agGZNe""L 7m h1Q4%XAJ of_x$x:? ;=K\ k綟 )值ßqp`Gp|v Q99%&䌽ˏ@UIDSb4}Af~򏤳uY{r\31[#u3BfӮ#X]R^W+\VEI蔊Y(>rQ:cVp@"` ߑG}!"L:}v=1 ]-{lrG{VLqjCpzyE n + 6 u  M 6 A {B ɲ p1 N Vg % ǂ 9 q: ] ߃>T@VTjfp")NqBvw梵qk5ICsS!#›`/N6M8 W3 ֫ h&q|s. aF A"lPx}qQc}6fs}<zL|qw=gCIa;b1Dx-+ K<q0 ~ A ) 3 2q \d ,?  7XB*BQ,L+S Uh$;_1 'e} X =+)Fe]oU P&~R}c " U| {n h  * \ S z"]ljH&IDjQ&׳>Y@q)=!Oo̵ v>(Tϳg! L'Me#ڊϮy2[F  BVTуo9L ] q{<v\޻E z&]թT[C9UˤY~ ͣȮ<9aMLN؞Kj1L [6񃨛XjXF5ҳwN'سQюZ ,;L},]*8I8D+AK樽 !%8z+ߗ |A8/c3㌋JO~2˧d/ c: Vg":U;x}!iWR59 ˢAH{"$gf혔3ZiEHb]8 8 .AX&h:.?kt柳r!HJ6'򮒳MjO9*pJk`>z;elmFeXB| ud -& C^ ٿab8b)9'z|S(e>&u8<=>bf< IBKsul\:UMmG^^r(0j h" zcaN׿&E A_$Q<ִ.p>)XC-dzt+-ƛ" z:ߴ}LCt 0S 5-P0P\ ^5&ˬ\m>rd9-5~_r!,x_4?d@|*ֹ,X\6Vz[Y}qUz%jAWsuNKzFY0jNg.FgH ,12b7n, _ 3 )D$'հH|HocXrW}Zg- G[! !G!~ aw[>{h ZsKhY B 34[`V.-2.!TT:nTU/i)B'f) પ  Z'3&'Zd4Iw m r -]V r$dkW<54 (V|`);oApMx՞e L |x aӗ  fsLu%ՠ*ϊ%/#eƧj xIcm z&gd{r'^y C9T.Y[Y`]3 Xէ ]S1G9:T)r <~k:c>G8Wl/4 6p_CEfm57BDxH0Sc8<>X <X(*e".`@inB(@?4hzPBo׶ Z N) 14f Vq " P<8>| OqESz z! wAYew ɨy 4{=n{.Q Z>OBMfew*y(ϐPi69i  |i  A K6Y_z7д uTB^ I0 & m a 9 voP&b7}t#?m&Q u 6hhw\Tua1rY(gԁ0I66W+UCI֭  p2``e͹jzrM$kDsG~L{i-<2S@l%MåiӅJ4 {ygysz⇼G"UGVǸ8(vqPa|]ܥQ.,. -Zh(G1*=7 ׋ E k J m zh ّ {_ x G^ Գ  } t5 ? كq*WJM}<ǰK9RWKמ‚ M@=rK42'Z$3/LN4p'bsrbxU: O Jj nRu"{ O !x| 9C zE0BZO^armL\N"Tks6mk3Hl0.-8Gцe13plT5JHNY9K5 uгm] T 4 ܼ= * bhF ^^ @uܫb`J5eAi>A">lP5-8|E'>:>3]D D_>=`6)N)^O#  ߃ oQ u ? ' : sZ B  @ H H p 2} 3  ѽQ , w% D (\ 7 _>n"'s$iXP qg-i31-Yk,d[OAY٠k']Uѳah jjg/+UAbk}P\Jrm6:8$Ed>xeDdlatW𖤾}՞F򓤿H Vμ&")< gCc{!]tGr)nyӮ환Va:ECk}kNU F}FMLkpd-Ny`[=N|z4c$oD%ńRd8gS󮯮m"K!-")TW%*¾AzL/D+U.QyJߓ[:u)P D8DB ?C"ArlM2Wbݓy:ܠN,of( =% OUD qwT 4^ȷu[fwZx()}$9$<bh sA l2R")Fy5W N``N YH xC\V5ajϞS󏋿ƞc_9_?4ZC_b%DN/^J] e\R~H:V|JvoZ6ÊPhR_'4@rSw? 0_P3jm?>5JQk$TYT4X cfr|/ I|L21Go8y/ln(uYA2l7.oV! S>x@z3 M,Gqk)FrA;v_>8Qs\1d@6Ϡ mi  O tV8ik 3A/=_5H|]! :a6~\7 ,yY{b&Jp@) =f}@'zG_pNTr `hOA @Qf$'\s$  R? : ,~<^(PȶCe; kN {XJ ) Rta`Ƽ/wN*= _ڟOd\R[Az:Kx6Y7(&vlTug Ee6T9JhTD:\=0cUopyq_+ܘnIr eUzn Ua2lSE0o 5z[HIn@ʭ} e v q \9&5'R-oIYtUuw8:O!R va|`u}OQ6jDض=u/ y2 ZS h -i@ \\_zMw#osW7 P| Jzgٚb|±g,#$OH0j"'FcɻBxdHV l`H \w " I V8)cI;_%6 xq{_)uJr[7}(ۨ'kCt\1pꛊC( /{ MO|A:7J\ igʴXs8b#]7?:$햨$Ķ݉i?4)D63tc \am@sG湳I<&!OB$qyOƄ /n~?rƮ$}SJ< )"'f ׍ 7  C : S `]t 3! H4 n $ o A= k,OHm3 SOxv'+[w2=T"_U3C`"#r2"MtxثӔKgb<P0 ϕB h * T @ =1 e 9 ]m{>{ MH|z^0Iq&^{ -}iiS>2J4i7i|NY|&|z=%%0y}U͘I ׁ ', 凗N_ &ฎ-0 ^fF` m~1wc,֨I}N)&*Qg0t5<>#hN?6۠ 4 :   U1 !Q Fx O } ҹ2 p ߣ 6 H A ̙ L y  p  ?? n Ӛ / { h Z U ޓ fG XW䭍:I1OXz'I#]ZBaB*F$ @LdklFUNpɯD֍Zy@eC8O6NM(rTHAx6}6nW/6De,CMw)_~!yy~4; uC # g Zi /T\NfxNH_D+޺'4d Z'; R yN\ZMmG ;~obSbp>S nr2Q q c&< : фm5l'%i^Nx?fsPe>'3}-Ըs =۴ \p"IS/i7O|2XmMTJ:J5YfODf c`aEo>^uoTuAUCP,KdF ! EB-e OZw_XE!dEʢJu70&8TYKw0V+pNX<ymQHi@4;VwuC^ZV>3 aH%#vtN\掦|f1Km?X̚ &Lp'iU*پ1&)KH;$y8(=M[[i 󟯾"&'w@ry[ߚqEp;)P2}M`ꘝGxuFHrx#2U7F caIhΡ^|)xKd+V'+tKN"=&Z5g$!T9\4IN_Y(Euh&G? _IKqoqM\ScQdƟCUPF\[>,ǏSagR~VGs"DͧEd ÷]&$U 1E*E/)/5r;u|K^m}Dr19l,_WN0iK+Ivbk%f/-\A.j&mUBl.ULF[Hw BdNfOEi{H2qpDt8Z*p\8p Eq1|M(|g?I(9iFѯh%\>H#]9k+Ct_ /yk`$#,5ƭ?t07!o-Ao8l0MC q E= Oز m~>-G+ėOP`9h3cK`]]m %ĂP\3@Eɱ w bD< K[+g5 F<|ncû$F@.Ҫ͟jN Ɠ!5 27 x^  B  4jr t WQ kR hN__ NO8=6Y,xzͺ&Xlg-e/8u9WP(kztC;}j9\1QU+Y"%/xP\p.nk 0Tp| fjKK^:ޔlPUGq Q--}X(,5ѪU~򀺦^OxE*s",aתp0"H(/UX]><s8j{* e9R _%=/j5 }zR ]X3uCHV)4j `R?8P-Bd-сBb+/Xg/VԲ:5سן(4bKX`X1  f> 0~DW'{́S6O@Y0S0*y"|]C41ͅ X3Ԧms`"l_$!F>%sKig" k7 44SM Wv n %7_l2~Rug5]y] ?Cy |(| c&rGF 1Y x` RW p>bx(MHt^_ P !Dq*t- r,[/@4QBU'9!Tj4qn2. 4-exۤ*g6{,_gӾJǙ \#!>%@-JT[ 9+ r# \  i 0D y b 6 G`U  t d QRo8L <bU~/(c.Ab߃>Yl]&DA8|40E]?z s};? xm'WCo7D vU^YH^ZR h a ,s 8ig=X;/#ڈwF"\Qdyh#gm0xPR>*W<B6̄s!-ӻ<5Sbl73Vʍ@7n˘"췾> OqzښK ^3i53/K%iC^?|0}uY 1-AO@65mOw|Wbi9'1\PAns[d~x՗dWBĩ׭kVe yRIAS-Y,IeoS^hC}PÁ9X XQAlFH+ auK\+>ﳠ}R-XA ݗkT= !@xo-϶|O!ӌdQ ǔw8OU-;T^,a[%F!Teb,FmPO/hzc[ըfh*";[4* A } ;q %b?Iҿw`~^4,;F|i=-^1@ ESd`]0-pg%y7%ngI .] =7 ~o"MYCag! k|oBfif9 ǫm 50  # e 94 ^j ڥ   x< E " Njt  O A S9z4yK ;^D  Z! ; o * & &d M4*>uQ:O$.?4>f߳S0By b( F({ E_&  07 F >+ @!i29`4J?;h?%Fs!aLr1TȉA#BY, H o ĥ B  2OH=G<ay+]Kb! :U D~l~J0 7G 68$ # = iUP~=P82>`p F6_م9g nG  Dh/S_~5j%tIBVb\ϥw9ɡ ]^#w6X'?;ܧB3u=\21c~J8=ֽzS}Їq3Ut^C'PPuCONkxp1,OlJ*.%ŘꩵR0u6 `v=2Pt/n ny0>V('YGS33M7C)r?U=@FU&k^*U3Zd BR'oK$#U8hи9k:ou4 RG5 ܑGϑ G0)`6@#"\NB#^CpE>=G[Udc} AdbΦAѦ*|qqn4h؁W+UOAiQ pvX Vj|}$OKb `2 P S J qK7DUIdRo* ڿ_3ed1`!¶: ZF@3wy Y 4 qo0E7lL %g%V.8C0.5Qvsl:~z} ^\ZT7M(/Gd:g"oTCsj;.YQ*;K-^l Go'##~D=`k'Bj-gH9``,=V(O0/1i|`똔Џ^:rq0+L]T>dPܶdwYb3^EuDyt+ ! eǣ \ K 0q uw @] 0\ ο ! [ dۑA#C`@mILenZJ<&pT{)[J%2 !I7= 1oKDn07R jyt.`2or*k F{+o.o0lm.Kݲdf@uNhlvRaE|P-y? wX'4 Av&DV |%tTgY_[.+N9jlx`I0Nh- ^ @|QՏe,]fny_:k{(sYsJq)BN8q:;'}D-]N>ǡG/&XQzDuvm@.P`-ܲ>F BtX\ox$8jH1+G9pX+rA+-4ZL(u-EJl%<I~9/{ C󊂩u>vym Hw'j'8-t QU4v}r ?sP^Xv_ i"DB'pү3gI%-p/4*ϑ&}!'Ӽ+տI;L"5>dw|R \tHҧVk,&0Y(L);_tK]l?TX1hgu PxIunerME>tf>ˇ4\2TUlT~ⲫJ`h / 77DsO%e}3BXF_r|,K>F%%?rۺՖJ(@4; prs A%cdlH&N|6yPFW4O]3K~q[8h ~Bv~j-Jƒ0DUsfE^v mN@ %}2v0ңQKg1429f blbwRy=M\|c%^&#fFpV+x,!J!_p@-I,{4";xkKO3H0_`2K22P t %h  ^9 ( : fSG Ő hjSd3w{T0| 9B G2B (53G?URÚ˼>%)b3).d['՜{0HSwu=do[$Ï0#; ۫]B}>o xώR 5S᭙8-~fA3dv0z-RNa[l9<91s@[tC}U j/&N$,)[tV"㰲|D`zݟdZ}׀-pCT`{c̏FVלknOzKb.bOWJ47]&7%5RںlaG'`~I4H +$B] #;ZY@V:(9 h'1qA~29 1 `' i}G/Y3ƒm "/&cF][nKtS+'+j mI#Nx|Ot0g{zk>Vͬ/5/{k 5eRoi<hvoD%bF^hxyoricX+ )e_H<'Ʒzc!Z6[/bi_mTiX&]WGus,?F ZFB' .ӻQm+}sdd{U!y ; \ , h ܹp $  W h   ,, _ l H( z\,x y#,r}j00u.WsƿpEh8 O@؈w :`Vܛp 8U@d,T<8Od6Q*.dMeKr̈tĐn c:AT1CZB2: 6Kug{ϭ1 Q7A{AT.uPHq*"zT^= v(ݖ?hői%&ݴ:iAͤNǺ/(]U7$G~72av'a#88gE M~,-*TX]'E8R:E}K벓6b`: irvtx~RiPV'V]P;BBZK+zRׄ&GоZGaҸ$o6(XOXú3?=ydf€uˇ@S^P~ChTO"@45;b=V]XlQ-rD>hVu_5QɜI.IԠ6}6>tQbEWtb%S] DjK.2pr=ɼR Z$y]#9~B%i' /L#S}ܱap.,Xm |wOM }a5҇q@.ψEfFbMſږ r8+$z9bU_$ ;'CooֶG-M^!pkϬ^IA=5V,뭽%?Xa4 lV<XWǹ]4 ~_Kt1J]F=w ,sUP~tg<Bu %u)0H24fUk аwO|pv֋ Hy~=O|{)th9̨on*,CC6:~f-cx6B L@ h x l [C b93BHcGh힃iE\%A#<?jsiDOM'9ey, " ]  v ! ;c  C z A c m I9 6  Y mvtNt~tKZbfg}Y%Ϻ+jdWWb5w<hBB+>x! M4H0堃wn,ì)& w 9T ]q -  F 29 : M ٝ/Knͺ%0@b{7 ` ͩ`FPm^hdL7gXK?V!B9X6eH#:QGp zP\ O}Qa"|[fHL<--RzI ^B-,s=>0u"'Gd9,lISlEyy3jXexUJ?I{iv+?hD(#-^$ `ةRE{aC7E5HQ~%V7W0]AN ocgLL*8>x'o]xpCao2;zK;5&b ^jd!aXÎnw+n7%|" f$|1)v{:DW`srQ8[cytɈ Vu?h(Lv/q}wY>Pb%qm B>Nnzta J4 ((b,6BhlD0>qZr)9'}m&'@'rE9>0}A #p=x9<(V5 QUG!h6^]fp|6 J  Ie h K ]x ) f  Ҡ  m Y%jOO~q|>ܰq h8 iS{EzobQd!(*]1݋pōm(Fm)<Uй9'qQ.RUTʪBH7Mseu:9ݠm}S=x]Bp(Q%Q}Vy]rA}ͶD F q]{T-| 89}j%@"a "%%5*JZ_XmnΩ'DAY|W(hCafWFQ%IR$G;o@s_EPABS[12 - *T/.3 6-Qu|yOQ #]AE9gʙ=ZD]6/`d[W6XS0ueL ^S: ;#',iO+&QGH+fh_|ةGe ߧH̖uY2g.n&ԡ?k7QYtOYS|P@ ,; ]O]X*uY3LJxl Bg~iw%Lq ,$} ^/2p1זj*4LxB_Yu+z$B5K~\M/]P",`IgS@<CSiIL$S~Mqpje;a^EA^3aSrk~AfvQWT DȖqz_I%(7 ).m >n-] rdҝ0/%Κ-55 8V DgOo*e)5J!&p>B Boa5~)XghpkJCPr0y4um8wr[?*NkO&($5DA> So픱B[pz G!8a 76<Ep^-:+FQ)[fuhmZv%WP-l2.BYNoZp(IIv\#bMB(ؤkS)lfG :WM~Ν1 K%r8EA e(MD=ygy?=E07AG.ܶb|^Mk^(i ٯTLE7aӨ{YDE*@2Ia80tBpf)m,W+N{?8vr]<'*iFt>jU)lyYַHLN$QvPM~T,MwZ +/ INvwlE<W7;L]+衧Ё\uDn\khcZ@K4wx,ŌHt`TR YWcjᤆw5J]172r~<r4Y4H H8Yȸjd{u ;c iQBfCT~yH{|R!K<dU* *wmUZGHT 66{!(cbbf61.sl\fi H^6Xbs ) NCR$Ys;Yl:TϺM"HR;HöMAYhlc{ޜSyXHQRctLG/`hNniO|>6590@UGSMDOOJ%yDr=k9d&:"BSGpe7Nև,sE2b- F:g8EDA2m2K8pWRH8<%h#OHV%:iYlz~:Ŷ(7P.w# Vwv#~:JHR3PiGEK8%O]k%dT)L q|m[LTMGLAZ:o9aUKΑ9il^tҶkJֵJͷĹE`$qw]tpmd [W2Y&aWp0_stܱC7P/Q|BJID/4 &M{O S'?zG 4Ms yrfO133Z Nme*&|Ȕ}zl.s?!T$FklwzX "Nx~̵֛i XlXHh:^Q6Zd%0˸O\ [ncF&,T' 0lE5"WGe3pQx~q ͆|1Lj|Hy(cߤ~O -%AUGk!ׁ˵%ݍ;!K98IL[~/g'Qm/ni1`zNIltFڷWj1, EUZ]i-sؼxlm{| n~w~*ц¬DΘ|%8$ 8qd46bgȉ?yq=jexc:VdhqqNxz9<%Dۣ`xˢ6&:֥{քnRU0yQrH0]jkb!5DJJ%JBө5K%~"Fc]DQ_\Um}ria0*|L6&AlKlStY<]q^]{[CXT4Q6OMYZMMc"NNڋN{MKH7C2D= 4-' 6-yQIFۋhFD' j2H58 tS$p.59@;Z:H9|E9;?SHKTcs/ʔ"~,.ʿHx |ji[V'@D\3x%B ~YgmX4 W[mt%=W/,:\HW[f^t(Exv}eQ<(@9=czn{+ ϶p Q'(97cJ.///X{m)!,:,H*4Vb:l"s uprLka$tUSHx`;g/f$'f +/ ~(/D6 SW tMO4K];;"x.7;pG*kTASan|߉Nїӥ" ybmX"5Hv[ߺm~%K5k7 SPfBQ|yjW?D0;y 2O Aާr^'7?֕KM9ëg+S_ %H6EFRZ[bXdd`ZySK0C;H4-2' pA0 GRk4dNܮ uQk DŸ^,CEcK#"8':,:/0s1g15s0n/J-q,`*'*>))n)('.&^#y< v@7u?A! nL,6 0U\J!SJ'-Ip2)7&;ab>@GBTD'ErF 9GJG HHR~G;OFrD3Adz>):^6IH2K- -)$c !8;"%--)ہ,sy/k2G45ZH7 89:;* <H#<;s:h*9s6M451-l*"'$DN!tpTM3Armw=9D=)EJAp !lu"*#~#^#R#"G!14 Sy$%3t d  i^ 3A!Ffenrir-1.5.1/config/sound/default-wav/ScreenReaderOn.wav000066400000000000000000004313201317357605400232130ustar00rootroot00000000000000RIFF2WAVEfmt (  8qfactdata2yZٷ..Ɍ0}HHz ҧVfm A: ]hjiﰐd*oDaP @#|0EΡۍ_ΰU#N"rgK-Qp< Z9@@- ~k MVhpJۀ+-Prte5* žhE(m.D5HJ νOPdDHH0k]RvQߟk+!Ԯ Ѱ[* 89))Dl /gl$Ct +&P/}s%7h* РxW$8=a_@, #e~*T]D"Ŏ!ws0ƶ;B% ,_&h#*Z^/gJ9 F}V!Rv2g ) gcUID?=3=H5DfB(;b_sܯsfMiA X Hm|_Xs&Y({@k)l 2 M#w},%2,'g!5 V%Z z*7H'YZ&MSh3韸M8G/ :w$>tv4u*o-,-5:\5G: )M -Q 1̲.n6w;5) +#1 6HV`C>q5_`ַ["g$j(קa?-Ѹ=Kg?Yo@ S[B?I\p UN$JSyE#p"J^lq7H49l ê ^@ > $ c- idgN!~jܱ8$aA&rtCYQ 4ƺKpd. 0+!xJjNC!d!,9Q`^V ѩd %<<%oHj ImLEarԵ 蘨#` VQ)q%~e)Y*%V6<"%?̙ث!̣LlЙڢ!'N$+G%.= !I,  ھxqwn -m₞2wịhϡ*]ۋb1Z I*g&5;BY@:]n5@·9oɥZ/={75uZrW5-!q\g[rMp,lk!Z?Ą J "rȅ gH ?t/gi-o/r \8痒A췆 9DEߖN?х'DP<YOPVީ&ЩLp},A6p1bt3ΧʡϲMܞf!Α2ߋՌoDTD$upD흺8GʧB d*c>KTۃ`g̴Ɇ}.L行P ;O/NgqV<pel4dFxz?jKl3nyv/D9T(X-%Nr~XF Hwǔ&ov\`쨲r 6K`d%?<~v"SQՕ^rƫZ=a>@_t%lo:3:ð6sRyv(p2Pk pr&k|*3= V,nnPmUCt0Wa XҬO2zFk# ܢYo+!,!iǸjW{QWA;+( M eJ hFU/ml WS6؜ wKBB 6hw  }X!"!O!Kt"xT&]vK1i<.6n-*1tJ[@s <y%JmGM f!^S(}G ~j[[@l{oeFL+XZvn%xyio9#p R4?84V G>5Yhheax,gCqT`:(Z ; | BL iSaD/"6Mr܂y)a>xq~ ЕL!T N ?z C ' Zrevs  +"*;Li~G 9  "'W;Mvytޛi ೾eJR,d˛'l p9I i=.HV^ lg8Ekx(o%.?))"0 ;A5;g,Zp2<w7 ٭{/N zːtNԋJmE Qa Iv(Ⱥz:2o!B̎~:D) <7l$c8ZfkRې+ s"'% !; b7 `N"ܨR9{ R !&ω9q $xy6Ee@:!:Z/W.)e2@sU6Ϟ/0&(K1G/4:98:/0`% FU#' `˛tӒ p'F HC% ZK=[,k `eQ]ݦGסT  F . OM.%#2nPp+gdvjJH-β[hU. ɳ^Y [U$ k ToS2 .dS$V%%s.w$9 zgDw&&9/I!”>Y+gj%"@bJ,DU,|"* :K$~ :uun d 2ͻHE;MY $? Dd(/*N4w=319 v4p@3* k-q__؊@ى7MއWĄC\}Ss =ݴz^e蟲5|A>HCE7=$e&}iڼҬWESbN#|G$DN*CPZ _^Ah鄸?\j |!(=0!-@ t>ntPW8L}p۽v\iիMa󩜛/z G7 B5@ v.ە>YmWS~HU5gN\¦\ޥܫ׆~D=1;`FDlA0WcaT1d3$v  P [-kIE5 M ;e 0X,zgWÔB(*z2![VAoײH'&] !+#@XCh Vp|  E-G#C.Tf [N `e-Vr0D4a%kp:NlE| 5!0%t+&0<+& -~i-(ElfBTz)HI 2;d&:{OLmFKwq`v{Mmh¨B,' ci{z'!ρ (Nb&ς#"diH>6&l(Wu#Y&F m&n6#pZB! g!,V{ ŊY=n+ 6kI/3 Wpbz t,ӽ7a8?5| /۶)2Q3\3H*g7(֧-A0Xj1L7!8444+ *p\"/=ˈC OW]( @i 1 f\| )!e 6?EkY~q$m 1q  : t qk{n0v}NA.@Wj_xŀa%/K 0\v ' : أ=a ORk"g/_W^!b=<;Htx.ә5 yf ~/A DTJ,[#F99|448t UU0 X ,1)~V^o+XSzM46x"_f8|Oh9ab WWi` cC޵M=[D[ոv人=K驇F㍮"^3FmBn,N265?vr2iT<W*>V(0ivԠہΑ?0ZϜ5sߦ๓:xr5qN'VvS~362siţܯ(чI$8FUQ[dA, O{f/O .RB`1M]%úaf9ĥ#ٻ3 ;70, *$@Tl}=q36XWqRdS[W{:/6e1ؓ/ۯ_GoP*ЈI\p͕=λӓr]#M:'৺괕K;c'EHy+䞕"נPVnyQY.FvC6\+B݄ ԋ}xMJ9s ~ TPtOdd!A.f/w@M?pܯK(%o"FZZ!9j z\OlPg m1R^^m_17eT[ [ݢnm߽[cFm)3땔_v _I!IakO6 N !cYbq~tc 2 h72xj H"ވʶD ֔rq dF!Ķ& " c_Ig?6 /w` ,2.}*i)^7t%ZJeB uXW*!TYi ~ȃbFqfv%­ xSqm jkm ˂{Ņ L#HoIK*~i š s & Oks:쇽aE9A yv Z, qZ$D2U'?6fަj"$W UFA $![#9u%u!!5!^/ mie [ gMs  ߑj%Pr16` 6t9R2k031b2#/8),.np03&7n5͗70&\}Iہ!\PaB(*] P n Q%EBeI}x~dqN81Η6=R  O7Qu.4Ģ}n7>FN`N]8KioW $2 i Yj l0|e[V܈k1fv,?RL*/08@ȰL'iS !!'^ kЫ,JU.u f : PCLߪDPR30w9 ?4dalZ5Xk(5F:㯜/zҡ)Qg[wP{9;iBfn%ꁂcMOt{7##j>H)2vh,h$%oۜ_J9h 1bx緘Ҋ@J)Ie8m`'U yOMIa+ E3ÄnVA&Xl}'b=uqCW-:X⻱jp!J|2~nzi-zZ|WHÇ4 / Qx t}&:B#j!3@ (#=<hR^ҹC$&o;$)t!7*COR.yQJ Κ'.2.G-J;M uі5ϫ 9VPpgOmaG5 DPS=%R)h,Y(kUm!|}&',r /e3Ze8 0$q#iԂA%`$QPk]7uLl$컖2:juۏ#v T}  ^D ^6Ok@'#}Z󙫁&[G\/;-nnB h^ !! ƺ5 T!6?lsFK'~:~/y&ˆ D u~.arY V  (ҟ iANص3# d%IΉR8ҙf bW(*{ )"zw|K9i ci ٺ W#5c,jhIr p څ 0 /G \gE 1P UپR jKVLW-KAi( bdSD=XU `"!$R"E!`c!)yL =c+:R ` c>[^2Q{n3)24Qv3JA1v12>/f0*L,u*4u- .-14k 6 pQ22r+K"Ki 9x<g zs0vrt i ɼp13 (fjTAUݣ1pMq x < N sO'lW-16'Xx뚫]uno 5 j J0 @ s_+ vQ hy ,q9tݎFS9yD^z:7_q P {O\su30:ZM`E, :^, /b=m=q[j 1XrYǠڔۛm-(Tz01IniKY~vmUQ-.O &z}tR˷T !e,"°Ŀ_Ѵ$h6sx<{ͬ'y%QVw |`n蜖i l񯾩hwF!K17ɁZ{TCK`f6vZw!*V{#ypb]u!HY)L'M;;SL`G`328;af$.K/rLnTd@]f6lʨjJ>'bL0K+^=ti_KRWb|[a/ 9yBR\P7Ő~/Ԛϴѧf8bN9* B\JT[ݖh!8|I`JrE?mkϩ7{$[M?nSsRa-Л8G\@dJޠ.W|BwUb(s(  * ln^8N> XuGd2E jwb9X!A#"GCKU T ;1 _>zMEpMk/>1G! Zu$4͔3DK .#%7r6e@(UJ"&&*r=*$~jGrDJ Nm. @ڟ csT4dr/h>$*NTtk)0.[ꃨ]u1wbQaL%>xݵ~d:Gs{8֞=r7ߒZi!^*h[A% m }>g  < ":Nene F{^ 2W` (95<€ D ϱ[(@D bu:Iʮ+,I=rQ/R#=d!e&Һ1gD:|ip˱ cX%@y(N0/;MOD>a 0̕nV`Oc D< bs  b 9x*0'#% ^ oRv0M .5;.Sh~2  ".D ٌe z+v,d"du97$iJ sIT0IwjwdXBO{icrICHs%lbK"p9p *!B"\)# !sڊ!&G x_ ʓ 9 bya{ c[y#Z,Sa22x11210-e+e,z-\@/2~4~3e.8'v !E?bw@Ǚc1W&Odb@{ ["J.}IH?ڼ逍0@ U0 l $[.##C!"[x" V" 1H>&* 7 o ^zL!) 0 ?K ~~LgKqRaC/HD9vHZgR{C#& ?N7Vf3-FCx7]pv>X\<=&Io3yey 9DX-p"}%lqM1MemgZ׊ԓw][飐R>8c=9Tjk*0}l{@:;杇P2҂m^m3E'a'2TUѲ|]xHha 㯜gwtliۜ!|)R!@M8yW=ꦠ)U8$ \[&MEU֌'.$RU}^szsg؆E a$ٱGs.ovZ[ADc8)Shӳmr0g'0vπ%'{$:.!(t\sW=t}\Ap'Uprrm'6V&ߌe|7^ӇIvls2֮_T؂;?4% $-8m(f@ С맲bhH%XK,r#aqp ZZH\|>0&s5 HUҖDhvg}7c}8Z(E}l0*qKT)EG̟NM% !iI8PY?t\~X񝵡5_#{A1CkAjf#*R㺅_V`L|=i>=tms:sϗ{\}T9s{ ħ6 ,*:Xv$`oXu (BȀ?L"c:"? A^u]2BU A4e/"V$E'# j>dv(W ۍg?zkJBˤZ[՗B #;MB(#jk'M)1&=g!Ѳ`fK :`qa 53qb 0LMA\2&ÏL'$mäUpO)w7XA,{쪽&EM7gjTfGx{jPI#^˝,fRsNiewz\G`*~FIIn]0vMO PI_ (ħ)kLq,O8SՀ t,+a6@uУ'.CpDv@#7źء$4U p67Jˉz.2|(@="ﴲ  AtgDg+KZYe+/]+@5M?OAgߐ;䩐*ʾM=UI`RE k"z#%ɂH'-eLdz04;d;́$w/ܠ7'LOkWjE d֍ҝɺHܛLwwMBj I\Y҇=tJJ0oIsiD@5˔WgU#¢244}^@߱Db)e+2/.4*q %2꬀Tx\1ԖkژfFcݼ8_qv D݉P+kzhii*(!P!dM_!`=J*>բU(qtKqc?bMԉ1)XCgL0T1MDb7{w;o-%h"ڥa ex/TTSSZ). S9ZY= _)xa!j NkChn*%hXd6  hz.'`$% %ګUL)q˔&Y jS|?h~* [\S 9h;'F:1!90%\R'{}'M#ϨpjJne+WW!  |] j }E %=0pmLS ,І*3rov t,Y.( 3I9L&1CÌh5q!V{74ƃqL3H:KVQS\4 i3 >*R lI`To<[ 5]nM987D؇.KG[f { ۂ4-d!ғ0L zzR CUx H`+O2p!҇8#X Q%dkDڞI7IpY5.w' 8 hq\q\6?N! w Y'ffԑ[&Pκ i 1 e NCBGB5hs֏ _ 65-yɳxOy dd']o7 m / 3  ̱ SVpJ}R%N F U] Q1ZV^X@2E[QٽZo<DF1 q!6C!!8R ^ <x rg } ?9 lѶ" hXf_!?)i.S*01 `2YF>Nxv򺂻(Z 5A0e+!oT4m|K1a(o Y ns[_$EzX۴Gj`H$Q1l;)0r VV,vv BHr rxHS.21{i8vj1+4uAw#$7m9#VKP)솴%;kݵMo J۟0ius P5z CE b/ {\6C=ffO\2hGW&y/;Y[<Ϋ_8>P S?/GU/>_⑍;齦o@< QqN䶦[”8Y ߙƝbh2уӷUֶօ=;ow)^aIG;0gIjӍwIr X( U%-RF஘$ ErD I[':UV H; 9 QI$O ˤ$O w{"it3KGIz֥Jet6W"¸E\ĊMDG41V+",O-h+@@Y> /$Ldl%w_Hs\sk||mhV11hO$iW_/06ܻZ#) d S z*LM_e$1 DWNo'RO^W9u[(oJ:]\oc9" E[B98{.X'M{' bF^5kk o1$ p >I 3 *ԸX"'O< EJP Nm6]1k*~B!J 3B 4Cg)F'Fh3/h ~ b^ _a Ӫn SHkg- "s+$*m.B//:n/Jvw/J-ێ,}Rr+3a+i5-G5/00.z) %!fvq[K9Z@d G UBn4ellJHIhazIf'=<3p8AL@.G^򮠏UX[M=4"| 5f ᑛ B :yW sS p9 #Q Ǔ04OYq[(cl;eOu*Q ;RQs_3 bb1 sz plj>A;'f7Fy&e1SpW4%YGOG  +1Y+7pQlSa'?k?(3nb*B n)1,f:|7uY%nI*t&p 1( *eЪ;d-`lM]m)RXYESn?vnLtb۽zj`!~^~,xTqʥC>梙nBtssUZr9Bs?go3=<tW`9yע0Mg5l3]V~fA?Y>92y9H)Dž;"c:7*,"\0N\F% FMr*  %} /|ֈYluA)s4L`!ݨ{Iɔ+ܶʘ")&>zPB݁9W)z loa^QyR4dCႄ8 {ioT웢1t!o5q4M,yˋ^b[bd7=f2s i C6f9S^fq{De8#AʹJ?OhX¯sFW,)_Z`ͳ,ŝ/uGO}fՒVJavѶ}'*Nk~6|mF&& DJKC}QXw`SO vB$t-:ߢدy{p^@{B~ Vmȣ/Q@ y[@LTn0 sl.]FPl=Ps03KB~F-bN9b EP!jȈ# i@[M|!_#%[:%g8q"{4 YT- ;1 w6 & : ] / J/>8 T}EW^|52,I(Pl t gy_nWKvxb@7j&76#DJl(`Q 'nf^KsR , F2  M A VK ՟6sNK;`S':FcW5ѱ]AH3UM*$)dS&J wIq3>52Sf\@-b1'ZZ+3ވ$#ܯޤ5.m_Hث伎23M\tΆx.ApW"Dߥ@>ϗ=Ea!U5K,"?h?BVB;]>+I6EC +$Kg4,{bH) 9ّRߊ6$*"=v\{}T석k;RaHGY\w mp.Ҝ.KC(Jm Mw4 (s5 ayeM ܐ!mj6%c0Hl3m)2tݰj+m|hPR2?NB$`6i].A~ \^g0 .X)(JoT Tqzi1ϋ3ǫOoXK_g?dXJ\ /icayk&6K<9yCD;u-J7]k4xW @-Ǯ*!4 zڥ (р_AG z>Z[G[F Y_L|`M g 4 Bd\9.GWF4*tyt]eVH:dn),6vf ^Ť7d<$7-+b #$x0H#t P ; "/ ԛ` Y$ O8௚#r|tO 3NÍ}beUB}ֵNȈsS㫾4<>Q 1sjF%nU&JmczƁ;o6-Tv*~B_ځ~EsCju7|;E|mcY27i ѕ3jǫn" .=m 5 $ 0 Ka` ʳ p k:C$(f˺MU{ ;t-XI eq1&WO KT WF#e@4|Q}} Ox k/|Oe , R  B$cD#!WyTH`] 8 | =L!a X 1G{G:By=½{hY J. LUc= ^04?FO pu4ARUR5<ZUX̉tyn4M EFH }z qd( Y˓$a!kqq'S^6+)-'#.D|.{s ., +C +G3O+p{^,-$/.,V8)L%{+5"tt (n4 ~G1خO ^ yQ03UGm:qxnmM9ԍ?U"P|l0dZg 7F~=],ghmușrYeṞdi[%)[RZW+;Ay{zuY">hR ),:2CsG"K(i/h8Ϋ +%*hhd㴊B#~gn<ؾq^SRת],Lޱ rB+193i{6ha㨋?1H#]7+ѯ2g%^#4_3zHLJ^WٯYKVX}16[?"=St҆GR+G'x:HL]OA+j{bPrsQm靺#D?/#F1}swuOTh]:?:l3 *7Fdf!bΣG-_^o3XPq)e9B-.% ,T ޙ0SJ#z OB2]v,;SU>_# =6fKpDb.& ϝf|v=}2BI~vYS V 0XJ Q+lWBH"?:,v D;$^COWϴjV[n P/g[8!!z#Y#R((!ozZ20 © @2 ¢ BN [ ǽL `ګJju^Y&=6cv тǺ;r 4l*y\CJ\B?<\A't8dT>%GH1V(+_Tx{ D ̌ FA m T _ Ӧ/7u#97(|++7T,-Q{-&,+h*99*i?b+,,X-d._U-#*D '#G!>ZŜ3=+M :AlEr/ 0 ːe'EI@TU_ZxM\r GDxj-JbHR9/pdTZ i3 }A  .F t6 h",CD{49i$ׯ-+ 1gC>jkdt7=^vq3I(/_g~#ƭܾ* VJ &&S\6ޡPW@m UD4$.YpXӆ&z{SG@lͨx4 '窿qx_OU?)PAVr`o[a-E's#Is/ok2%7~㲫ޢޑ0U;w %(M4{qPR<2sEJvz4G8nK5@ߵz|5۰a2sR‘ ~vjֿ0նI낸`Q`or0usvJ1uN _׀O,ReF~AɛMʛ桃Pɕ솚Mm;ㅝ]ݍ]ڭ&?oWivZm.!9¹܍cno俾QpvAE&q13.fgDyӢ䝞@ȯu@$\4]ehT+1UY=V{ 7tZMrxpP&c0dBB)N-׉pyKw32vAc7H^R!^ʮɣ=!~|3|tAdLjcix/G*n3q|gvRv󢻏sO޿a vSwsIi/S*`%\H%lfm.,mX7YOk5# 7p3IxJßmp\4n.|M0 , S: AZkd14z*N$z=~;g)1pF VQjkX[- g ;x=j!"fK!Pt+xyFOţ NZ ,2 m [ [\ztNDki gPT|J6~NA]l;ql{&{6hkO}${yNs^sAyq&kI|@-Yٕ l弣 = ;},YE3s|t#U @;$:xeS7{<LD4w+ bws,C   bk g d  a ` s 4"U88xJeZySւ[) e AV^"܃^t6/f 3pTM‘2#xO`Z  6= r9L};u2r5g^:=EgPö  G d24dM-1V ^+7m-΄0T/F)Yq. "mV]66|'e?GCO_4,]0S~.6`andYVB \|IOxRK ] ]; T* ,o  O; CO dF$_(5+m,f,۳,5+*,<~**T+],v-yl@-X|+((P<%O"JbOyvXh]ڒ:P| ͊ T ڊ;X<4m }rK&'膥d Q2%Sp7cHk.{>sOB]SNuy@rsxbD x o p -a O#\~Y)o1 gȖ99OP(lIh L 7p&~tʾ ,[E*Ty3G _ (31GR8rm$Ǧ*74:F R!1ًY7ԋ _'MwV|sK_2驂EVu| }(y=u#l]m E+0 mvX7l-廄.z7jߟPᤛ C2tV S=Y"|h燙*bdRDڦs0LY<v 2.<`9 /U/9i+NK/O>GDW5`(YHv!iX\^^ >@{;PPQ[=ƿORdC ^sϤLt7C镂R.H7M=tۗ>eBqj鶇ܣ| ڍ#غ1\Q.a1|h .[j,LhuKOs*jR]8HyirPg릹Tv2\~=az?lz*@%T\#+f߂K_c܆(Wpc$uuہ޴~t.o4DP|x#cɵF0myՀ^%SRn'u_! G2kt /8q&yZw19X0W O h2E7L^$&|xI>Û~|IPE7_4?OHwԇTlLQ%qoV-u&/!C&xa1s/_WR>&Q{-g8dHn *5KsՁ2{bt5Jn\RTf1(&:' t Eڛ  ] țy $ q UUXQIxq=/|_w"?3L8H.1%h u 9ϧ.V"&lK4#%V 3 )OmGHNA Bz ]5ؐKH5ni^|T!kZg F QBt뜑] 'RŤ}Yf  ) ҄fZYyaY+k/Un  @!PK|9;,_4#Mfn@Y&hx^ҬG/RS2W$KY}?$+Z甪L簄~~ }-T恬 :4 Vzxgmy'W+}K˿Im$!^E tϹioH Rh j  j* m 1R/ \Oad P_"; < (USt(l.;;K{gTc_yPvaīqW0m7]TU7/} 7|%=ڌ흫V"yBGLb#8n&5:bhK}GS}gVEo|+@^c Y} Th Vw :^ 6 Ӡ> h 9 43*|N925Lh :73C6F ig 6a H̶:5ǂ ӡ A $@pWo / V7 !IQ XgMryN rF " ѐR Kzñ|yX"MKL) Xz%L "!{튫 F0m(k0 ͑[':F$='0?ePK"V8sDjg@dlDxkO:Q6ѱI6u"})a2T/I=T%X|=Q5@j(-,*\N㬎ݓ ,jنYXڨaeK_ҽCl[)ę<{YY.;)W艀z5lhUmQ(w(3*1b3 +o9p]^G]z6x(>F OhF'p^s&9ݷTZk0Mr>@ͿV0d?zf#}7xTD8aWqhU 1u ֢6r3@pz8Z큼 1y X`1rn$4!MaTLs$n|HGzy3ZB+ @3eJb;> >M ; LX[J} 9 , lŋ4 /o 4LD$)4t -Y3'%J`XOd5Cc\;GRs΃!!  ʭ-50 `QQ - GWĐ#I g MPx ? ,^ tK@}Q"?vBB!d 7Zp~pnZbn,qoe|fD %,sfZd IxuhPkQH£wKB/JEV\z|&5. o}jre)-o{ZvQ9Mg2?2 q X 5/ : dO ÿ 꺣 Bq1]10Тg[  W8No|VmSJ o 1 )7aA$<ӬVJ` 6K 6;0q A0 \" i-Ab>!=ɮ{? [ yB  pZ=Y4m4*t0v} ok"c$Zi/b9h/rGn- \ד/{?'+-xn/}X,FYsh@0U@2؋A**0 `AY rH o 0 Z #l rkk6 1r#&G)sHM**_**`I)a~) )-*:+9V+Bz*U(&ަo#- 'lW•l?E_ͨĞj Xг20ؒ4rD FkwAa ^̟ hWl:'Qc̗DLY͵h}WY?+5XaId/~ nP D ?aP4;Ph KsL"[/*:_'υ.AUjo%( P adO,6)?1&kR'!6XV4?%tM"*  e9Y5i_U[30a>)ݼNC(id6T א6mVs9+Yä鐪#)skW׫ҨVȆs`G/Goh9zB}rn; l/rzMBnGCYK$AMҩ haL\'NkCBF+`ШV=O'8o~TW- 蹣ѓ{%3TqZ*CRν1>pƙY J3bdc͠E+Wpo1xezxké՝Ⱦ  NE;w%HGNk]%;S7J wzŢmILc >"yo6OyH<ߦlEGg{>ڒ JބKKᶷ<ܰWeT_wgQ^OfXSVo=;COH6膾7o/*Rl(!o#^a 2mdGpkQ_a;1Y*B9f̌]&1sz4>L{x_œ B!]'/BHJK-Y'L" kKTsZ?l}%C+-黂LfV [x-cl{s,[>P u97dw y yVoO>]Ws19p`Dt orΗ кGVVEl߀z\Oxi;X-Y77r  ȾT ; KZ hG>\5 s PXzN S3} H'jB8V/Bl EO (^ GGk1{:GɡYx\qږv@N :d {0ݳBQT]>Xե}\Gk@X|)jw>B ) L n  `  y2@wbyf/Is_ ˝Qx@ ӗP4> DI Nxt[ ٣' P 8IYu%(~`Л Y8 i}=%\j i  _n jJH6ONJm_J |^o!#Im. v] ֽ ΖuJlBHKurHcbrW(j>P5ͺ6{'O\Չ Ip X6}fn{ r+XuG\& z}2 -_ -!Pȗ=&b-˳/{  t _ c C  lz,z] 3$$'QK() T*)#Sb) )<)l) _*&*;ra*>)^'$F! ~ $E Ykxn;~Cf ?1 x[Uef ,V+)'c<:>kO@?;DBR,]0=kOj{ujx;Ju^4w9xdVM s  i|\Î!D˲Syw;;h?|m @h~/#2.C{DbF[3q|NR2qķT I-r4B%\ V*k:X߲akuCq S`h2sE8٥l ߝ(紤1Pyλ4YFV; 6f*:ǕQgC=[+sIz]e6##=EΎȦcO+x:H'ZpjfW5`/eN/!jҒ9qIǺU̴>~>g/N'Vv[^fh=wҏ֑fT@HⰉyXIw9⦉~z JRbD܁ȃ*ջ ϷOkgF~,ڞ։շ 9mtپ Qg,g>QڲۜݹGˬ̑EUp")0!vv x f)8 nD Am%z.ȭ9վ({&23Ē; >!.]8<yu59y"E.Z(=.JK#'&xA! vBH8 +˨P7&:KB\<ގ2F"ҔȖ Tv/$2 0O}J7g]=ʉstP?8@~UD0emI,Dnm Mz{Cľbu0P t{_BkYv;* x&*`[BuY!2wd*(/i$F)>h & #BR1 Y@<: &z?c ?@P"ӱ-Ae*?NMjQóK|CqEKŨK1AZE:8FB[0E.CPGG ?%#y/mQ@?-/O[ a~c ,KLp )] ҍD҈nEzQ $B+`TiAKXiWA23S}}VK7VS9w {Y-*oչLWи:cߨ&Cʤ#tez2!2%"*K",'l;9FM~psqlVdIKt } )Zszgp٬!O=ޠje"qDe!i:;Z菸|vRmMɚaƃq0~֘rfw Džd]g.:X9%:0_\]} y._KឡX>!jǾhk0"ꐫʮ .'ݲEZ ]}αfDZ˯Bʁ;E۪{0ׇk!֧c^ux\I:Ƌ0j}kS!(! Y.`]΋V_s7aV?P ySV-9?D$2"3 O. f2%:x^ X| A 8e)ҝ[h%c2';ZuGD g;~߈ WϖjW cǟN"ֳ$ ?Ɋ @w W :l"m*R!Q;Xu  q9?2| H[_/| #;E.Va R] Mc= VEk6H #IhM'VM]FP:,D.0'-.%Llr ,A71L=E뼇N )<{ 5#ʉ2xYoHYYMfﶿ&?6 Te$?b L,O)a`'ha-&>hT\XLQ3&޺C{/|"5'nS** ! z @ %) 1[ແL a#e ')s+3q-){29O52L1%D1һ302O2T+sQep2h&DD ZXB ҕ}K G\ 6;픍%Ұ,] 5.k,L.i)dsYm*V)QV'MGƆbWמ%Lev1V7|i"bOkb)m%ib\'ձ9TۗhΞ}fȊE$)mٶz/ٝӸ@n6k]Qd+t*?GpOTgo$͡ycޝ1ژކW+Y-KZ"6;/!w,,G*b//2^F5IW{3B|*NO/ $I3l#wYE)* YL*Ndc6 {Y (5}(,kE;R!2OaZ4ČӃ9g܃/rC"4Q De.Ή͍WwL_}Y넂0&J0I5ɍR[B)~inIk89z Y~/! I~(z}@(} 'JB H.L { {U5aE& p_?Zg3 mJu<\<Hfw+(R&}B'$<AI|_H0 X~j Dh zGH4Qm x-( kN?f*HZq?b 7]eQs\N݄Fr 㯭!F'Y @&nc(@VIۄg֧6۳Kb_hymOI&o3AR%Peùf$B# UbUX3L։Ւ,#BX躲ߵwl \X( =-"쯀n+=[dŕh?ʈ+mNrwCR}h{, )وk#l#&z B,V4 ;Y9!x?2L$(!%@'l k&8S C"1F!, z3KcJ7tS.CbaNRP16.h`?MqC7Q֝*[L *d5 0pw2 V8h B80Vv>gcb]+< ч mߛ cp.0/x,|PfHDQRïE/ qUih y<Or4Bu`#!XI Yv!%}+0Xy-,'U,I3*5x.y!Uy)M$/c,:"qx+ -%j "c( &h# T:v#d1sh:t,"p" \!/99M2( &UD,s@b^ @g\GefvF.$ح]0?.ۣs&쎦@cq#,  _LU@Oڤ0g$s#&Q\y?0@i#) &g$=<%_ J{} e{ߙy\F ­ !,Z+,ދ*9|FIL`K4GEDvHߙHvzCO>X>m AR@51A@k:1/^!KC7 ;MzR PeV e%R !ؗϺ/Z&x`͛>Uу[0 y:"f~;*ܬ 1 딑-y9`{=]G5xFB/lGB쒐}VV6ܬj䁤̔R'ftZ-!6+ja{ $-BcT J#%sS ?ƕq oRqSRKޚ7u ̏lPdpze\.D 0J`;sϰ#yrܐنvV`]kVrЎQ?7ɀ6ɾ v̸~)LtXdcK_I߰mo >C`ky^31`aMZ\TTnђL!8,2]tHO!~ljs_>#~%A}b!י |C Tz|j!R!G/!~DK])b4&,?CB&W@tAD&EfAx?ALDC?F䭣HI,gEoA@6x sC>Q=|_S z;[ ]K|o*.#L%t vp, 3F!jtzZv~k #2$R|o \ I OGO , K gd|{/!&v*I,-0{Y6Ժ5Jn2]0D/.-(Nh-Cu((r#[ wUV*yJd+y~'+s4,weN,Ղ):"ԣŶtfv&S aI.+xOƺ6 X|;\>\!> *sXp6=yH2L8 খl}s':Zʭɨ35V؋3EoN-⟩6 mtT`NsNrO@I"zDϕʿ] q0\``TH- Bd"a}W+U {N.g* 6Hݒ?sZ;X5)0$։֠N3_/ґ鯇!\QHF鿟waqXl`s*KΨ 5>V}A>aQqޣtH4S)ڄ",.M͊@q͋ߒx"ҖhC/.cy2vN0E#D}LS96g`mf 6)׺ SVv _ "z$M6 fJv$FMyt3 BWƙ O)w y o»8Kbjb6Hu uw@k C)I*.y=7cABG" PtMiYR[ĂKO b5ؒC[YE7;д}!r#z3i/D{V֔c ̐' Ve=k,i r5w~Dq|)~bELNڅ QS#J*I+&:)_&94['\)Y)?&&t'*~9@-+)/0E/*osP!'g|xZ'ay 8ovg靅މ8L̩.o̿ HM>#Wr?<^wN([ ^2L.ڛo.`~T (j= 6w $ h ]maͪgf{~H _y*/w a @D6*>u_/F8<u%>|a|9J&¼0So2T "ֳ  ̫F!OoDRs o0Pxkѿٽߗ[E.ܟPvꪭ ӞWRIݶkةOnQTtڀp]2Xc.eg'/ي[CM뾉%)@᷄ۅcw,SWUM `\Wo'\Y8zV~~ hxW%쳾p\RSDϵZ\szE㟖!\KN[Y=[[MxO^~Tv `^1%)0N6a&94K-&H"NܮYG]8ac4:DhSQ3zSd+6PuX)J<’RLcLx~ _aS=dysT[FjP<r ^DFĝ *nvPIC3aP@f[f7&{ޮ|01t~2]FhH,JۤkK Q)`tcrl%!g"C!! !gC! $X'A<+:"s*{#'$',yW.b, N$/Se@_k"g "1u*\V.+&i%Ia'w''D$C!<jB^Y"~+$4O8A9@?7v5[18I,9L#|,2';0es3/&d]MU=+* dvo}Y|jt#LYY Se%Ѥ4" Q&YJZ "r"$~P18!A#'iN3@. d#}$"Bkp"ru <(sa{|`- ڿ8'T1`g W EۖK2(m4ȑ?cBG> IGGE NF8`EBE> #<:<rlԖh[2t!Dfi61PAf#nyːf{&!Bh2M6- e /={mDZ\U]a~iZ^|A+-AvZD l' 9?d   "0B5"Hb$/8p9I?A9A}z)BCUbD(zBJ@,R?|xA2C/sDaGE yCC=<{V4<,("& =#/Oe\%Zgl Rs\ 1X2nH N?DjkZUNVI[Wx;nZNQ&9'|<*v%+."T &>|m2"^' *<0*2")4 $ AE Q g$/CmOkoJ!iAw-~e6D~v R0gQ#$[J\ *l7e. lHy#2XΝ~#Ն(m&-/ܓpߋ@Md؋4ٟ:\[W%K}`qيҸX <@`: w!܏?L񨍎kHn/yDT<q ԨQ$5V/$g7JH:F820Y)R95 % jÄ%8 QXdcxN 8^G?P{MDې~mY4?H(Oֹ݅UweK{vU TݍȎ:,Kr0A,8[֠+,;O.)i\z7a/`Ui27*^KA5+233/EhʼrS=t䪂-B[HȆi*#&# ܾ>ɖD] :?M8 ' }y5Hs:nA#60";y.E'ՙ nҷ8 !q+%n oZ,s ++:xal \"iL3`ZKIkKa Wn O*3ZkASIx؛ t޲zz)5o=@bUDAY8ެW~ۿ v'ӲpӿlF(@ֵꉛa&Z:MyeI\^b"ԹMtDg2BѢ%Aoҷ2nwXjڿ'2!D.*n\E]!&G @dkF ҄Z~iЪ^4hcXh)(}0V"rb*_/ D1a4q*L 36 54(!0v#)v W)b!I:ORB#,%m@Hadr1d0"U8J:_L)NN|BKfVp m ^Aw = v`G0b1OEm[}r? g:D[7,M]##Mi{1Bm79nH ?~ )+bHzJ cm!SM="!!sq!]"6$)e&_߁&B$$6R')Я%)iV% L(,yT$i*.p1s.-+ E('5&”$Gi!enJ~!'QY@/Z3)865wB4K"2/y?M*v# $ۙ"n)-O*-"=+Yc% p bS 0 , AEBL0R@Aa2ɿ%M}~[/;%aP2)l7>g9 a FvK7A!f8~!K/C{)C=> t1UI~! A1 ]">l!*]n6a[ȍxWna# πP:Cʇ q̿|V*]ӗUh֐,ء %Pѕ(zu珨:0w`X8b!}Œ)4&0s9AkB l7jz bO_XrY! -m逓MvϤw磼/)N?$nE#XBY11δX][HQmD{Ջ?ڙ}]a1ꇣJWr5WD-ag)=@fˬ`ڹ;J)zF\s4i0 C>E­  ; S l2, B  M(פe L.*tH*!   h?po\ C/  >\gğD-@_ ps, z}M܄`}-%˥hʓ!u&MJ(H$P&%"21F$\  !R F #LʔX ך#3p9 ]/b(-ױ H%& *c ?aMX&3Z+Mc QU[h[vle>;\\LRWe!A]Ȟz+ `W-ɗ;7`-s#Ihz $|8WU~!j hl$ܽ> PY$ r gvq 2:b ;rb& ʂ?!*o4;:}@#mAZB!CF,?CA?2Ao>W>]@K[rA BmY@;_4?F-qC(In$u!%Sgɿu9h=WҊ  y`7VLkzcW0mW} N /C9eD_ ,s_ѷYA:rBv)#  l`QO>篸=S;"   e  2 F !.  Ե0 ~vE +] zk@!9&5_*Ɍ,y.fV0*a1|/,#iv*)(EI'*&\$@ 0kiV*L+z! ~Q  ko2$һG [9)1/$'i( 'h$~-]E QxPng zr $f%2xw-;!U ㎯ aɩB0f+AB \t5B*4]ꕧwY #40k d0d7ޢpy{z乪b^"s{!^O#F.f|@dQy׏A e}7@W𪈅P4$^K-{G&1мD B/kH)1%6E6g1{ )  )ZSc` " S  u)8ATXGP׬=/?hY&_,F o l?$Q8NNOC"a<8+ނs5!_^ׁjMP~Wj;w k&$Rۂʃ>$$P `yk 퐶)s0!(& ^\q[(7TOo'vTlDw u+ܿF{(x|bצ#  ví ?Tv㺧hmh.Ndi&āI+s_V hȮ3j'ӌGi%-P-=ޫ,E]L55[ F,cI,G5)x|{ &2uv[+R9t ^Y 8'&n-kkS # Z*R0>>$Y&R('ݹ(S )i;*^.X) ('nk'(-)k`*_ҁ(ƒ$' vXOo+?% :6 %T&}+L%JŠLǞ8zv0)J$m,tah; OAY_#!<D5rF F 3X q{!Vۓ: ʇF0k+$^l6 pZ?d8EQ 1 .g ^1 :\,E:=%W~8 Wۃ]F ΈC<{GG2wF. ݋!cw{ܗstDE֠i.i.ڄW߅gZCȨFxbm.B^ ^V(4Jgڎk՟miYs0 ܻuݕf\pBJX@3Ej" qr۹wŀξ·1I8E<(S?svӵ%s eU} @A~6F# m3&n.T3sa4 02*"&29pij!iP PSƽn9<[n\:| G2_ |tXgD@( 29RCb7[  |o }<AwØ)P%:Sd*MlITYw@#UgJb' ݦY9)Zo7%xnMȒT"SwFLH Z](j6B {"U!-"[E!Ta!O Ί!a""!(!8#r%(&x%F#hd 7-?!E-%q*Z.0䀦0%5 /v\, n(k#?>2*7DM# n('&Ú"fI&] 5rNoOw2z-D_ `xs{;T:35clQ0p XӰ7 ,-{&Dcac3/{@a 9r`2Ge^= Ց+IZ| NGhM m^ O=P Ļ SUASI&"+ !48n=:\$7aj442741$x/W-&)C#J?I ,_!]p1f H_/a֣&U7֩)~QZo۱Kܤ(V$Vb-E,-,}F[ '{?n̕{py05l{!a%J]>̩O#N yڏ~㬱0P~rw8V6@ z^ CoH]&xL F t Z U V * DyBD] X*t$tp~\^]뮆G%NPfgYc7ɺ{ZQ?+iVm?՛| ֟3ԓ Pz4rѯm T‚eϘׇoؙܷxݠHߔ^NW@c Ÿ7mb ;t]^I_@kÙd?%@ѯ-}ͷ@w̰`z˅TIA lp|׬׺/֧X'pѹt^^Ǻ/6I%;ߋp =:fj&M 6ipaOlW#2 fzfURƈrtHML kNBVKaV|DZ>sנѬKp7KמX;l77 er))u3(nk,8"/Tj}K7/E(Ĉl b I SC fj W | K i )\nB4j1N^DVJiݥ"a=ub I YC r TR ï խbvw})mBp, \I*x]2O',"K(eKj"6&p'F&$#ȬxIe` ?b dj$ X `%qESv *|U jF g {%=q EPxWK}a+A$T)7Df(GPa_,/̗ $W@XDz=?C> =[9%;46-d[(#Y |ha-oEl8P b/$Qn[ ڽJ{p-z\qUBݛ\^5q߲=O(a<|nz Z B=-. N w U {  AP 0= PV ) OabTƱ$ I(J+,-I.,?d*( !&[$#d9"= R49س![;RZDg[h >SWg'!$&1n& #Xq `*C8=4hsTf nOpyEU橼::f=7DYH3XVMY@sf>̔غ5iE+GkGonvs|`BU4c1=0=+kڎF,t"T-izjY+c^G+N!6Kym+_mX[=%;ZPV$D [ 覚[`Ṝ&;࢕ ݐr-R180iI VNNNhp/G~w+G b|:`e 7 ( W YTR /[ .@ U!E}TjPd\W+uw' l?E7VŲ|D_O-j$`i,(S+EM,| ZFM?|. T'欏jjrߡ'eX0بOڨ߻ЭYEk/!GSrDn.B /K?>KP+Q'd" uAdtp 'w 2cd+Rf8 : *[絣kVoפđrn; L?#z } %nk'W(Ax)))*~'^Q&ׂ&O&'X9(5'{%xB"+Xpd=#?o s+ )~C+B=#YDnZ}ۨ: [aF(К˫Lv$8mH pƿ?i5A-RJ6-A(* 3r SB mA * Bz8puqTŕ$Y dw}Vy@Mdm N @bhM(da]<   0\t72i-VG\H!ݗ=q2UڶOe؛yR<סȹ)dhrha6Rm)3d1-8w.1啉Aܭ`uԴ(SÅL3|E Fބi߂eDQgNZ>\B#~=Xޛ~ؚ$J*&׈]U2GHVm2V?d݁&Aﴬ cp!`*}P0920#+*2r$8q4k`.o+HLZy[/g^}# ՈzjtIC!}W72oOXJ$t E}$ x< x :<=e\La%YVp|FO Yh Ă. n:tB8 +;CF?u5uͣlC0BMxf#/ @ľ6X O!es!ᚨ !{#ߢIVi< oB#,%w%QW<%F$cu$&%Ѥ(,.=/=/_}.<+6\)b5'n %#"!_  J["qf&)%{1,,+m)U&wR"UBoޣ!!Y zSmRzl'x==,h_>SAs5O'WAֵ!|_,+z M~o#ྲྀ;:_:y:FxKz;y/@2sلj:3)kh l` CwD( k70e߅7%m<"?j~@9?&>H;w8(?4k1ձ.-˼+}*y8'É(#Sy%/ fڛieR@ J H9 l ,'(Y)٫ՎUp%+)k;@k5&1- ?[_hXŮ(¢%"HcC)‡ Sv!V:2 mSFKSա*+Ԋ ,WG ҨyҴѵ-ЏkNELӤ}ًҜrh¯Z޽Q_#%`xCeΉM1˛9r PgǰTv9y)f}:UQ(ZtA"e61x.3Uӑ ՍW`_2_i lG؅ˬLY̖l ւ ~~fc0UZk~^'#,!9!i.zTa z M. z'5g  ]Dd 9? _! JR(  @N 5eMʣquEQ.^O f [SLP:صgN r п y!#̿%_(%'q&eh"x-lW {ƕ h+ l1:$[3 2 }(~ , OGߏ}AVxu 8% = xtf]b.%'dOh/K|?@D$@B>vO=;;]9;u;; ߍ: 7" 3!d-0'v#Fb(QXu7DXqNv cuu *M!i66Nj2 u Q ,9 +?nZv+D T U~;ie` D4^uQK8$ ) iHH' ku,? ,~M  4 1 P m/, ; X.Aq,Oj! F%מ(RQ*J&+c-*") 'R%$"a5["!g+! td ~VLs;PwON0o0y*Dlu!%## d!ge*؀p6a8}qmr=6ߡ@zߣ/)ް: UpeYCh-Ǜm (0r[ml(GA$\DA+炭}꽽&Y ⧽OTT쭠fp͌uU.ւ.)P`┨HثCBi 4@` A[P+NPj[YS&P+<-Ҋ[,v' {['/!M@LC^nCZz9?A*>k~2ey n>|=%\Hl߷ ڜ;ܥ2wY.$d!0U/Xf\/wݫ { C\)zM ߟZtMXlVom%*B!G/f)&. A] '=j<(@ Ȏ [, Go:}>q2m^sK~9*?6pӔw8v̉tS2.FFDoN<02*&@r/B-эoQ#=} WE]N 9Ԋ!qdnG?P7Z൹ \RRBk/tMaZ2?ð햢|3TLaஊ [E~ENxsM,(h | F}uy\i{&y PEQ&mu e1!1S O~QE M@.'"dS\&(_X(V8) ) (ݖ&8%p$H$%p&W3'& q#V$@+k#F  Tg"Nl2+򄙀+g e⪈ mG+JPJ #b ^Tybvu{08Fw)"Q9,A'la[kP 8 | 53j>34nrlR ц ),k6g |E+."T|Ͽy |G ֏e1q6bؓSm zIrZjqM_! b |g8#<`A IRKm$鹒Ja3BB-6NqeQF Eڋm+}ߴ׽4ֵB cF _ t na'(X'UH'(ww*,./*.w,;*B 'n %j#lw! @- "[^%5'(gbt('E$qk@!JvI/?_nC-I7B(!r y,ش.)ޏe`왔\@#wgL^4$GeFU^,r- Hcl#=CpjtnXuӽ&s$'>~O5X 6UX]bgoL$!ym .N#6l.P%"8,c2S8@;<<:5Z8|4VC1n-`++k)W(%_'m% #d0 <#UJ/O[r$ r*s=NsⴾP؁^W#՟ߣO`B[҉Ͼlwp DC +9꣹(2ƴ].b[CM_=g Ks$@7/w9sC=A蹚 92_ ksCa@ZqȈ qy-:Y-'r>p Ö  ' $M @ = L];͇+hZl0'?/TH茧8BYf:@BdU%P)'ngMW>)j>\Ӿ73r~v]bфу_.g~Gרd KZi]!?ګ!qVlc%Ӣ[!x f06Bɔʊ /ȐK]"س=çJάA(W4:Y-ѹ}ճm։Lٲ݉E: ?NSՙfҲ 5Ϡ˻V3tά*Nv+O;T Ϲ>C)<=n-ꊺS~|l]{) # o4{j `#..]r9a#gW%V#VlIjW8/ U~*ْ|\ߓIt>%|񵲂9ԍ.w pV_1QT˧Y`>Som"+%Ʒ?s Z 'S+Y]+ {? 5 I4W,m3.R~f,2#cK)U"0J.1W^M#t W uxfk!m"'%"#[B#[$S%%$!?(1 >9= m@֟) r1Tm> t N ; kB–~Pd H7 qׯJSݬhWOz1-X|z ^ߋ[56C3rK 8A) l/?Q2YV-j2Y"-?e Z{ lz 눞5q@t "}ɞ΂m:4P.`likjԭK>Z*_ǭ;8 "n3)'[1J7S;=Fw>rNA>K= <; k:h`b9k888m͓7iA5}y1(,'%#. B zWVg!Ae^Mf y z!I6q^ἠXdHb¦_QE XV zwe% [d)S|s;NLei9[;<u W<Jj* 1 huTY\4@bWg < U z o\ % T$K w" Z2d]ʣ"%'&#c%?#lFl"!f!UX!!Y!X!/*!t? _D۳J/tl-fpL~uu !O!wsM[V˗v^WXD=8 ]I Uw@;oUS޹I+f&NG PE= J z(9NA`Y`Tv΍".̙cبv==ߙA8 7p&,mw꣎ueUS"Bɸ? l5zڕgK F,N(<_b=7UacJ c_P8} ᡰ ^!.!OJ&(o($:c1G<vgj!ӈM X#Jt6/TN$uF\E@lF8[eE'@n?X2rD4|K{6=S6ypQQ,a+_-8%G*A-osâimjHX p ;4n0n p93sVOo.c~ <-⟪w=z#FFelsĵ Bz;z2kL3`HvOv!sj%1 @ OD EH u>rgtu/a Xt^b&D .ǾVZS"\Zr&GL8PՅM(BK lъ#~Ea#?q/CURqf5s% fТH,%n~ GJV< "zx-3*Cnޟٟ6O>$~[c7f0ySC #i^\O _][FmL 8 h6'+-U[vcH] K 1D> $F&B'+'}z&R%J$3#d#$#[%&%#v kgSD@ |FY$5 ~TF(M#4wLĄLX V9 NU2zoPetPm`=_~g2I)-0 @ -i ^QDtAA{rF~wNxe1A] V OHpH^M.BK Ų7? T= "l9cb0ZP_f]=unGGlo;ђ'~h qKAiy` ^YHKNt)⎀âb+η&3\2"U%4%*ܼx0Zڐx 7`ٸ%]gش2EؿwynUv@~z%WzC)&q]dhMbxOrX0%?Iߍ?ؼ*YIWڎݜ^pbӾztkj^]0\9J篪J<0=6ػ`}6=lW@| Kuj};XP. te)5"|2(+3M!,a)N% +P 1¾34 P%`mtqx. N=1;;%MTY}5uĩ P VBg]ɭ !G y gw*p c*&}xB}b]tAIhٞd1Z_+-[ IH$m _K ue i+ LdMV:}[.8/ x kmjņXGO&߉?j.np"K.UKt^ #&`z(ꌓ)Q>**,:l-w.>/.ػ,O* 0(%"#W!^^r{n!#|$%A$e"+ްp!88sA(>1oӬ ]q;-xPc(>6T|DA0|+%/PlonYIj l= Mg7pooBNY@_6S"c֙[1rYS<;2Δ{-9IQ0$h)m3T=FZO"r(t.x3&x@7a8˗8?q7Z4ߡ1Q.?+@&(c&B&S[%Ty$("" lei 8&#ڧڠouM YE D֩$ey7!뗘<冬txaw>Y^k}%7cn| UvT 1+Y(]Mjyiy{ꉬe.1b;UIB"2y&k< 6 fsecOYĉ1ZyQbu1o/3@猪ǰI溮딑KVt o} Q ^s  F N !c`?.eY@.몋ikC묯X0>5sT|ߗG}J>ِNְxs|oȉh^5jNO5|!nќeя| s\yRXܴ5o9UdbFFӲ5T(;ktY D)!Џfί{^˖7a̕`oxθXYϳQJҌԌA؝5{(qۏF*uںn;ت)Xu4,Kҹl`gy/.-EB]_Wꬃ%ICYY]| ]lNY-@d * <[P71g5.tO(\BN۞yT j D71w|⊢ u9iۉRƒHXh:`:GuYirNtoLP4h'[ٷp/7RuGH TJihl,'Sbrmm I ѻ?&)*Xv U fpsKjRCQCI1IhDktȂ]i64!) `!^kTX7:59W?"$X7$$$$$|}$E" w_^#\ Ec$mJcf,Ci0'*AF V^ )P bd r٫, ;Τ%r#n15n+U3P6;^ZVOIʄHj2=3wk ι5|!} ʚ4r8vZɖDWbohܦF"NBTnd6$=ڰRC,.5.43'.R/m|wV~ rH . Ӽ&-3-3?q8v:UY+ ($ELIh}\k׏[Iԋawpma  { _D? 00ݭ{I,/CO9WsGxniސZ+r$ 9W'|3C"|+UO$DK>PXq0{,$ɔw1%v׸ߕoyyۡ[d}^wnnc\p&ep?iΏj9߀IWݣGڼR ;Eְ8xCv8- )hόS}`3s.gvS)ϳ祳䁄JܖXh؟1F2m5G}QO-PLq[5 bV =% ##/=o!3zif F)]Om^X,K! ;y[WGc~^ sܧҕB_+٠Pb܁ I|qU\" f%>>s@IFV)ݤ8hOVfR4.Zi"j ~C ?[jk+l'4&m$2_PIXתL7ڏT|Y<.!F%-A e32i3򔖤GrDMaX&n8g*H-w+^~gkR^:7T"楰/8% *ܨAou:6Ov+EY6#Zĸ|ϫpy GjwSg @$' _)X7J(KH%L A9C4V# e# t#_'n)5+W,Tm,.-u-o..Q5.KH,*(gM"&t#| X!]2S\R B!s!!k!u  58 >[!۩/;]W 5 {33+W u$TuePvɩ>xqqv@V`*f{q(#>%cf m 1R@I:jYGj @r +}RImA+,Y"gT'xo ײ5߽r,;9[O-\yjbzp tQ%t*/2v4n4Ü3 Vs1B&.+(!Q&I$'$j#ݢ#̓"!},~Af.' -W L k1[eHn R2\f|[L-uh,}WSXЈ̈́wn3*ضjcgZjb !ufϝ4,s,Zmu>Y]2rz ? &>%yPNz2چ Z燞 tTm"ET<䘣hΣX!$ 0 b^ ڬ 0 OCǸ.INߎ8 +~쪟c 9H;[bMp o{sDߑjV&;HԤv; iӢ9j{!Z'XF&Mxҟz{(׽gÌۄ*^ݲQ'C{Ӵݶ`]ـ/إAŅS 6)#v>̚>1Ϸ1SRN҉q},#*܋6gu˥,Tdgq:Ӈ0ۡ0tQ J>THzL9y5cV0 7FlV6)$ vj%aކ>F_M> Jv9AC7"ʔk/ ,z)ti㦪l"#ށjpݿ Y;:s}DcFGAM%< l7cؠ^fB̒M]u  7rxn*lY>Gh@ b &>C 6LE kO%Ghe+G@ |ch<f," jF^!:ʚ >Th7炙{+KE6HEtzl>!&ҙ.F$*.0Y4 l7`TK99p9bx8O[.775433"2 y0(.A +b\'.$ !Io!Z]H'_̜(},g4! I\g\nQtʙ =m#d9qAۯJAG>u){HM*l fD {U:924vWwApղj=W % Ye | r T0 W6b(_b] vk!Э!}! !+* L] Ѧ R!")$'X%6& &l{m%O#1d!=N=]Er9:~3belxWPIIso %+ g% ɚk1!#u n>,폁9-^rC| |}yG$B䐢@;5G o=P?2OA^\͓]ߢ#S@Lz˴zihfzngoxF؛_ߎLVnLg\uZ5NiߕݑR68%=0ha2TUY .5zk| ` m%K)|MŽ10C vYĖ!̲bQl%Ov~=?A eXOJŮ*蜇e'ݟ!'2>UPt:^߁}Q{˷YTo|5nz嶫4O%$be㦾Ju䚉 =$@pKnyu6m(b)/GqF֬_RfŸwAG.jE3ZЍ(XKUȄxGs4 G b gk M [# # C禐})VRmE6@,?[NfH FNKx\Lp;*Q,[OM-2 >%P\٪^+EV>蘹~mUd{ FD:灩I*^A?$3pYeH7q|*kv)*@ftގ d a =/ԝB@ iM |G b| ˕1\%`ef+ erKڞ&"$$N@$Γ#)"f"L"O#M$۱$,$tk"n+޾& >kr3nS4K;=\\J#.3HTt-φLEٺ㏼ibo OxԄ(`=Y8)/(%ylvw^ A B. @ҙ}1ƒPu"{w@A : FV{tb|P<~X"P9:0^HplA  it 3(č}hHk  U c  uR2$hO $-~\\/&x5:mncQ-^$&z5i$z|YCb;*N,P1ktdګ8ڷhY+vkrܯs:JU;2f( 7kcbcY<]UWGɆ`ΖS}WPJ)?;23:ܨDCR 㸃?.y/J{"h屇{C[b0k{)IV2?>F~aRLy5hZOh9p6>xoXu:iਟAr<G; hFg6 FR6$%S&{5&$2G TۡOx  V,Z0vQ Iۿ[JH] < {F>  MUqbkZ SS26L#L tR!2PxFo%g">:,u6| 9 FU e `R <[ d "< =6 %058]i-`R' 7xm DKiZ~R#u1 `b,GJl{`4C= .#{'U[*mpF, _Q-#l-G:-(.W.aN.-ב,"*7(g"&e#cU ʋUDzǪ,@ #a䙨E!QL=qC/43 @ ˽scY-D/[%b Hj@:{Pe $a`$uPp9jFt8 32^qQAUϮ Z)tTMt;4nW'.fnR?aKOۈdbզfkv{]r@j&wV +\!mt8(`O="8W&|ޗ*e9-z/CS0p/-y+:("j&z$J#A" j"p #$G"p"[| 9Y"iL`[Ы A<,2I %)oM8Yu$Jkა8M`u$?:rC-LoţQ%`e.6!#鼇ᥪoAkPIXl7Āca(G&J{ZfW^1 xFgjZ8 VJhǩN~) lqY>io-  ]i=  "%b * 5T }@V5Qk(ò58/,41C  PIU[!!&[v! Mh c)Yv))m4Xu4C$#=ߜ4h!Cm݈|Xٝ1nB}>G΁(uǤm0T`CВI!+\tA'd#)@@{˺ݮfN%59ڛJn{%T1J/h0Ջ癔騭O=pBśc4]$< E%rE,Ą1$ * Y leEv;vP$ӦXvOErtVhu'5s\ E"= 笛HF6qJEg0(y:t6`j`oYhf[=LHRXρ_qGw i P@{*a<A3 >L !,,a[׫M _/Z~ЮK Ko ԃI`9v,Ғ=-p#ͧ9 C? +>[<U%#oW%i&*o&%F$;#ah!:P_6p}{S N joùVnZ~FmJ8 `D>qGP"Dzo NM7":| 8qҒ r ;GBA5ɗ=WkV3i  ڱ=(=SQ־UA0Hizxr ',Զr|,w/q~ ͲɦqW.~/:v-KUO"E';,U1%V4 X6;737 Ny6N5#3+2%106/ b.,4[*p':B%x"L#! bujr2(~p*{xV N1'> W0&~c^RKK2"5{?o?.d(N "yDB}%'mn_E5Frʃ ) - ?k,S>C>9# Y6 C .  ` 4,5aBwߒ0x=(&A)*aM%zi ""#3Y%&1^''E,9'~%fA#w) (tVWkQD#_X{>ݯNgFW8T ĥ' V?t4/931Ϣ}457LFE' Mjƀߠ"N:4,`V>Ed]_6 *{ Ͻ c8I~灊awQ؜,UPY,jzpN箶K+ϋIz(;U T 랸 $T X-aOJ@i x-/XҊc$9;32q ctdKin] ^W⭉< A櫵tjTxk[£2r$CAOm֠)qH'b|gZ o]LR^jKer,oxURWPjKqxEB.5<iF?s) W/ ts (kq s ?0 1 ՠunfNk>;=n."Ki[*wp+-YF$#R`%GO/ J^T0Q_?RtL{)T 1N&o]x8D7*=eI,TiUXrp뤆샤,(Vw,lp YDŮ*G3Vh{ %`22_uSֺ#"^Ʊcpa^ U Y +8Knc;eyE @ſ vGmb* X\/^RR@Sm%!bU""H"_"^|@"{Fq""\#v#д" !;Z2d$$9x V` }v32,Y|;ءe!$Bxȿ:PpET)bĆɣq_ #%6F͉)/\BpckNBN[5 ^NNK+'Z.WyQ7v{! %-llŮ-SbZc}*d`1rF9 H[ nӍH8}&\Rh i !ݘ%"g!<u>ƻ tX$ & rRc01jru [ݏL£&ե D67+Yۖ.ۦyۚ*ҷfBgbc_AzWymԢafn+ޯmbXK!;iKq` etXPޝeXqjӊ%< c +!k収$FaTr7x,,&^n9HuAI40~'q"MN ,_oL#1 x2[[3$QA'**,-{f.΄i.I.w".YU- E-q+,%*d_( 6%`t/#lh /| u4Th\|hN[:[d0oo| 5 N U - RkH(V ~rP}P1ӄ 58TQbbF`+kc릪*qO`H (lhZ,ާ J-F:Wq% 4۞6322^ʊ0*&l^+!݈Ph|pBmVpt{KTS%"/3&x))+TK+j+_Q*5(:w&ʇ$kw#0("^!!R6"7$""n"O ~YSpX%q< /rԗ- ]Q8/T>N=} p߰nk28v0=13a lF?!cA6=;玟sr Ϳ<КOphN~ǵދ< 藓v 91np=蜶"S)wa5~;ۡSyA C !  <: 3 H 5a GCg%ƒ3>gxWAceJ;Qv}V#F9Pkr7u\ ₵,"f@y݂֋=֛WI)Q'ApV,ҮDѼН0JѶXiҾ*ekob@ദ@c⌒@n3p{1?&')iSJ0GNeXnUhПi(gkժrXYppKQn}R8sL .Y=&f껎ܻDNg_$svxr#NE|lF~d1Efe6 y8 S7 /^e =+)b*Je6^vF꿼L>p=r 毖垁L 8N$KB %8ňwzv#kr-DlJb@1ZM']L*zC߮<HqGLH 6.+a/Ԩ 1 kE]NFn T ظp ;f98n5_H_PR]0 /D`<KA; nA /F]^Jr3#>%C&-&A/7%z#,!"L*Z%\!n э=)cS Ś)u,1{PCJ02[>]EEe~>{ #".MFz¾Xl d&%`s@R}zr]b;36Jd!,cY;( 8;J] yjtHv&x\/B ZalR]s΍)Hjl{q=Ûx|vѹEW4mhI9p~C Te$;)\/-0i=3Iw49׿4|F4D3 1 0;/~.ӕ-,X+)W '%w#9E"b *Wi3(+@@` x[ 'd GE[igV[K g^T>7)/ _,s1X&2t8Wv= E]V>Ve# bۭ V ,8:gf_ j(6~ : $ ` G?tN!N:d}|\;%=CFk,#vG,yik. n߻dj>*nQ3 !"cWOY<0;2f,̬XN.ʦݓ p(|6k|JDpjbȸ AڰڿQ,dc.NH 1p t`Ip#4 D `M퓃UЋV$<82^ *U 1 TvN T [ B& ^*V+7H4|92+!WpX난,-E%!!̲ggIro)TC[muhBЮ=d*kuzN`j@p" q'DS&x{G v[ hw Xc,mm$l q Eحf@Y{ .T'(8g 7|!ٿ!&!6!!&"C"I"\*!opKDmΘFĪ = WHy I4{;C@#W8iV8b2G =||xW1rqiFuyu1!OYȲo֔g HV]NWoTGEĨޢz9 [ ӡ#&b}Ϭ'[ӅNERnX`/(^e,& G)xfx͹ !ç"|"!h$0*2EZ%, |UIVj>pi9 ¶#%MrKx *md$}Ta=#W,A.ܟr蕶;jp=Fd`qlJo#մ`v#yEa1ib 4V\WGN?Pvn[<] ',?v](䩘 B+H)mGxM | ]:HKr}+{7+S#d-kej;ؐ6 pp)4;Y m CMmd9y ~ l~m '?NM> S3 ET)g\0 Recb|\~}W`Xywwa',.H%u`qѦZC\?IgudfNjRJ@N돚yI  ` y p % i k c:T gVfJNX` fE 7 Q`ov+ eg;\H3d`q$PbI) a{$֫'u*7,-...KB.Y-j- #,q%+*Y]'Ykf%s"a;uG4jhZ8yxPkG  K   ZD" +*o\ D5dqh)ĹwbDu% 1LLvח< 82 7_.=V+GeZ.CaOncM+`7.O nnhPiI֏\1PXw[o[D9XÊq27!B{$Z&`'A'&ܲ%VG$"@!?iX!W!3! *" GR"( ! p%5Q) 2 z*JWvx}id+r4-?㴷N w[ml APv MO[v0gL(]NU)01ݭHJ"ޗ%bfJ{9HzєV5x:{̋1f뺪kB>?jl J _E ٶ L 8 O i "<YeY7b4O^gXP#K 楡ֻkibMo& Sr$C.הWfMܲ,(LEEH/lԵ3ӐȸUѦЪl'ѭ0Ӱ 9ؤ JL㤬C 4 8)Iw;wP π[ςϙB/qѰ& :_I:?cg .$ҿeH*T\̄kz?eQJ 71laT"zq&R*/-> 0t121 1/j.-4ו,+2m+ZO*H)0 '0?y&$=#ʰ!C; 95qf:H ¦h_Etե ('0HL]6Y)s#u+eQtn59aeZ+dEZ=w.0wmpjXi@g  SH(`TM:Q59j[MdurZA%5C !F ñ C B { ( 7~%yOQw4,>6oh<5&!|#}%0_'(*u)>*aCu)W(O$%CR"նN\Ǻ0 qK@9Q4X~} fГH Yn?y41~BZ漏'6CLtc䔋[7j0=kQf\Wa0>lꆻƾ>J/,p'Y,| d%b 9鹦tp2LQ?7(e\,`f`Ex駚_5}t;IVNc}{EN"H]^ J T(Y?g/ ū <E/oIf[;+2a$~sF![;E4+&jᯥiߗRF1DۉZH_lӣRW(znyzwoBVCrnq N]]Q ;,vKEƎQ%P=HX9*pV)h Vx*i鋂!}Q!-`*NKE_w>파LH QT/qjH8K`]6@T(Bd  lX F 6b X7 )% ,J |I:]}i[&6,+=w>i<~<)~hL$x|xl^j)qEW_Sml"-/e+M?:,i69qyy>kG?;-?]3'b繭}Z|5NA&iɮxgu˧5 G  O+f&U 1e c 6Ξ75C$: Cb&:_T1 e !M?!1G!8! ^v j|J^Bu3oVE,m ȧwr*ajpmH1D.4M^0j ],,̠m,qZL3\sT$fwئzJ˧!xSb} (:U68_oZ^b] < hݛaUV{ 3E. =F!T TOFzS4ӜFT K6"t#W"y!SUmr4 K +l }RVa{W&Q_WN&\{, h7fY{E1|W&c+݌pIXUwi]̏㇜^Dv [z$7l?I6>@?EH \L&'Fɤ}AKOD e | ",   X  !>|1Xή8:+/! JqP99S}(6)yH }ز 8ejkӴfn|l%T7LDyL`1~,"hc I 3Rh'1"qwâlq ./ e!R# ##s#K""!B [6 P C!P!ض!>!qshnX~r aH EQ?xAFZQ5a$8OaW燏?됊8m B&sWG@6sq>,媌j}.dw>G4mX{msƁlXCL`X)b U_ "1A\C CJS\bꞳZ}￰6;y<ͤ@F^035 Q dL v s  Rx <t \ '5vpQx[7 >E<,:D4\WQ-am:JoZf=4,>4V׆ 0ceՄFf#oDшHGѢ W\vԤuKb`|bOŔdx+'xԴ&!0E.@j\J5&C 0H:oz3&֚oQj|ڛcNzl9Xq:ޥ2ˍYu|4wNo4AO &C%[FFIS,*dtb[fbl A |3W/A & z&-K)~ureu_xE~X+@_  kWy O2$ ("a#Si$a#$#V!.Rg0׵:|}M  ! դŷ$& n3c >8zvopN!-%oA2Y.Fd!! R Hw ;X !O$HA!~/j(LUD _Ԙ?%\;œ4  C)nmFbtmu1ON6jO7>a^ ˫ JתNsQ5+MyvV{Z~# 'u4*,`.n3/A@/.T-a׫,+CF*A*)Hb)~(' x&fpp%#Cc"o xnp”w. {x\ak  N )k.K-Մn.G!0<#.NnòӅueHzxF u<iFip v l4<p0OXZE;IJ ` 8 (  N 8ƻV_zU8 9!$U&H'h)J*4{*)pD(h|&# 3`^f;X|Yr'qۭCՎ})1u@u JA? c5cڤuw' ䷷h8⛐X (Hqр*탥Ys)\r>bYMBS=4fa~bG澅hq)':s' h 8tD{\l&T#j(\闫 8ߠM+JTC\vۑ ͱ mҊiM3UowD %Ǡ ٤ Fʘ] _ k;+WVZ/I-m0Ue]3Faצ&^PV.'$6/I vw%ݵ6{)6~b崨'[^X%@Bj=dMTԁ4TJŲ/rO#OY91}1ruQ;q[볝mY݅VqC:PTJF}M{%r0ȎЫ} 9'.\NQ՜0戥ħ/lMuTU>)xF.`v Ee  t V" 7 3 ' zbRlt?YP* ЌσT.E)]f_reh?I LI ao6j3ߺ k$pDfzhLĻ4k#! DA|:4)QFXU. U?~598Fc~$ӎD̶OLcixJO$#63 f T M9aq_ȐD/ L . Fa\* MK EIvX8Zo3w  ;  * ~pa%ok;  . w aR; jypm`<+\6[5a^dtk^ATAv:fK;t;ЀH'}CH$f9_y?_T6Q0r >W+ )FI"4t\j~2G Bd Ժ= 'u/_>-.pș ?VpbYi%[ t&L1 =$"諯"=k"?!ZC'.t(Q `zb-8b;.XqMtKbutx(xA2_m )V_X˽GV7&QfHb. N'ULss-n43pX/P=[)6.tס? q"oU5R\K*m6'&&o;m~Wj+/9v@EeRl& Vdm6XGPbd}*4o56C!Fw]WN!b@=z j QX : ,c| 6A d Ԩo ö  aD @ g Q # 6mH-EYYΈ8E} FA8 ;$I')Ȗ+=-B-ٝ-6-s,t|+*YY)'\_%Ħt#A F(/F8T3C%쟦KB`%[ m <:#KoZ FOfY0s(Utqr/,t{%vEdh{?50V N9][SW78lP7  B pWj[_$,d nmIL_~Cm}54Vr 1= n[[0MB}߄{a+%PV JGV&)Vǃäx! +/=  2IL 9^ e 㗇[s*7^ E ok)UCE+4!P3|b{{H'[ƣ Ivr#bb<3BkQyVK#ОmtحL[N`swYV<-9rҤ}ӽW:Ꝙ@s696u>("厝M8S^6氂(W ߔR'-pvj,T&t=0ө*; (`׶R6ٚSڭIgݤh/@d\p)ߑ4ހ՗L8KŘܠ5mekrFY}z3@;@4˟ e_ } ,-| \ :oEe]1ptFj={:Bx^O1Ezӌ~)h)g2젩 C #܉Dv -sA;Bh;&a3lwWaHʖ^}'u\!=rS+Xq,:~%C2 Rdfi rr  %,#a q F T :-8AO' _UKiXKrE~"$<LM5)@ wj Ɵ K%/."m~ Rn!c"ǃ"!ol /pPU|5LnW{ u ?UgQw6gRv&w?BhVLP//}ʶ4fWm #* w k + ڍ 8 lA13 eDiG9l )w[9Y=}E/sy-Tc~f 6 /% ѕ  Lz 7 ɽYQanz]V.Ozh4[fSA4ȓ`I: ~mÆ0$9 Z#|E&ڻ(w* {+f%+@;+d*R- *XC)R( K(('㴭'('nS&hD1%i#S\"* wA*[($ # ,I?! $ QZR8Y6^.k]n (P kF E 7 ^ 44 T ??A.i7d^g!.#J%<Ȝ' (GU))X) (Rv;&@#P ۞XV1\QMp 2 OΧ L[ sx \{{Zϣ/Tw;gk9?Yg]AjhZߴE%ińH^FWFD 8Es$? }j|I WS XNh0 赧!wP 5PvZ%E_,Ǿ e^:!WNk_mkɬ(}"ZX@49VZ' K פ i0:  g p4  &7h}y%*‹P0>΃ KaӟA9DXd6|jߢ_| AsVz=\IQ;g􃴒gacۧrI n@AX6얚u;rd/SS`ytJof >7( n  9x&|bq4.,50jRP!O,21ŌQxjg- Ηlyȉ$af?wiXɋPG{ E4@ M H ^Sx<Nt7H@Glh  @Zyo r$5u 2˙pi56pjg E[XeQeeu" !\! P˴wlYz;4 o y?c,]AS>+= =InWݥ]>Lz5W|(%4᏶}'V(FRA3 T,n됤5!Hߘ_xr.@/Q:\Rbؾt NCS3傲Ԁ%3Hwqg{giXSCk:<[ۙwH1l@|X b*DnQ)O"Tw绨,D XW>k"12j1` + /L,l'v s}3mm =b (E f +}y[@ 7gn_tj~/Tfͪ67HX!0 ;SS._{|V00--iNVI)_>h OU`ՎӥM(v56 A_ , fm Ku t 3f y 3A Q r b QPR |s rH3  r ,\kW=&WDeJfۂ`۳ן20*U9Yd@o-uN\UWZ"%!座&iZnxgCFR=#M~̓7%f(U_2u (B+\mڔ?2U_>O6 B0 ` e 0R8 b> r  ;\?D>2&RM{ r;R‡5Vҋ B,T0Bqர(byT?Cڥ4r' $q!/JL0ny8p+/2PϺզpٖׄS}SQC_)R DZ@9zIn"랲pүس']5-4Zզ]Z*K$Kh53iK`ڤM>k?Ij؏~;/ ~o䊼|,iF{Z# KI@Kzw fU8[J5m%pSp,%j W(iwe » -A c w kkw<eѢI'3bM d>?4.8SҽT]шdϸRhMq{2_M@"!F-=xw3:8~  |wU1<mFfO:g1?06V ^. /2 6j  ʱ Zt}+%8ոeFF[xmGkrqXǾ6] + l&%sM4(4ޔCWRMz(1? ;?9+([=s H<9v$4~R^a: dNzXUT. B* EYݮJBu\<%du )g9 ` r  f @su~{Tu< hpj@8]]δ<՗RaDW]k[kz?~Ԟ9R<Mtgf K t S -^ n . i͌W]\Zڬ!;[th:RgN&xnBn8 +="7O!!%$%M'H''P'&8T&%"P%%ȭ%{%_n%nj$$+"M!Z ھڄo1/,=w I$O7 DPAqYD2xҪDEwd]$s&%~(bW`n@'Q| ykKր k  R^}wGsx2sT>4e@- \ ? A7 = 0N _  V T{ xOhE1l?MCK F_";$.?&Ti'G(@Z8(Z'h&$Լ" KqsF* o4j \ _  YZ ; ` Z2?Qs2MK3d4Cd 騈Oe?Tӥ-B(Mm]趔RQُO;r/E~֨Miܽ&zD-, 4}(k5sĪ Zeg$v¦鄊_O1LZ=p|R2wb.s=ddD!4jºὛ muNV#+itѲ3 z.S ̓~W{z  Q M C#3#ӹUDL 'On7|Ugk vX#J\\[v; $KSHdP/|~NNcAZRyHU Rwo X uGrR?& β}~{T)b*P K)Rj|KﶱZ.m;f8餉-Ӈ&hD|1U@QF|{oѷD`K2[g)u4( '1f LX O& 7 3 l  'Yɟ$v^dWl41OֽZ|oEf:6y A[&P'(Y5;p}LAPn kKg"F? =.nAml{{~u쳮&В.!+X6KQG{3ywU(G=&2D՝{)HI< C xG "H > ^8C eE e` = t %l՚Ӿ}c=nxIC! 5 n+$,Xe rObi1R &UP-Zv8!Aaֲ!gF~  B MA 5 @Ff l Ŧ}kiMw-livG3/6 ǽQ;ј]hA xm3}~4#mdl]G]QU } d5 ~hkQCSB }uv pe 7 - 0 Wl)d`K׭q*(gQF=P N -Z]22fΠ`"[G`+TeojSW&{z lvgc_%p@.>/ x}5DIOT5%[]\ptzv_zhz9zʅ^b]pYdgXVzOjfYҡ> z칧Fl_s3мXLma_vo.DAvTL 蕌E=ꔠ]`<.|KfE#5`=֢zlp;6yCr*QuȌ .7 /!V6Gr FyQGU2 |f e } K v d ש-!< lbxW<**3fNJL6;[#e5u]8x-wlJ9oxXYql1U z %{ # Ǜ o-{  x/ D  ʩXxD$*8.?zlʦ #| Gp `x ; Zh?I /T Yg^N}b!i[#qd%U'#(ݱ(j(:z('7&^%&$"=M \5P\fK1 0l<]}Ţ2(  I R l_ ME ӷw d:-&)C"r(ͥdE_VPC_i eOrQd ] y;R ďlxRbܺ L[^R#a 6 E g / G 5M  V3ܾh\G(S:vZf=~rtuoJwP+ 053n#Iem$LoajW;׹ :d]uS!pYW.=`A4rfި aq"ot' J"4̴0 uI*6Q T>Zi1q6)5ncCkf7qE3NM/우K]6v914빭Wp ԉʩMאKe[i|k4Ukt}# 5X!\:}"}['#5?by[dy;' ~_>$ 378& dH > -] A ۍ Z !&M1eViLB T-8ۙ5WtJlE*3jo_6I"IbaE:[gD۶bc2;tי4OJץ&ʽܟFM$\;Sdj:=nlVab[|hE| W/yrf*ӣvк\۹bRz`w߯lo_U66MܐC0紜gTku\%SxMoȹOWS >c"b[ݡ1VNG3?T!pGJ{ kK 8X_< =1E?N/?TRJ'<ՏWs"g>\9BtFJXFJ 쟏p ԭ )  } f9tp4Vƒs Mۂ%%]~ 9$R.4D hk9 / M$ P 5V 1hvD5NUc9an6;}6Q|;ϿlxUcNLA6D h÷L>bA:< =&"Ő"W8#&;#n#""I""u(#=##"!l!*,F(WnzXżR c ^VIH;ѕwY3Yі҈+_ gnfLCzQ UjIpq>4u! *N r ML[cEqft֣ŹY![ * 3  v ;I@  a ^ fEC ke 2 derB _"#b4$Xy%O%6,%:$G"& PYo/ "}|1ϱ V ad  n\ 1 I\l p7yd< Jek7(M ީdEl?%'SiH>t\.hj3 T/~ HMkPK?vB7ZO306|ym/ø&Os Pΰ`JT  ^ B'TkحFf8),5hI썦" vu;T݌*Yj v 89u7NTZR3*qXMI!k.2𼥇P}l鲉5O\7}9 ]b%=/i'X򆝷:q U l&pqYۄ LwcSx切#HE;MʝhKvMu*zelIz0r  b_ L l `H 3v_y]OvieWˋUm,yq ,t* 5=A.Ϣ1/Wb"dOj߿sIsHL *!(E%#wR{HaGy#U :;RJ MHIRq'&z&@8w]:$gھ5@1;IԜo|x? G 3 '[ >| N1 }?l c\ H }/ m{r;HM1E:?/ ~D RfNA7%JrXb =٭? 4, p8iJ  U}  / Px # }7/-8 y-y6?a5wȦLFT'dhU 3+0m$tWvuא)^9D $ $     2, pj g && L}T"H~<n^mld> pOX{ \ đUA,[q :"Yi;u%N_ W c@aL%>ő^mؾ5Έ(/$dvY"zl WIdqq蓁#x3\$x뭷Zby2S4Z- [$0)%zle{. pf9X*#d"8.Sl P>Q1J5l10yC.F_츙| K@EA*$ ,o,YI{((X @P.%p2>ȁHp #p} _0ٿU|wX d ] ̺#s|f\^Dmo1  '< M " M 6[q@'=Z8BhbJxkOXMN#I1;{NJH!Ab2R&AD ƺ<"ME"P;#& v_M8Vp1c049N^Da E @ ќ | g u px  |@O KV+,$ba<<æ͢rgNa P A1 1ͭfDPu$&?@';5 !R#w P$T$y$Hp$$_B#\x+" `T3|b^~cq7tOH| Z \ l;c` 3Rzkн_WoHØo]j1 Pg4sP8qo0'p0P),Gl0_|D`zɗiqnTst 957+aCwuXz Vh IK'  RjC V c- & hR$<7R"pN#W,q}pm^{W2 QwMV?swl v gL7U|x[=$1TP1`!KAIv"v=C;&ϯCo4o  ˹W^  $]na,D{+~Czq!rVBs O?e>@FJvvcwȆ#t{ 4 .]( 멶$xz׶D>WPs]H2. Y7ۻ!o#[hk av9uP0*gy̦ݑKfibs]yƤ>ʱ}RuR+ݞk51Fˬ,$PR(6Q%ysGk鳆:=^,zꄿy=특-fwܩڵ=!k| *os\&wHX#zHCZ4Ta.84L3e{i-jgP\1V'p57Z@tgR򻞂|0.OtGKE~DB_m2ٌiK vw+L!{Cd%|Y>/9\C, Wg50\ o b?g BGWHpwR2Y[^tvt2<1&`ysD = i:ur-wZeB{ʆ ˄iESed'( >DpfK7 G , CEqkRxP3Qwf~ۓ@cb%]mk=S3s9פD{rl&b#U!,w ÿ+  b t4a u' s ;8$0?;^vCnQT >v8Y~WdP0C<S ?>IEɻI޽ |7G$LkgWUxHd|m46r4ND4Sq_*fM- lE_ivR2uДߤg! $8 C^[m{anS[6kJ wK{KkI+[hiJqQ0S-';";$R+DWNE):4m6Clj  O S eLGpb!EjKapRZ2y Y q Q w9KrZi6H2 #dT D x)Vf 7r!r!b"d/!X r8kGu9n{ xFkK1 ;\ N׼usp7Nf8WgOm0&[;~]&MUR ɡ\C^184,~1-oAҗzf'mzD qW'M0CxOF In  D'^(eLjuMQUճ7*58"{=Kl@`gB\! ׅ;OYR&r( U R'O{aV/@d=R-y(E3t}'y3.Y[%wu Pz:0|R\O;F 0IPNGJH!'&G`z2xD,YRFZ$osp챀:Kt7cuE^0&&J>'Sm < W;@7)jauY[W,&󲍅U-i?WU\W =ͬy9Y,>iLjo 1^   24 5==7^D-fM8u>TmrI UO ) "Wn" GQ$]pxE^x9@ }_ y$ ͎Y1IO8 95 QP aeSTFHbp!Uf"1LFߐPNMXSnS9NJSH>Kv!Өt[`@f l~XyXB\۫~KI$5qRI$'=ס Ӝ{  Äh " 7EhbD'Zn9Iܥ@&'_2 g i r w ғ;l.n&[6K>e-d k P x#;x2h iQ0Q p 왏`a 1ZQPt~+߼2A əeD4#0쟤+WD33KY! y` 1&fsv+vg.A(m8Q1T3ܳKT '5z+،@<) 6&|cqg^ wRrGD^Om68d8au%zԀPK\-/>?OR`*>_a꭮k7p7xA;ߒ-4w#ds8΂ O,ߡﲫ{"߷:Ȕ)zoW:0ն o"x焥"@*ā?Q ,fEs.'hV$@.^@XK0-/ܝlc"A6w=}M|fYl~5-e5$'$y<' @;m,j+KHUego/j'clppX\G&|bz6@mX}T)vH\ |7rW/Rޛbu>G$Y^E` ens˟5CRWoƬGy<‚5fjhpy2xBHVKLݥTxikP'֛LaNuʱ}4iJE6XW 6 : s(jƅ_'ye?<.+ f@T k w #rSE<f qY 5 E QN/saxL{g{:A kF?at0vчojT3T 꾭nWdI $j sSł |٩|:Rhb |wKN.p8TjyLKʘj'Fj]B*_e*6w&!DaU8S ;= B  -{;t-#:٣)LKn9';4G/O?]GC$s ^GD#|MpOΙŜKH8ڇMeDpx8'iM0(FXsR8W`k +07k }xE򂬚ֽB(qx}`|ݵ+Л:ny[KefH_->sR i@M4 QcH((XB}#f|cLHNG5zd{(Зw ,F2+@gudҏ[9hw6w$w}$E`|#ȒBD<+\@ +$)A\}y/2}yO;EfqX*>(Y)# | 9A1߇JK Y$(%smL8){<U;T)p|*[skYn % X 2Y vʭ94(3cI_5@ĞA!'Oe# g j v^J~@,Xpr2 Ok F_ K * (M . m /L}]u@$r^PA18Rʡ ƚHf!qb.cj&YRfmId>(8rhO|X jжS3 W gMۛ"0JtMC[u=ll2ozhMX T]j6  zL@dt!8i-6ASi]t `k$ DDYr'9 Y9 1$h)>X6gL2Ϩzn7] g`9p_]:N&p xj'&c7\aR75Z>H152]E'sMAv1mN.jXLEY[pL.PQeTXY\a+/`%x?,9Q6n_GGh,8~o)5f8ju6J|5^eoѿ$vZj?AM%[2Gp G~SXن`ȼ Пr>zH4@sƃ& 4R);RvqT ( p׵G^U|i,&ZrxK-$VqI_y+Ӌ+K_T 0uz#IqE&'w _ \ ^bzEshDS5ёy/5ifK8ಗ\:Bd2ؖRcZ m/  D'?@!xzFT.]K@]x%:8OE7 p0 >/ט Ɣj<I0Q,#DPWJmo(CVAL E-C%~`vXWcPi;*7s_ M _ ĉ HQ + z" 9wTtNaDK12cne}\hvGSV~  , Uua )wOT&ȊM c z  ;T64>Mgզdz%wbMTf  % B7 " >^o !{!Ģ6[p4419_7 <vuP,3ahgr1ti:c _ G@ψ,YxQќJ#Z{KO4ʵ%042$oVzv4oaKZ[=c C}ߧ;+w+v\ id_1,WdDDxe.?&`]I_MmtǗsUtpl' "K Խ3[Cۈx7V+t5 iQod-ԍ21:KO$Ѿ]}@J^WHQX(;Pq18t W_Yg${jzr^P--VZFQ U,vR4*AlT$Q#_] ̵̽&^K ПXV4$u!𿂞,g|}P DTzX,VT\;rluY̾/8)Ŗxg9QW!J,_iHy6e#$KYr\e̦4o[) Cw^ 5 tN] `"'O&)AE,ȗ4}+^`;MlOG~=:G~#g\^|haFhpPVnpo\\em]@}uA|]*ڐ62 go81No[w` z d p# j Sޛ~ks %yF:!]f5 , X`b 2DbBD8-5@le|²4/AX'bwXMrƆ!̀h )D(T:[X}O;MѪL"r޾uI y,}]~8"s1U0/ANNmZJDYf  &̺ 0T '] { zO t@ELٍ8[5q-nx@^cj4 /w1 $ Ȩ R{ B;LxPiZEtKa)sRSgnuߐC4KFJ3b ʣMp YiNHli/ `  .f?BD#HST؂Sq  ͻ]zI4Ug[,)<;x4C~nźVnAb^WVr* \b U h *+ N^ o> s 4" NW&m=aٱn$Hk.nbWw aU lL _C#=_i+Zz|^ݳiw,įUYK$"j5~.nuAh VZ$ W gtx9xp`k>SJ PKGam|yHtCfd>UH5;9(i*(R0ۗ~#Rlnq]s`1 |M?oXWok4P JyX.*z-uV\(caV=OFbW+s"I#JUa0=^{MnSў.&IsnRjMj1/IiEQU- JfZ_$2+%F[_ d s Q B5B8P9GNt2ِ=\]ŒUBZArN;qwvj3"Wp}p:}[[ r1B Uw87nG i*J2AYAVrdl`X=iDWgf| ÔIZz7O8,#D|&%r)ʪ|IQ9l0|Fp7!R2XaTh#dit1~.W6b*r|vhPTV[Ry 2 %Z nE Ɍ V8^8f |a([-cOOqw#*=3L[M!Ĉo,A/c6QX1Oۗ4jUVD5'`Y4o:LnoS1!L규V-.yAJZ^n&8\*HH0Lo^fsYoC}acZ0yQ+ 00 vgpOkf|VlrKNG@\!i.R/fFp>T1`KYq,C즸. =XQr>@f2&=$5a_Ŭj\4PHIKS*O6;<3|Es `zKP(: ;jmf[CD[i{.i,8 OWMlTKilb5z]Oj/DTF9)6Rr!XMֽ2QkzL+2~21n/Fa']S S_,3Ubɹsrc>v'O5"mqYk0[ Xw^Sap:3Z c!M׏!(Wxf@Y\Zj|dzQtH4+6PSs>s~EGc< JRD)ou\w{[>F~o4ACqA + Ұ\  Q* &p Jɠ c f . EbZ  k  m4/Wo7~qG|HpZb)\i3:R\zpɇw:]誄P:6R)ON& )EM}MjЭ9 pi?k{5юS5L9L)낃iHF:$$eSsRҀS]^%:=zLkU=^-K],k"ggEalwMme  8d g GP +;1 X J 2ȫ M 0O H F :  /_ ` $ u [, e +o> 4) LH W %8. _u-5d|'!`). 9R#GʣS ~dHz  ? N g^G k$% !pzƌjfr(sx[5cbX k nfP\VтKȵLnԋ\nR'usJ[-Y   -u95'-c'.x<7yٻLis"aWzn[g0N WWx@tzH T衇-'zHa>N 3s! z(=TE}k> 3(UݵgjHDK-A]/~]k*k즪f!)S9 Q(s=ۨFCNu7z^jǕ_O3ޣ$HKCy{bL4E6!~E'74=%ΣJm I/M*X[^UešpقLve_k X~x$mЃQaI>C=Y*"[\[; ['ͿxEy|r)>PNҹh2Ye/ z CD2fdZ*u(@ BFa.\@K/Tv/զJѻ~k53JS_ Q{WlzNىB!h־\Detja{Hwֳcx#|P& &qt2sq75iZ_jEn`(SGJgN|>ށ[wY|brL`?wC"\j{g T/jqm3 ?e|@no0?0JLyNa} H ;@lm̐k3|] 2bgwOw'=5~C" }~IIB sшCm\ɄEiz[W nHO;h Q{&^u8#Md Nߡ]7} ^+HKW6S% Tx8\b)" 76JJe83JVyg_vo6z)}QAyN^QV3` ^P\%<b*qstي~⑗waJқmA-*^Wx4xIA_j-/m ݦmNs˒%!Uу#"%\ wb9r"P˪W . 6 T: p ™v O @ RP W  .H_ B(~[3iSG-fZJ y93/{īЄW [ 5Ģhtj leSGI~(M=>ҫZ*64i7ʶ[}^Xj>¤Otu ov v@{ETE~( h8LpJpMHtR>:ۿJyԭ>hN!zC!f"APyq7h xpM jl&r{ͳA=$E֥|Q1y,n)EtBV26f@gb-Hq±|,"Áptmv[$@} ]f5.kb Gq&[l@PyDP$#jIT,"b{?:}WotWuCDEaQ666WE NA1Ǣn y ? H ? (p d ?-[SbgfEޜ f ߪS Ǒ 9ʽ $ cz^WY+n#8 S B2/]a{R|];ML)ztFtJ_v*PV\'TiZ|v.3Pz<,ٱrsF0|ȍT3K{A엽fxWvo{tG1 p 8 ` yD I 7 43 B r ( Cb?DJbG9 aUln/)sd 8ɖJ!@9LRV\M6&|j$>=üRfH!Yh)MJ a00"JW0Z![*K4sV)>Wh B9Dz1pGq?k (XmJUpqI6xk_ET%L8ZP=],PKN/~i]$3s=JMU,GGoյLpC-t^S=F [8siw3SLK 3vW5 1ΛYr91}wu3q K7ZEp@(8gڄf)TK"IF:@!&Y.fP՜G`~}+ziK֪g]nCF)ҢA'*iHBhV}ҕnF̍HNW;S605UQFbgx :Q' (Xi@9WuEy Y<>y64ڱ͋%wI.Kԛr_A<,I?N iҰ]lo(Ҝ 7i=bkI5ġ!\]d姤Y 1KirY26-ژ*Qq%mp,gb`p ]sn3oJ!7oIz/ TU Z w; TyoD-V^56;n 41P2d+{D.iIXt5AAjV0eG㷜!3i*LK 1b|bO) O]!vt"ضiy ͷ _O W s8Bނb,/ק&GAXjT%}*D[H PL/zs 90 .P X dL J @ h - M 0 h F9 zKE,LC40=ArhY&h*\AT$Z[B9Y+0ڌ3C9PYCUN~zYܞ>'+!`,JJ8LD/؇y3|/>$%&KݑlPK3>Y;^}N(c r$r]RqQs4D+e]?NNH6Lm5/x!n9WB<;&6_,!CZl@t4otU_!Jk684dH~[]jvhgFlE|` 56?fǶ"t_mT2ϫZ.G\ ! IS)yf]F|3o"C 2c L Gz0tM1Op#*4W 5}>M ħc4}ZRj*+n.ejc,,abVgM@wżYS;y"d x$[H|SP skrzNw/@4gP+a8N>v+(}Q0`B頯Z5է3ՂKr-lPK\hUVn.Coz7ՙi%V9 ȴ4sRc fE@\.G,)H}B['W$uG m\.? - `."l[.RA.y2O=5F:9 l3Pohw"" p;pb}|X]^9+yAL=8\\xChHKSFahMӾ% @\*tm5Yvxk7Es"Q/)Å)`2ʠ2f]O2UlQC w/C1V1Ӆ6SnDKM2k.$ Ԅ7D]d"J#qM?`҈"qiVr=ގy>BfURYeӆ]"P,ƻܷ琰Nr=Asw}=%?f'Sl qI6Z3J@)L4%, Nvm g?&.XO?`ȃ,MG7IAtv.mlkH`"Fr3 ~w@ІV7;m RyQSJs% t^^[N~\)@7 R*g}a A`ZOm+2qsE%!?@ZTy))I3Z E61JH2hdĺƒoR:mS%!m1T8Biц$oV8;[+i=psx@ }fS .Z|Nǃ$"4Q93! ̎TzBxCyYqlz]e9Z$(HZ- գ PF%M(6&bf s+hO4}s,&!K@VZ?evnstpf~TW9IP4LJwh7 %^ekO$^uL^q/<3-G3K_t"`'6#P_ AO\W>ZKpd~ ƒs!`G,yoj۳ Q.Ax B[q66 r9%s[j._t-ǑO<0J rz F'L4&bw@}7EO4ZdA;gC+R^*"kGX@[~6N[1y\ux<9`Zx!}L[RzY$TdLS<3P2=N:^6W!Xmc}φ ²'qVi2jFoWӁ]$2"_=j*Ik(@`Yha 1\ԈѰh/m NW"4N%p ,@X{kA}[d<5YksưoZ`oUE a;Tdu= Br5'8ZO] -Ee\C6haKak6 |&43Y$buजP-)%OPAMBh48j^,XUIFXZ-:V~AkjenoRQt= -U!uz&D,dDN3fI%(Hj e!(CL?E,ۿ aE=!.U:MLl*I1&|'h3HIgc/dU!OHVڈ94St P8jU`нaV3LڿPRӺbY$K@jlܤ;.;`X!ށpWfVNC&:ޓf&O-Xi"0&_7dexszTe ~@TZ?p'PEnEɝV-OEzʶe>dנ|܀IT$-ڽ9\˂;"i,1 .$|T!r#):+M_-:ŴXqjiWbsJdN=x,m昬ƞz{d M<26Kv|7NQ;IzTXB)pQj+3tT(ЈB]UwV`>d/b\BUOyK~JtLQְX`f kol*Qkʟf^}TuGj9)% J#(F]G?`[e[ k)?MGwC0 :$Uf&I~" 42*zFUh*N||T ]X9#vL mڈ!"$V#s[7 ])/ɤX$br#ۼR!WK6Oe*t{zbq`#HF+ mHϒDw+y-uwrv9P+H]VGMx2%D}OR\8c5Iffyffh6n"wT*ޒt<n:p]ge#=\t|Ĝ,ؚIwwBc 4%Ϥ6"pZ]{J~7$ [C'EY>Y|=C}|ZW[50 LE")F.Ax2.4y68P;g@xGQY^]`j YxU:|˗ >hLtڑeVVhI>'7Ե58AvOc%z%=7d$<52)ER^ri#rBz;4[:K{Cs6=hAZCIS6l! /XҔ6gM6#W/ Vir j%_%D+!16#:z=?qAA(Aq@>2+=s;`4:8;9ܣ8/\8;88JQ752r.;(k {Z0:m}Cv}n 6"1AAQY?aUp}iJnQx"+pj97a7g+wL}qkZZUvL9A:t82:w@zJ.Vb>o Kz1-kjZ: Ԅy"s /ltd\(TGLC*<ӎ4-k'! Q?< ݞ^(T !;g-]ܠUVN֛>} H6qCh#EA'_(kU>{ӈ.VWБ t&r3r5} Y*xp+yV&td$ ao/aU,bYJ~347/?mZ-<K;L5mb!|Y88SCxāì H'fenrir-1.5.1/config/sound/default-wav/SoundOff.wav000066400000000000000000001131201317357605400220720ustar00rootroot00000000000000RIFFHWAVEfmt (  8qfact%dataOu"f'J *Ph Is?LW:כs R8D^EƋ@iK*[*Iz^[j_W`TՈ0 9ڶ{7PuRB9[ué^Bw5n m=7>ffdf/3b,"j= CN>L{TeIGPIc7QRE2`bT~Ǥ*ja'_ Z lw>ݯ\j$d{ ] زv>UvF$m4/ӛy>JD*^A& `Iٸ}y@T _=B k>s*l?gpSo&t)6)ԁV[[ǧVw(Fn 2]7t&猙}w{k]2u0̄=&?[֏ڹkK\Irnw`^h@4dr3tlk9T83 3A'`WqP宋CqQO;y~!MXE|g 3Aq=0jXHtKz/|-pRЭbfLh+j7f򦴼tf s !bno {6#G jJF#o$&߲/ Ϛ M2Z t92tr ϘOfew~R(P4MS .yj@}b [umd®1r9Yq1')Um'`-,(aRhS YD>y :i&du-Z>w}!q 2KWפ0e߽|6+韴r!v-!2ADF`0FZ?5oL)A|9b[-8?GIǾDZ6/pi'h|W@1a(&H D0[8ވ`-Fa$MI-F'Ol _g C!u PrE@\ ?W*3 ; ^|p T9@sc$a"!"hg 8 =, QSc 4L em+EO Xn16F;[grBm07 6u ~ N6F \ Q/_~`mC!(bnX)$L#;8N ʢ/|. Y W GkC{3Vp!Q*2 Zd?Gfs/0C6 %]-?3M_QCH^B|ې 3}ا6/#1 ;GsUQ7u?'3?򨍝˗]ſ  G Boc7|hĺ( WTVʮnB"a"Ŕ'wi r_ nTu; ?:}=)i5Fc gI pjBcq )0^۰Ϻ5 Xlx<"@xޕmz!!VR'R*!g%-?  n   4n n& Nɱ0r CU_S2ɳF0ݹnBCD`=GKU g%6MAKdX[Q=g&PK~"^XJÐTDv20/C\7;iLݴ뿭$툘~5UQ7=Qe|6 W dkdf($_ /WraK%ӱ3 #y gb%X E ?d fy(zM7/b6 T}_,Dw!\C,__ qe5- O>n vH< _ M"n(6)"#ze1X]@^)f? ^ w=t  A.4KΥB񻲢U/~H/aPChc X-Qxꨵ% C}!x+tNS0;CYsII7vL̺ b`3| ULX7"jI+ v k 23ǍQSa͑hA)Hళ-buZ# 2b$7@-zWDIg i `MTr[nGm$^)d(Iq o8j n1L'kf x- EZ*zNd!{9oGHܐsQ<"b*Hڅ`o`pwhjM8Jw /pk PH#P0n?ڏ9cSjrY(-K"!Mx-慧sw V(%u0]z#, BM /Nx7r tρD)'v3IG<]Hv ^  MX<L<>L ~Ke;6Cd,!2"{7Ԁfd  Y), aL ~T Tq-z'k ,If4ښ .AcwsR\E R%jF)g&e 6R ^*]s5:m Khr  oչfG 0sWCJJI$7HF \OIGcS.~sᙢy)v̋@J6zM =6Irnpan15ԭ=U RopEB|3#Ŷ. =/vI!0eƲn pLh6AA2_+Rr X2_1 &+ (8 $ )u_c*crR&OS"a fѼZ :h nN l :(+{&jѿ096ݛ`#2 j*Ev(!$HP Zp0 e.SE !t]&(BT$տP< (%b3 M v{^0G8E9E.Q"r&ߝ,ۄD. 6vS&> b<$P#Y$n fWii['-X)%xw1z ~;޲^b.nKqaUs_Q@9"Wbx:b\l2eDCZ5HKl`i 7cJQ"@_cOSS  =(jgDy`"0mUSſs' ?? W~ |N'u vY3=fRB<ϑvKmk ¦ ew#4G ":r\@"TM'K?(N"N=SyrG!N ,  :R7rEʻ# f,g_2,Nb=]j8XݤYۥ14'|ꐷg_]+%Nf)reZ_Y]> K]5{#+iUkUr;K\'ޏ;V9>3Ů!s*" >  C e &HtV&a" k0 8 } 9$;R b7S_LƬltHAw?!H4JUft< b;p~>bbSl3)Q$r39gl}8J.WxR(K]kt~%S#x1$>9wvjY?Eh#nx숅DE2F9[$x=-'1XX  X |! qlA?PQ!U  L O g h?^EQ0vmVW{Yq):=_ kG&98"A] e @͑ȋ(F; vq%]s(%삞f hvvu4 zT yNG$%^s'>B끞O Ϧf>ƭA4~6c_^&Kº3.}kWT3U$?9w6||<w`ЭoFx|Ƚ)Tؼv8OP-p b4t\)ח)SiG2qOR7{oK[MB 7+: ȼ%#_+`0v#wUuTnV[ 8 [sڶX .0BgɣkZR'Xw  0 n ڣensb }1-EZI).cSLnt g=\ j [ + jC f.5: lPAB[x 3#Qk$g  O BW|Y4<( @[{L7Lrmw!srTVPB+.>{ 䀋T頊bg5_ 7rue@Yf*#4A;U\;S^k.2H}d}iUk6ˀ^^`k ")zE q?\ۋR)-*Vڒ;f+c.΅ؠ5ѫ 7Č --&taRM O: [i\f ) l ӣpM?-CDM!z#!#۲Uh~d2U zBB_wȱ;P0W۵ғALhx6*S6md\ZW 8*䃷籩ꘇA FkTߤj=t` \KeE<+ S ožlys*g1 ߼mL>bO!ptYDf/W=gE[a%h*WR@xW T|u=.Bv$UW/!mKG}8OS@/./]P^hfMT>ȘhH өgФ%qM E+tQ{ĨN2rޞ3?oL6 : 'YќЃd<  zUH:B _]4/خ I u3K 5 h    me!SUo!yb##A!F ! wH Лr 4I7[Z> [5[ҧa͚\58`j7^v\9-%29j/^;ǻVQsEUq! RX:-aT>GMuM 1S 4Hf4w]j | Y L/ J!jd[ ЏR 'txF W|F;=?.TflFAdy״8a [EGW>k`&u>0h}!}EJ㞏 #;ZrA*EKkIxXC:u4qZWcyȩ X+9 2%x:W5JU YoR[\hݝ- QPC6yLIU}LR7 {[ٰr0/ D7#XRCv035 S ٽk W'0ª=rO=GoꚲyBvNhR,I4S li`NI#1MQB@ a%1R0x(q {N%Ꝍ=أYVN 0.&l0w-:'-_-K33x2b23%^&;!BCUe l!B_B7진$E|p(6LoU,!)|\@譡 jHz*Tmp Mٌ) WTcz)B66I j,hs$:B; "밭 O'ؠUrط ߛ|*7w૵?GmlyP 0N% #d@1 ]§0uW= r o8~s0\m)`'G Gy[#|0 jwY x){bcڰD 3 =QD$7V7RDetWu  !IRPKVIDBDg g-26Wf45+D&E ; b"(P'P_sʌ[saEv oF!̗)x|xn4Y:rN2d4rdB֣MW./Һ{Ĉ\N>rgPх-sSg`ASFN[ ]}Se녍=z>RVe16ިFl;z֎Ŵ66Y AI P27 i T"I #;!c,5p6H2m #D&mZy e>  h$HB)ҎW>~PCW]nZi &V\Io4 %[Z R:r_'Gi1XY;fN;Ф97w2})k#}lskr3Puy !/16>JDvt -5X^`zzՒ?B1Q:5, >q4S# ҆, |& aDm`31$[TePu݇61xRab==R~Vdc-_N GAL~hP; rڱ ~!pY+v#ou&x!os"><ҤA: `>dvKՖ(4G1#bi^4-uxLF P'[)R 'sb:]Fdh)S^% '{n,5QGi9@K3 I z axDqQjV $%2S;B7< %/&\-*Xr\fhC74B@;0Q^ mFex.d*C`9'.4Vz(e@v<9(cK}> d<Ҹt}+0 AW+)@< b Dzg@'h|AN"{kb榶Y 1Ir`g\ ;,/ 3> )׍ d QA;pa"|t TO  < Jl tf5v h0Q""9Y`+l;N_2I"da3{ hRN,y6h3 3&jo>]LOujYc' >]0uUOX}YIK2uVfH_ 3 "4R#sj(W B0&Wi(cN>oWԀJd}8B 3&)57 /Ua\` rIXC$\ > 2)0irۜ]՜NQD QFp?]yޣRδWF` i).QM*  vL 23ڷL ?-Ge  <•PX"wF!|MI֌{ Xk_uvLp#6uPt^"q'&(V!$&Sg*.b3; uw;k2慖 23x߉GS} ]Ջ'9rഐujK]R"jDj|U,궕rHHkQ09-}~=iPaM+/j@UՄ^X n  l>3I-< -j!=}B E AV OUpS Hyh{^+,,\͌oQ,?yZa(FP9^ʭ")]%3t]xl03E" 'rx$g%ukA`* L擔^3$d>Q~-F*1"^ *(r]  i vpG=TP`@$fΟ)A*-0'G"<&r!H"/*&ɦ$"9]4n\5Bl"t Yc-}ta^Vݒƫ]K8(@xٌvv/ҵL\1?PҼp95FgGV2ReUvJT ۿ@ɺ-܌SEʮ9 z3& gC^J;rt֮t 6ߵnlML 6DIњMc)]gB~ߠ#Q{, S2&\U>_!< $ɏ!?z ( 6W H*^*j(#t8&+'e 136 j O9^-3 xwf()XN4ӡχ ܵ`A8 w#m"xgxRE4%|)d).>(D. e `2sހ>:Y3#zS@v6 w̭^AxVsBpE> ];?&qv}Q8bߝwЄŃՕk7"[ q vTuz8t߳S j[dBvF/e78łK~4D_JiI)?k eO tظ 0nST% *VMȨ0R^>7j2D/4Rԇ2#0HS " btw ר)5K 40 47lQ2%)XS-M2, 'N,q>,#;mNUf5n*K)Rh2+ݗ C>NhS/U.H?5ͦvakkT]^ hK6vQP ),BB+WU#Ngf$+*~0E3Wk$4Gg k(_d޵`<>p.qM%aF e uZZaW$(=l v=>} 5[43 U Le"vX `k A ocM&+3qe;wm|暝a-JB3HfkmL`S#I@SNңzW.|Mr=$EGdR6\ƯLͽ IR&fZВ^u0 ¬s7˿"a g P̼Ŵ~* s'dVL20޲Uշ- 0g WՍ9B۷+7d,f .%8c8c%W /tp* t&B  ( !}- aq: j\03=@|{2 H{sk Fp$ҵC&p1H ?F;|B| Wq `v[‘S]ȼ>u''Jj  [79J am"\sTȓ~Z)Nz+D'&oI {|xCwo-CB@I7X;Ӊն$p)WҹՋl<3;)5r:|Y޸\R7`)zP+.߅}܅pߥ3-+^G3A[{[ci %2R ͞IrݲVp4S, e U 84 0 x/q.^?5'w5 Va j dbM %iڬ! ! ^(l(%cSuC*0 Y dzDe wt F6 b g xC m &kQu [=&;DdRr+ z3<>]ųRN P"V. is!|}y p75}WO[$,(b2Uݪ3j\^8 ]ۘВSDaȈ%A Il5Huc&੭Zzit? < -,5v "̬i򵥽~V]Lrgk6 2 HPS&}ȅdcZi5F[kEn~T%2>k+ۗ0b՗ e˝<CW@4Фt2_rM 0bf0= :DC| O Ѷ 2bWvi3urv4~ {W:r`w 5X !%"v`2'E(?t"fW5z +ϥ]y7a?~ g0g1Rn}TT?W IC@]ssYX~c_ejG+C:GR!T5K'H/p\)gs Ķ yiEw~ v7qvj#dkj@^'Ha9Kl7,Yͤ7VٻV݇1֚Go^L q cYC8 yf}éF^DpM:vL.қ 7HD>2n+{7 A+(/HR X mެ] mI6E J^ mԤ9c"(N}ck8,kG׏MdRS!za6'p$摏V; ߊ3U݌,a E |T-+21NJKm9-[o`\\ V P UbqnSƇoS$J G/{[Fa <6/z*FYM 7eF+ZIRV?oLBf63}\zZ=fa }W< @Ȫe䫦 "X M&m__N_/W+ U+;kq)%A'd% C1 /=> l`?  P Ū.:gbnN4_yO 1ܑPTHUòvg b07 Y RnuRJ ti4pkުZ<⫓%i?.\OĊOK!۽`-۝FAOI|{Z۬8C:"|'b-o']K E3]0C:[Mj gRR彊q:屉*,eC#ANPj_#G=pF?hI> @THenѧbW0#T 'pS?gwgix0Ju_GH^5wwy TsYPp s6.VV+2 Bt &! | Y x)DE}]`  n o1 >^\@=+% ]6]_" ME*=y&JB D :I 8tk7qb.W~B ؓSFݡ}ힷk`I]PRL~EY2 A*Q-#k=!i/N]ܹe% soځHچڬ/݇u XﮮC]ɩ8Ͱg/r:@ p:fӴ*JSVV*[qdt%$tLQC,M{c[(0Н[vʕQR+u'?<\H@L o!=@b-.CˤJɶ:j/qQP=,Ж wt1P!x]lpmp}B>?:NgXF΍ N{ tM8ine%y(*H,.C+HE ;m)'iy1&fukI "[z ,5-sE8]Lsz$hoHxdE˝LV[ ( <^k%тϼ"ϩ|\w܌;)+WA}f?7p$~EtZqTi#h^/a\?8'9< <ѱ& P8( CCKa~e>7?ˉ~!%ޗ/N^3簦ΐxO.xP pwߖǿ TD $DB5z s *D ] T8ҹSkWx~lq;~JAjP^N]v}ʢRo ;R#(HI%;5jnS |z?&`wI:FJbp*֛S= qmJVAhpNNf u5yC[ ^B슖kZe{Q9f^ S<oEJ  +(H)Em I1tOy E ]U/ZH<  0;il hruF<L xL _' 2zy9&z8K-)n "[-39)85rG7rT4/C&9 |RT Fne^=qV~Ѥk[dmQ)_kyPu⌝3aȱG~L-ls&> h _B ]p|A%=iao_O'`v^*^پ/*3d4V%bEjDi(\;ڦ+vԋW`B _1ů~xU~sk``ʕENCMN4q?G;<xEa #  .r\]q*-r$ xb-|o^J)9]8{y僙86h0r ,R ŵ {2`PT ZP #"">z }j4Dw?rooPMSrP4$=#shN,#-Eľh1xsKx͎8 -]Nv EHW>"}BkZ(|X'@)a.r*3-\BvI'c(2-y'1q4V'ELU/;1'KSz gcV;oId 7B|]%˾ ,[츠/ kPm /]Go8 Jfs>7 (#D0^}KsXCgC&5f&3 ZX m of-RZ%ožGyz(yrVyy4U=yGX䤯ItEF&v_8ڨEoQڳPQn%I'8AE4/(('$2$q""(#i$x`9/S c  .]EjuV T@6c7bF']EQ>i Oӫ.X0XL$:TaA1 ;eݸ([,"GX83sG ➻qHf@ p=psf71X5ym6OLA0;%ӧWF Lm _} WYv- Sxh B( ;^&#!J!]h$O.E/8++0v6&s< " @)QmqmoG ܜK2TDHM? b;5ܓ`$zϛ .{"ҋzh7kwʟ5դ'oh'[tQ&D*{&3vc^l2  ^% нmuT$>m5o{[o f42 19PҞlT+"KGGY.$ 8  >` ٠1 . Brxc$-<+& ?$Ъ-N>@ 8*sZ< 3 gWo5:D(RΏhWKJ^P yAW)R@OX*9O/ (4'k*-A3H6#y."PG"P"Xu+=)v*R&" @8aS#a"܌u[Mu/܈ک)ߧם&E`]t_-rt\0cOy8?NCP~ FG݉. L+ إ`?EmRpm!l9 z1oLy}Ffl@ids6ªzJz KGvoSM.В ˄G{6g0 ^yps?b W D/Grw'*]*(Ѹ*_/4q64Us5w3*Ac#7*&8#;E ;QX7@&{ 9 wWqں7!1@=%Tkߑܴ3,C@ ޳/D\ .t7Iiz!b',?mwr᢯N3uOzs"yN1]U8E?K*9ɪH$mOb5Ka mL$0CV4!@xz^{-V+Z?_m컧!3z>!v!4+b"V$ G hP ?e, cOi)s^^*Rûf14<eiNI:< TDS qKy1 0a37\'JpNj -O>, 3Ju 9y iHJ6gHzwJm' GpӨ0r?''UWqD5d-b$ IU+nY:eaa^'õT` XC X䥁PBN   v DKӶ!^ g+~CZ8!. (;  bCuҚfPHu4%n u_w(-Dd,o)(($/r,7'b9ђ7v7pY6%4u4Y6.4v(/X`&ߔ ","rsįyN[ O+8?srm9ZH q-VS"aX&; OW`1/q>0_pސRT  sҟzO kn,%Glff)۲|[RUؗW(Dۘu:p!M2JE)GL>q ݄JZ+Sgy๩]?Ynzx O;nt2ALԉ ٞ Y_:z٩? btX:9r;2+NV] "](c(׀}:Sϛ8ifԓL k ) [L1 Tc(&K#/O3}1.I,)2$otn}wN!8#5ͅ ͊y V4I :f8JJ\ݒOO%aC7֙wdagfr=) n ;]~C D  0 T cL 0^}8_42ƫ}^P}oT` Wv% ,pP`w~`!G -,Q!#z*CTMrUu-xUIDS)N0Cx״#*JY/$W̕iMY0Isܸ 0| Q\ Fd&kFEr(6-,At>H^b VNc5uS|X h q Mw rU|2  -KLQ : "r @K a"8R]֣àNPÉ31|[|'b=+>bdfLu|D p` A| \sZ Ch5~@kU/AYuoPm!8arGOIOELD.E9k0W 2࿧f1p?BuMёT.FTBߓd_ߛ'f>UצGbe;70nv=ee K %wb31SH 7 G Y ;9P F =uz`]DIGsP Bag N -S}̇2,b"}'!z(e{'^~)Go0˾84>!?;w@m?'<o=ȁ>]1>,921&M(ى$#Ι$$ n j0 = WPyćt\,+( LoYYN:u8p\tJG.SQnQ _aP͋W "[00b簱BgHG Ӹ%qwx2D>|bmLoD_:_. - kSaV[KD JM?6'|]BZg53^J[>7hxx736@I5'ZcK;$_3#ݒag7=gg*y$7E1KuN4DVq5JӝNx W_LW8 ǜmvv:q XL,I o_CLp9FJQ W=H[_ T/s>0;j$;8C5S9@+^'icvK# 07Qݺ >Q]R c|Nϟaa֤-gddC{HW>޻u;;@M[3 'R yR]H$7#0%i SFdqNT*Z~(L|yɖuB4"G!ZEt{@`ms_8/e#e(\-d1k3ߘ2M02/ d/2' 3;Ma445V33w0M,ir)$7ѿ%c t׃ v_E1iB˷(Fc5/o f*Wn4C2(5lt徵{!Q݅(Yd Q?3d # )Wi^߻%5ޑiEDɊ_fxz9N>_(zg: 06&Tm⼸:2} qޓie>`ޣX8ڱFQܦܘsַd=dpR2Tyb]Z<(~UIsDm i &`% k X;e XC`\ /R< HvD55q&%D  g dHdt#MG INT;bށf"j~0qb , E ,* X BNp/ OgRN덲BJ:ue +E+A:hgfFC0 OQ#2"]J"h"nkiKK%p* ?7l `دp(b' ӟRbCFZ!KneRRN@>kg2/Sڷc( *73,LȚ*DsN ,\8OQ@8L->l̝Vn@)2 mXSb> l2׷zZD *!NA/'NqCf-gхоa}挭O>iYs}_ЗkڶԋEVQsv$J(Ȟ_(킈UPlr8v*[]%u桢?Ɇ=sҫ?"&򕤽ǰz eq ~x3^g|6~-4.%Kk{7YR4t+)ܫLdu2J}' }{ ?E #$#T_ 3_KqZ:%L4brYvpL/&P_UbYx X Iai Չ- MKq (Z)0Wm-@AhX?OcAf ztR%C$yi5jM.U\S(6Fl"=]G9Z 3;Oq3 e0C]W0h D T7Dr&B5F> E+J)i/_K+B!e7!%,T'1[~@]ľi| Ikϔ8{ƺI '15$/([2]"ܺv6~K5z5I ڲ9:zN ݜMχY,߂HO]g!TR !@䧬2MxFc3ۋ4K*6Z<@845/ K =:g _@wq_r f`:1}2;X!J!~U.68%]2Tb(Q؟Pfzm3>y7J!Ma9zdRd*:=!風+z'~了3MU MœXog)߻rgS#X9Y׭;ޝ fǎ@wԒ뚓_F볣w4{G3@.FԾI'S!Dm Q'`,#/ 21#,$8C##Q#l@d/j0 V+1m/8} \SB nzM { _&K.A)ki;:fsut=uw.N\{+UHC5EXy | c k& t E`k? b `V6gz0dz h^KtۃQ  + 3 %\Ioe\zE#wl'9dEH~z4Pu泈ܗ#1:~%MFrt$)'9 ƌ.>{/#o?9ETʠ.klTi䐆-pR{U $i$ 9G//xvЮtEd 3?Hj X뭟NO-5΍(/Vl8=gc٢WK82n.sI1iyXWTAHJk+WqySz2?UR |Ռ:LN-`(> 鿦T똇%bq2<0cHe^fH4EFky˃i^?n^@+r1ǭ48+DLc) vU壈"pE[J& ~hUc/$w|J /j V*'3P^_M4Ӝ_ } ʦ lhuQ\\X+*E ռ(gjEZh$l:=p˜Y=TSLۋ=V9zJpfLYg$-I r`*c1+ =O  m[]} vp$.?V7*LBxT {!hg!L8Uo;bإC%! Zqr?VQ)36<WEH_q{F}D#Ag@AWDICE^PA>LkBG^JMP]MdcGP>_2n(t%Ab'$F7r&_!_>q8@pX VP5<sUZ;( w(G ?LWh gI!-8R昼/4`Nۮ׻j:l+ =dLYim秕ʹޣÝO)OG辦vJ"qq[ͻ~ț}Wb(r\õ,A) FsaHZBAjѰO(gu=?R_Y5#nkOwd 媢t߳w %,6oC=7\({cӝQK3k\& 2V+ ^:?S3B?U^=mbo*<u9t2L0׊L=tc艙ٳT:W38ZZXv#uRyx¹~pzF`c83EQ[ oxfN]t!NMJ}!<9# f'\A/qJ$)/]8:h/O]Ii3̄`G>i8MhO(5 F 9ubXSW#PF ? lׇxCMD˸ޅK62C"ڄ!J."xh)W/3mܮ;A;U&6*i50v*()W.8/z,]A*\i8+)}(H$=F!W* %!: gI,Y{ =c z.(^+d!'ƫF$1Aa5Ot%cqP]dN+/k? I7>&Di ad+٠S足̪Fn/B M   AҔ QfT" 89n\| |" !ȳkq@gCv ȇ 9 ry?1KzՎIBιQڙսuπChUK$kd/lL$le1e.!_'z.xjӘRoPGW}w ⏳0h> R2qJl=Dso~VRe@G;l , UP(ISQ\WxB e0dEr\^yht5@pKA FK v5'oT8lO{-Û3O8f ]x C0 4 >GCGEyO*u ebKǤ.a0%134֩~?ROUM &+wz' +vbDPH Ɋ2(nf* 0 T#e4o\o+;:qGk8  jn K&ec) ,+(RZ aQ7 .yWAyL졝q4+!z$VA2f0l$֤io{rrj6wEImCHXyA 䝈 S 0/8@V J޶uS.π ukfC;љm;v6oMx**<r4q' :  ٸ ]%h,ɜ63JA=K@ѯ BDPFD"B8<1*0#3q;f8ڋa@4ggF7YEBs{=S2T&o u d'^A ID"An$U&Vm'0LUF )KK]{W"ۼ|i[ sy1P%pă)/%zR4kl'%EIf(~DL df:ӁٴvV4ٍsϖj_=owJ ~}WGe64F\gb!c_04 7qꐕ i}PGLuaq RG6#^]$3BbEr i1" aٌ\|j^C1$i B`ab;yZoM9StK, G^x7I՛,i}<n*3b&e !0 dd ^5{W JԸNqx'F!RT6:'^@,mYlaq$9ާϜXEx)J6d7ckMvC#IyqT3:Y#':fqE|/ 5Z(|n[P WkdD:LEHi /CFh[} uqOK^ >' i(S6jg. %0J] ʁ ć^0eq'!`$)!'D(vCq9.$-f,ԉ10/25Q/6Z+;'{e'{+11}H1..I,u,')$pV";k$Nv,X/)߅)D"(@ KLfT@;L3l*X7׭̧1$w+RUL?삶A$Ly&㥬mn8/J3[NՌ+&`O͎hS*1W4t4Zm"j7(G)Egekc/)0R(j暱'Ew8̓0FVBY;w,[_8K !s "Šc FI +b"_j4h%!#* B/ U%u"-`4Ґ485)/'ڐ$&) &L@ܜ l.?0<amE#Ym !Mqf5v[A_4HY5kG?ci@/U'#u,T[ƒԔjgw$O_ҶRW:p[ɟ'nBh ]el rMNڮ|JmA!u+I `QPy$(c*Q X2 9g Z  &7 kl ȓFWz+m\D\T9$]9?Nu0*xƳ w b I* ;UU`@r8E|X/Rh  ,`Sܜc ͣjЏ;b P7 /{:5 KRMqh#Uhbm^6Yy얂g3WY` :j&[4打RZv/½5isemqa6n6)}񙑚؜Al>c O~ (TaSay?}d6:ִ 5 _m(T,6KG %% | a2Q$ p 6l@&ϺVk2L!)$f$TCS\`995+tG  iեf#Up;/}9v=;y7ʋ55Z44C0"+ (SW)<,(zR2g7GN83B*r7"x_4!vp3BmRw#P:(U*$W' 'O<$Zx,ŎjG, b Ot*JU GNaj8FwQpWc1~})ݔh7psPVQL7pX}%xI+R:?$%6Sd,~]O "SwF5 I .G !/P;OYqGS -Tm3U+A2-vpoe_X=@̖s g0?-'r͚)W}6tCzc 6S*-N?T~vI0nX')3/#zߚ_ڨ LLjK!f~;栿cHH7 (SwEB@ ~|Ӟ\9ڵ$&ư:J SorZI h:t2vbh؜.WW)W>i.bʓ[`2aG .1 PV/ Cf0a à R a5 A \ C 0P( }  _  =5z}?g' A[KlQ(8 #L'Q),s0_YM3 o4%Y;5e43et.C7(̪"#!wZ{!!fenrir-1.5.1/config/sound/default-wav/SoundOn.wav000066400000000000000000001131201317357605400217340ustar00rootroot00000000000000RIFFHWAVEfmt (  8qfact%data KРYLM#N'yޢn n+1QmUvC ~^\=<'DPɚ! B>c o֘q.d.߇_z߃؀0Lud5cwQQٳ',ɴH5rzJQ=flbKsC6`&hlZ)@\+6KXk5f&W(K,ZmnxBKFPQ(uҨn!+eeQL`s䠷oz[#$CI강KG1 %:]jM"Yֹ\@t!N ʕ/, c$2s4Y ҄1 dJ rzY ͚Iec;xq(y K#H47! CE |  p )D1sQ(S Ddz1Qz97{3@+%cF չCưN"@F羇X峙}Y%UqСw=Ss ü/>;WhX  mA 9k ZXC nyu/hoT NdD\'`?[E(121,־)8+L->'*/#0<#M']3)Ss,B11,V"ъEN75Bi S* A\A "@1YVg Ѥ=̡K_;!}c3o!J< _hg$ipo+p[ȝ'-Ϟe[<3) ?R TOUY t,"bHs}t_n ki[^B,9W<욢 mڀn͂ rK>̵L.JU ](J_IToX+8 ZM \5j̵t䤖oR겑e,|DO~[% sNcR z Bs TL_J=jy >G(h@@~" HJ |K |"E#b8# W_zudyU!9.Ma$G+Jl^%K Gٝ$י?Ukm xr p-CK va`RD d`FC3cTPn/mR7n7L=Q+C1-D>K|%߃ꄉt5DC6ku곦:.l:r1kva $5es-C<#Z;S7P x VxZ\y>2  gK> 5t *mS1.K/Ő!S?} ͐f QM_ ~ (% (S{haN &oTKP5kTћ|4~ wQ C5KZyK09,7o:7lO>g踊:;>/_҈f[g:$7kOdE fG cP TUct Ɔ7O]Es PUQ(wrRaP ɕv q6{DY>O(jK0T0`,bYS*+i'-h)#D$ȴ')B -+0%T0 +3!e d`lX[ O: ,EJL Aj5EcրI1ے>ƅuޘCeJZp21F[߹ⶂtLEDU_1.xc%+q:  ^|=>L6HoP xH+!<52r~$%EK>hc=WD ӆBd۷+(`az}W4L` V'G=T m n$ nBF<~u-JYo{ ar?Nij{~MĪMc6B(JpלtՑ-10(Jv>0ۣ4cؗ)ῐYԗ ++y;#!! l/) :JAD\pg){O)j|Qcn=CZ/[T^zi`į2ꔽ7bڻn g":H8Bl-*Tg4le8$F L#(T(@.lUf_NBwfq4|4^6'jl_sNt."^z0TB4hRޟ%k80,rUN fA- R,AgD/dqP* |RY % q`$Q z͵ ҆1Î 6m;*W?LpX'] S {  DD T ^)P#)4m 9!fVJDv96>*  o64|L$?gL>?/'0OP!!Ub)6}ҲHҟF Jy6;oX 2r%qV׆/< ji~*GR8@%yj'XVrK %|2q\=zyrGP 0ہr(e /f/X,g\*sf,/v,(8W$&$~'x)/;-e0/P*(!C4]/Z3<f]  } .:k z{|kS(dL$ Y'17ǺEC 9jzygsjѨ曝XLj sfzώdN2SeH<{V@2`O ۳+JEF>uBd~V lqg  v|O`MAI<Ü<kJpT e TB,l`ITV [[ꃢCnh0_4:W\M8*]) !'HNb 8{Y3ٍIJb ҝꉸCBzZFmR#+RJ @&8#?l {*= bf曃"U= r[% A'=#8+.'.@; >Q%o֮qDW7 6QMR{ALP$H  \?'d e U>Kds P %Zۢ p$;D}22?=L-j.{_.rGf5o( `" ' <+: n9 $  xe^޹mLd D}ZU;(mh0Ypf H/W 3"r1zFќ $KV;MDMxܕf%܀G- k+.T. ,A4i;p AnX%R(W!7mM J"77|DW d ydF"/ Z|کBQ(苰. .1,* E++t6(\$ $%.'- *3D-/&.(o w#1,Uw֔ƖV [A鼙,Gz@͠ݕ ߈Ku<cڌHKN4yA ״g+{Ja^oD͞SvOشl{eAJL2:ZFQ^u{ ZT$/͸L_꒔6uY~^ itE}Cz h G$!<ɢX3V>KA+PAۡ؞}ݬ)W_aa'- ivly^6 1Xsp6+Kn>n\Ҽ r c\J ;=FT}3m:)e\QJ=v:dJ`}7Z^I2``654IF4%@1[pHFRO\mvԅYSxj3PPdLiPԷjP"hO~QO.)/CҾY`= .Pi6.@Hv|ĞJ,n}aó1aw&p\c)&Onw Hm)GڟQ+ENzH"z,}za Sx`90HzJ¨x[bW F^?9 0ū )X$#FQ(v)1[)(1*+Qx*'%˙&.'ڤ)R,G-,#(!({\[xހ&[W Z6Je4~hP[ҬM儃 P}}5(bwD0i_$oBqvSY>蚤= )\|;Ί0qth0 +[}8e֓ЗDRzl^i!3nr3&C=)^迏;o:sj '9ZEP^Ηƒ{zo^˿8 H k? mwFꎱ6iE S\CfcMJ 4Jm>2ߤ[1V~|1 af[>rܒ5N'h=m4oX7H" Io7-\R?*WP]<'m6#X:{T +P#l~_.Dc ߀@&2 kDFp; *&/kaiX w:e"~XpPDv-:K";8 ^Yu3xdUdq|D ;wԿQ?qtN &TM-pa!.#W l(x# &D pw (I i173oa,v$ Dž C Z |n l1ճiyrZDž.VUL6ʎhisƢ1 E &% fvo7E.vMOgw | VԔ ]p$D,] VLeqէcWz8%"PH"@6fcnnAPn؈`>XeJgu^0 ~z4YS_]G  " |D Vl}mn_~4U>%s+ z _-VLK0j3t t Ϡ">'Y)^)&*N*_)@v'%4&ȡ'ʬ),E-Jl+w?'Wr\!ͫ#7_9j n"H׿3֜ WZuΔ2KGfP~⫒B6TkFz&Wa.D7"ǵp4mn359:ޏz4𸾾6p=]jQ,7T~UŋxcVrHt#TlwCDWVߐj$ ,bu"Y.EuOmO;hR # Ƅuq7f-9@UOBa3G J ;W<6DtDz,+58q}w:;$j3t, ?wa%s_4<.۬Nڊntݺl ]KKmBݣ]#uJ/3`Q)ML"'şT yЍ!Znv񞴸W0X𜦮汐>v=D ߧ,(1/52g&/}|qZ4Yғ^2UAK.yZ&ISnn?'&ovw*mCyoZtAtC$-g~Eu HG h퓨Lb!y4#fb>|Cg[q/{ ӳR /  ^ fp]휱II[ / w P (b z.;-ZjȘi߫cӷ o+T2Y$ Sox `{ g[P $ *"Y(3T򉹫*/b`OӥCxZᎾчہcrՒٌ9WPLCFo- fGj퉍o|G_ ō6T9zKU8[-k dPrc _zHHm?~煭zXț j3&[ ՠkW ic0h,!cQ.ϴc%j&|H' w'=)DY6K*8,L 6* (?BJDcu/y06$2fUO}&7 e*wN^)6V:#ܛfߚOdw5Lc8@JFZ@Gewȓ5O(2^$Vj8t jJz{K#e'"=LBw]I桾9t&,Z5a[s Qh\^m۠Kn -$)I5c6M ",P);~-ԛ$%2 +{0:(-O'![Z:sFM7TlN 9,cCu ,ؖ".#'X")I']o(f lN =oH fgl+JzcW Ku:)i,/*4th.o%t aΓ(yv 7G/ x0 ^ 3ҝͿܩuL ٹ怴6-a秊.Ƨ,6J)/8q**tҤ0+`3=k}RlWե Β%4c(wP7=,wZl }88H]qZfČz)%\.OlQ 4nP ^ /[zh&psfn **OܶqWaUd(|f J G{x1c:2( [pY tlU)Lh e $ tE>s7&YP-W&~CvUO8 "k)`AAݐ[~]AM(Pcw!׉:7y۳70E6Z:tjtC+a+T=˅!-.s =N2N ᭌe@bCdvT0! <B\Q4 nR.;޼<-JF̏#FX\_v',6M5[X14"IJ6o**<<8g=< A;̏9l9CT<98Lp30v&V 8!ՆI\ 1 h][ E}n,W,(b9R?\V#-B;1zt nmEXl@I2[!>X=Wȡ;(+FݼR6ۺݘSཱKtKó>nH I呠 m~򌭖cé [dr%OooW ]{4 W9CE-% ?zr-p*UqF #btl_Aډdc >ZЫ Sn%ͷF)hA#vF$&00p&t-I,E0.(&2D8<r?6FA20 ,_I-kH Sun!d T!mNE .s( KlPKdrW*\T֧RhuM @? hЧdqS8){5)ONoQ0N_$Y.md>xbË4l~VYԿ؋ݼgN[f([qR:19 j#I12\k(0]a+ɷM&Dm&0F*3(A)gi%=x~8:X,5ۅc+L閻Y:'%tiL+j $ !$v e 6u60 |~b?oh wjzK!Kt^U #Dx!x'o)\P*O!8.bhR L%08s>YܡBG֋CrAu_ˠfFsѼwXXb~UE¢Ul1ӫ[3%>J1%*@깙Hv)dܧQo)gٚ8xdϭ8c׸/?2fD@&RE~1B2#Eiذ-zx'ڢ pCW@p~_|'?IڛvY9<^%n& y) ==.*N`K""\J|&W a@XUߌb 8 4Mxx[x#}FcP*?琉oA[. 7R G S /G B"nw ?5Vi; z.u0^ y.> SMٵKdAl(wL|.u )sXjУ)B0܉~nRs f ֺ M0oN8Z7w!bڭ:[{f  ["@i!]vv/F6-3p*i3an,s&Sm%!E@H _ ڜT ^ :<=^?:'S1!>iOILRMKojOeP7O K4M"R@Q[aQ"RaOHUB,“7b0b: 2P/*Lw&k" Z:oc}](.H Lݕ #F㧧cl썯$3ȍfh6b͆I<TD٠ e_/~\գ(שv Ll=_вޯhӴe$Wqw2s4'm" j_7D8Gz)>N^t5fN8xF 쬍?i.+3!6$ L Ԟ r<\Ym5/Zu%yG_td2"Ѥ<orߞVH 1ka#% aQKH@a!쎬@Ll:gO/YMbJt!@CeZ$&Q'\T5=0캥,Q1k{>Y$5 5^g%W{Ԡy@ ց *:a4 "<4+E\Mx<xwRsu^ܼ 8W[2&&,+o.j.WL3s8:GO8I7j96<6E9(Ho:T7p4mW+[#3"/hn 7푀 ,v B O rcª5 :vua3uQ- 7 6)^1sU$]18Qhs $mVyiyAzؿ/s"fK"z9m}"fOPM싔huQOю5YTCA-g4QmTq%?Tf`K &^Bza Dp>-2w:Bp&>%SUZ t'K C> J,"t! $A&Y~n"ze%$)_/+%'.7ƈ;?kp.NWl7_9apC rCql5--Uk\`,M7[㛔ԀOzNB<`\QO3=$%jz ZdQ-(s1 90'ؼ%c\,<0 Aw3N阩EKm(< GtIpKgW g=8yu b h 0Йd i#' H& YDN !]]m1t4#ǣ)&]#&/."YG{5A1G1^V=2ġ\eZ?_#Iuڪ؆ئ`#-5DxJƌ)!yDPkuCkDx>{2ήht$.o.uT{50'4-P+dܵچnثҬY7.gٵfmrE)JgI^p_1^G:r47-d-yZS]זp؜8akB^.1澿Ի ܈X؛gbؖß_ݘf.ቧ⺁:a 5{5b:U$̎6zIߑkKMq6},[V&3et* `#7kHI}74g'U`b/X()i -ᨔ޴l|g#Zm{}$FAom홨3_uT'\)59}7z0+(üxA!g aED@tϽ<>lRY7. wGwFN4#w?xac}7i8yk(QrqG5;G, exP[F^wTw o~ud $:U`z 4n.9ܫ۶]؈iYxط-`~/캈#UP5hX?<[1$_0,*[S4 g핫 A?FI)ҍ,V5:.N< iODu`B!nD\!yk! ?"%+*+Ns+™/66ۨ8!I4xv,)vQ(w!U{2l!G/=Amm` $ gg)连]ڷyNw]2= y!đȦ qUa#~_z0# %nR' 8(lr&Pv$D"EBqf 3T7myְ+O+ݕR~Ԉ)fz < @] V , !  @ r kIQW/j8 a {i/M!,S\c*zCo<Z3iuYM?oP@ߧ8Q]"S<\FfbͽEH)!1|sD>ǣ̃V2ɫTOe={sTx䱥BWNCS(pc[ڱݯM:E׷MO$\:sA[c"5@7߿ϩ!~7목5jvsp"e@lHؔCBStbRވ+b5?6"h&1/x&W!H@ ݋2k f8ciA.eìkiZ,GK^NBeoیal "; ZWx;c&/moMpyOn% & Hp ϑe _ Ws[xuop6oc~~HDl 6mD,UGyq~:{STL묿Qj¬nV]j.ڂcN G.C3;b{" WЪd;"#1S(Nj*q)r(*%h="iYZo2qh`Ů s| x J4t n'/S9w9 pAoD6^DE(IL9KMJo%KMkKAYJ\ mJWID)T=5RQ22uN.m8'L =x|*a+ 416,-'O:hJOL#R hJ.W~ЖCǯ${/IBȇ&a~@C{ŧԸ*ӻzO.Q9jǪK4Η4࣓"e6_GE`aH܀+:ʍ%[aS T1hqZ?X.٫n{Gr6{iQE~^엪Y]/Y4RBKŒb!Vj-`$bd^h3T1j%4Y >;,\zEЋnC;ov|}S*)jz!n2&IB[4Ǧ} QÛgMJnE $Yţi KfI{z]׽g*vun8;ld"@`SepF_Bʞz˔iНzل|i?T3XUFEǁ  bDv.U ,&/+kh5#~ n&?t YRc.Q4% _EIEiqO :%;FB}?ZWN+<coTL)(DVCU-$=0ha" 66Ͻ+dy\[!RN rM,~X5Sp +ЀHI~E.P0($Rz! w~;pGi,2FhYPN~su.r*껇 n;d e+: Yt"qx?"d3M)3 Q0q "-[ #w( EN[S~S4g .i NXH=Jl1}jb?a4!g7c4 P.vH8B}:O-^*3P7 I84<.-%B"1#g10H};<< 51xe#0wRJZ046Q"}1OWFwdW[ۋ[]ׯ DoЋv~Y:)F{#([|HC1'?B=Cܚ vӭ-VFԙڎC:*87MfĢؘȌRÐI֫ɿ -=Gq'(QSsVֹ&E me:fܭiI|TrV=ξ}. 51 L GyWHZ'CAyb%9cyJD{f-$r!>KJ6ehōvw F?ɍBfx nHV{R\+m3 5 ]N9 CXF%~,\V^o~ /*©ŒB+H`ee~CE ۩Dϲ*4˼,_ Khm}璣x] [d gCUzn1"?0,;8 4%J iu+d ,PbJg}QAN/F\Ap蠻n~\z4% %)`q5 Hn/ *% Ơ&&#!,OS*T "i&jFbB[)PdE+HQt>ZXW ~1-C ņT"f:{h<\6h|b%௔ܹjp0(a)TLⵘۢ &w}V4#3-뉦@w j lϡ@|ǻ 㬴 F "?Q w`+"$8a$ ( DE H) ]p g 0;a *1= d =ottI;!'}V'oI'|m 'gd%!"9x3'V(Z+s+3(2!N!{X!2Ua&e 2*w'y"^%'|*/Y2e]eA!1 bkPgPϤ^l:]d{ h 98 NJ;R?Q@s)d5#;xm/亓j ܈$MN0&yܲ@ْ$xEbi;/3rR )3 Oڸd</||Wi/K EAM 8mX C )ER4p 1g'?{jx5 3N]P9_h*$`B4p-Nԝ< +,*6:T$x/.'A,<(o3+@ڙ6"_& -q*/#riEKT"ɬ!VKOHe~VtE,Ibmox[;\_ ]=|58!CJaؽGRBY/ٹؔMBdÇтl"-BiwŢݰޕ`{'QdrqG1爜'\~Re\)F > ' &a#z :.+{+#.^1 eD;?%Wp~fB՗Fe=nSUp!2x<X?$_&F Li?׈ja^J oM 97 $UH #+ - ʵ }g,0 x573KXVذb xX5,qS-#S8]-DV•J劉' KU1a!JJ 5.46 FfTa)@kbFR8GPBf$:Zs=[# Ui; buҞiO R9"}!|9+P^vm &xX@TS+(l.!C--*Gk+tB"(D(&o"zdm )ǀ{0N0&:7SU SK,^79*60)I.,r>sC)EIߚK E1AP@/tw; 2H]14`J3W:.F.Jc>12V8\ 6#75u-- L0\5842X%%ޅR? ᔥNb̭cB'Q ‚u0*/*ܠP(ޘIiR14\w: jyӿ4lʳ{WwĿk1cp ġ1S J<Ϊ GSų&llFԽ;Ø& f^ fи:"'z5x NE3@ww~=iz['DE\#݂sޒۆc)Wӈl==';G֚ޤInK,w^ 7d H6`c[, ӁL L }dfjG/HYj}8n\PZ Ye[Ձh>Оyz5o"I:L><+=z`J}^#Guwo # KM$V &<(ZrJ "S+)St7#y{C 4` k[Lw4bQ.&}?يUA{2$5Kd] S "e"[S!`Z FH' D 6'tX yܦ!xM`XSp&}gj5G7^3/d?AJ]qa2<moK uH(F {Ʊ TS/!dVS :V .%72v+K}j+x /QcyP F iZ H4$ h"$ t&Gt Dk' `%(Y"ؖ /"1$Ff#*8<+&g#M"П/A<c԰<M(ƃ&"%p=" !&&].%"e|S _D*Aq_X7'8# cfpCjӟUMg : zr|#+!OCܨ߄2pEN{C>[ߦ/3 LI-DY3['޵tݣx*/{S;2[Х.?03 { [#[663c K7w]=ѴE̺yg5K &$"mzϪ/ې}}#&DO"Jm-{bAH&˼.+3&#V}\I *b>ݙ5Ov\6)^ v ΒpY |i}kh K6q{4n,a bCE#쩝=&@΢̭J0U*M=3$4C=Ӆ a.P0RUrʃK`6,:V)|@FB!/#T!Lu`1=c  ׬PjQ ,,7g:`iy 0x:@ : LҦ2 5D| l_̨Y1{XBkA?~0x% )nD(M*S+,(k#V}vW$w o)Ъ11fB(tH4LHw1+*4(7[/Q-)?,#]5 <~AILAuFz>ў&9g3n/5-W>2\M8uw>HeDH&?95i3#n5:6Y63S@2 10s,1=&13JV/%+W  G ̲hS:yL p,yQW7gc}+Z)Hҵ/fÈ9z8FP[ŝ7Fpʳ;mUkؠMߴPo}&܍4ڏܨ̚xB<۫Hٍ\#Ԅu}Dfb`4h(LBiv(HL:z`lou6i0v6W݆*3pEԕD,׽ڭ%rWTmI/r_>30rVEq?h*Zi. RbBԤ;wPgATR":iB} I-J"U_LmqE %k  $:>QJUDUF " J Ϳi "7K_0qbAS98gP[^lH* Oxբ\ԗLM&yK܇< Pu +stg2M>Ԣk\EV杁E + FA$)$ ;byTkx}DAPu*92( P>++ O7 0Q]dgw ūA$/!+#4! A |ANe: =,% 1zEx UrdL3C Vx 8 0DKfJj LJ<ļn+qYr;ɀ~t[㭈\d*fDxXc>굖C[]`y\bz:[FڟE|(6kQ+qs?݅IvgF'z^V }{_3e %]l1^Cc̪h` ~ ruV Z$!*">^F9#e*B*&m ]z Cv= # *4'TZ!"&3!/ O[`w7 fi 0Gk6/a4!չ%i;{ ~yM!Iqh*cK#**3D)s{r %jZ!XM$" n 'wF{"& ` @:dF!R P,6" :I,Srb wI]g Z!/*pt05x% )R!p{#At,sa*!/-q?BF9 2;"Edbú<rr 1:iY545.g31,15f2z /8-35 //1+O3}k3+?U4>*z'M*Dh!'ʏ-24!VrK Gh#(}tyGy]^mG^̻lGVc}mL̬k*2lߔKDF٢2m]0pb~(L’[Q4i`P,:QsgeDE7qkN#B4DTϖ+X)yztVx1cQZ$|%a*9ݨL3/L妺*w̽gp|qp-3UEߢIӕb}Y6A:'(Dj.>;倔ܯx/ 6#F1 X! #'f˝<{"㘲Y*oiCwAMtzQ.GR~G.FzTd C{1'gGu() 00W bp `5TC#~3/b!>"㘄t^PA 0F <+d_"@R*!ltLh obŒI%3ي1ow<#1۶#uP 1yh,NQ1dlP ($eRҸ?]\ ǎ)uQzv7HqB-; S+b QTTNHe}/Sk=p NNW5qpH5 0饔a1Xr .0a)B-j6sEar=قY}a/8Ji64dޭ]-ɷK + g+pB7)4RchY N}q؋E˹[ ݽOZF*l̺ ^% avhvd>"s|(#L5C@9 G7=Y$t!~eBCLtCY`' -ˊ.( =M: *2|5`7>~8t5tF*/h.4-g^yd'-,V|.x4A, %-.߃c?mc 4ըM bHDz6ۊDR#L >`gOa+[)(Dzِ9|h.s!d\G\ ݚ!؅- k/B=%+GY&]91>Htǁ lD-;͈hԚ:ء^Zdzg!i#TXDd,SQZU=#Vcfhƍ:] uB. !HsKRm(Å enyӞ,# 556h ѹY2yKAB %l'%u(ɹ)%i[$YS?]61V4}H+,F٫=7).c XM6 !"%϶J*:uN2$\RТL ԙEQ(o-Q-Nq>$4;[q/f(-eَ-AZŌ=g)!ÆZ܋ʗݳ1{J2z O…g7 SF NV[kp3Pmvp; jX8#Svfw{Tt s% +`. tA Z=O(tKʴp$``S?H X6e(K 3kFV~jcdM0MN7UӼRt3}1 g8\.˲#W T66!\A"g2q1RC%\-i5z.љr K =c8=wt&H-5++%.*;3,}4( oz{Ń5,T 5J6j@=HMD7X;4ɽ0`-+'\1 =V;C8J@B3l# k] D/;>) *YX&#xPuB]b/M "h_ݎO@(7Lemѩ at&~D)0=n|:Z (I!24tw)FRkOOGA{:uu*`%w׍DǎI3<*W4`~qΉb')ƙ.3^Gڍ)ތ OVvO9V3AczE*Igz\JSEdw\i+oV0gTKn LKkV4WV /,NNH |^$,M0 ǡ "$ALH-+G vuSR& >B F  N/xVYQsصo_)ͥG9l8u? & \ { A9H^+4# S:rϮ-K(:&,"iS  Ю~ dg%XzOJ*/1e Wnu;.JruURsG-޼Q<]V%\`f*O ? |>%>+zgG]!nO{rigcn`-Rn}O\ > Q eJ!:Z"I F }4F f2Lꆤ]s׉jG'}TD-9.NVa9{ތO䁫W(N"້ {f )rn 4 owzCEuF@ ! G;  : B%am ͸*4$9PVNt؍W#o pB-  8ub"C)w)2c;}8>"9."%ig (#,$Q4Q5C/ )ܥ6B@Asn5yV!=2&(Z"}^D {x{6nJ2 1Hٛ{vmwRu]zllRŎ4H}qAٛePywoMW{$8QJM׀*оWB?cNc} h-c&a7)Bf'Obs @z q:` Tuo/f&" j: 1c[ _ \Tu + kfM`?+7g$1 Lj ?o"q\R %w% )B UaG *St׮X299֫yAtIrK3Ct3$k& >?c)v"2'('bI+L3+2YS%i$*β?z3r<;|҆9ZZfW*٭` {ݫo~Mò0TjZ9OӊOۅ΢% ƒ7Wwh6ϵB%meP \Rb\2#/2ҋp+{-)91r~0bVs#( Cfc۵C0VkJe ,_Jݮ␼792债LcHNܲᙫy\B r& aR>l t0Gfk}e %mGE6qTa@g꯱c+_V|= LZ F< _ _* _C _|q~ќ4"k#4x$/ cSۺ*R#xPt `B0, ӹZԀp> T+-,L袚n)ԯ菸$Ow Mb {|{ ] RUs?uvI d7]j_O~ Wi , (\Ωp7&iL.m<0(R 2' | [RVK9 ڰG#!k*īh+Q&7)e,/3T8?6D,'_%'%J,K0;6CF2s-gӉ _ K &= T`z,V ]"&TT>uIdws0 ;?n s-knՎU5 Տ e C*˪,/=.L%s-+'3]J -'V YC},|4/M. (uzX= A ~:>.aLL,!Z+ F }cIڲiڰ-mE 1 h6 6&6xڲqﲊ= ٛ(V_!dckt3>YF@[wvIZn&]mv]T KxU>X f|mHPErȹbԈժ?^/t|OMLSspB(W PIJbum p"DlSU' e@ {x( h_R;y 2'p0|N.Ga^/O=]= >%dym M4 nF-97=7!t 9LV7ݫ4^-'2K]. +:=%ZBN0@&3xT2y"(̶ 8b7 X 4Sԍ-f& AwV-(.K: k$ң]zqRov8S US7]:aPpy)sƎ6̥(Xܝ@4S [q.XcCJhFNr_eD讉3@Y(@ [൮,UݛX44 SS޹4hp+⬰䬦L, ;측!)ɦzo{m}G -4 lVGWJL;lc̣G4-3$ưrBm[^ct* ^Ij> ӦuT (#.Myvi ZLv_7?a . m0 #  ڨm^i={! ICF<? *oEwbJQs@ȁ䑨N4"2O {q2M}$PfFyK7hI[q76.o:jf `ugbWa4gWb H%WBX)ƾOϱ\)?] 3Լ,NHGL}F?`s'2T;K:?x?ik<[4(. +r'7 %^(}2Z+u<#D+KPSZd)X[Lp?pl7w4M2,,174uP6p?/ o%\ ? qP$T 2f{Ep 鈖s>;h\:Fe[]ιThJߡJc>pm=00/Rg,Lӝpbnj*Γ6Љ֊ %`hևb3bݮЦ\Qݍ4]U *I?-݊ߥ1n7Ԋ)?sk0ȎrpכqCvգhDx6[?Tdu LߧXTKΈ覞-QNs$|87~jy߳Bݯ:Nס2z(T:Pn2yX4<Q.GYoV8Q @ aN:A#o*9{pm&  6 ^Qr 1G1=IeƐ|z|\$r+ G7 w_$It\us od= #7c; `!0,Xb.Z*f$T$דr:Xe` d"kGZa0 iյ#xWkNfe<yG4h9uI]Rޯ{\J7Iq т7/f@ B+ UV +WXeWe |z[Œ~ZW0at fenrir-1.5.1/config/sound/default-wav/SpeechOff.wav000066400000000000000000002735201317357605400222240ustar00rootroot00000000000000RIFFHwWAVEfmt (  8qfact]dataw#cMh.5 9& +QF.$ms㰲]{pFL)JMS߄ZܧnڜmD豎>ߦb/O7^ʖÙz2Cھ_ͭI_Z wǺzwĚ>~ *|M9bQ\rL# ێ_޶" v5 MS7b#M./Ig+2 H޳g9:)>AGWag_^ O 1\J<QcdŽ7J. &G ]53c .^3mF& ? 0i P!ut#V&LGz;s>^K;D~+V1z$}3 g ;:U%`  ˩W".*=!]CӘ`B-P% )x]o‡/EX6 h?0$N03m1T7?6jJ#U1m#⛧~ 3u q*5_,}~ܞuBg *qaRdy-εppǦxN͵UУOrxW!-2*,x a:T:2o`36i1c:"Ж@ܷ3ݭ)  Y j7M:YTHʹ "| < $*+ }tF؅ _e2S 67#Fc kUpg } o))5f6Z`I1sߩfh3kr_\6ްf85_α;C+ 'eٖ-8Fxmc$<S(+~D-ZI#!&_!=5WmsٞNGH4X1F &2 p$d-6)4}k+9:,*im2c cY eb̦{hݹ[_* bLoFUY ʥQLo{&}Q?F,D: eClmZF@YoU>$@!k1<'ѷKb[I*`#7(/c|$wq3`hhܥ> "D#B3B`tIfJPH H,0Dc+G0*gx2\1) Idrx߼z#A .Z/T ? .ZdcMAHWrhQI,H썠.h-w/x)u~bɸ:v= [$Z/-x*&mCG(b/@2.G 6_@gb' .(1|81Z$¹Ή_u_W&O S7  `ZaƧ;dCa*@곛sN%踊CgW2j6bGG#Re x{ ME\sjta&E>9/5Fmb_D%`s"W,vN,-)vɑ\=7 k+v<.B!|oAb@taW䒏 3«l? ߐ MⱬWdw *> s?NDmfw{h{(=B/OG+Gem b M'o <@u$7p@PDT탄FD)iژWNv,!X}}`dp3IF),F&DsV*ubsN N~+8Z:1f?V{c.I,Y ǶI(!,,q470^-xENo~C nKA4$ad 9 j TdݤXH|h(,RU}ejZdLz_G6IU⎻ڸ ;f1wP+J'dD,bALP!'-K.&kw=5+{c˱,A &;K_opUeD4طw i}7k IjMj (Ai/_#.Y,: t%B<cS |FÜVQ̱CdU_Oi񕦫eAxu5)!0 VyvtDˑ $_, (տL 4y_c Kd 9yk2e-緲f嘮o@*P?27}640"F "]6  Dt%5 kd8zlպ57>E)UScZ:䲗枹2t ^v#'ṡ0GqNqLYS}n63/3Cr Y c ? N}y9*/:`m#]=xl+J,L#¦~G@l -Xmqe3μ ]Zl9ARV z+Ha8=D!mQ+i. ks,-(P-O*}@.2q%BTcZn&ds0%4/12~&b$¸ \B$gDs7 Ǥ yosC9ۿ:&O->9"ᰢ.֮̔ guweքQ+>^ݮhJ~(@\Z Ots,ꎓ5`Ptmu]Edݹ-T|EbZ %72M5SJeiD rs2yC6v'h阜z¸cQs߫ W QI % 8 !aVr: nN6`Fv+ $ɯ-<)0m3((Vx</ }o6_ x?Oinw9 9"M3$ <72 I}c?kz"9Ch,18%Tku L}>b Չ~z KS^yDm?b A>m9*p2U4v/ ͎!1L[ iC ~`  "{5HS"GᔞՍ 83*쩲w:S詸 ̧rϟ8Ҿ.P{![ [gіlT@q7vAI%Ti3/Gu֙")謳'VݭFoN@疭8}ɻߛP`v]  tن)yL%!L;Vxo@5~Ĕ:K~l8Kz OF pē ;- %u%߼ O'T1?0 ;c?(!,,N&n$2hQry +p +pn59 WW_sk[L=MK^O&jVyP)U2%O q I[3PFÚ& ++&!X OQ@5~fWv?:ׁC=Ij©{_ (`Ԙ# o-~372*okbG'z [+ dǛ sř/׋ֆU➇&xWʻ{ VI4vk,xj/bѦ[a؄Ϭt%FlSr)n1_T$'G+%&4bz`8۰p7K˒&ko7Z6LzBtpnZws0NP g,Lv61TL걯Q;wAFPc8 r V LlI^ eN\P&v1c Ƈw*ډ*>"(joF6ܰ v?^Lݔ$vx_@WYTZv]f_xx󰂌Yf 2/a?~/"b6res )FB)nz7(E4DE|&!{ ?ftQenOd 1i>ne'/v3E/&%W/5 G^8V.u^ Ŀe`KwsY@wXtDgΑ΍3@jh\Qi?0떒r\z9jU/A8=픎j?]0`l5jo#.m掚T-CGcfQngv vi4jc眛k\T"1>ǥBC^k{`zOW\ S ({ Zp6N_ Eѧ 7=}RA"-^'Q$ mOhcTlh K:h\Wƍ(=݃h1 M tCA5֊7 Fyjj2\׏wC#9ؕجGEx  [`ԇ8 50`M@5*B "ۑH%/y+7;-\j)!L32 HvP d #IP>뷴MP[^&N teka5?+ilxըv%+y~H" 3+^^ƮgGi6y񾥋A fd4W@Ě2!.ꯨO SUMX 0 j B : 6I OiE el6sa"&7%cZ Lf3d% /9SYQ&"bBW@,yS }7"~ B eI H K| OQ#]rT ~c$#!sy&3Q"#n! yi 7][(> bbx pDz?*>}$KzsZ= 8nl3fi8 Jfp@ć!:!BU}̤ e?(_{L~O -u<1 8wDn{M%aHa+,?(1_ n/?S> o JNEQQ?/魀}ԏohj2=搹 ]]|"i0iy^Yf:ۚj#mGG a .`bO2=1;$ x_CЉ@΀憘'_ymFWtr]p efwP1e_OŽB4k]nAi# P yvvw "FkǦ)lp L [4xHKs՟*<>/ /Ucz} }}2L)FGMmH('MT1CR"}1{uUiM2k4Kz=?.|BJ!G  \q0A&rf+.2tޯ5H/Xw'R*32$s: "  azH;i6gfME39rֽ12m6Ni:dY{+`lԔҫ{bH+}M Pc5MB14 l( L bno3R\U Z:T .sӏ5b,8?/˩Vح%s{i@L Q9o&y d?M%<ͣjd7ԛ(J b $)n#'5Wip!,ԕsLxFv_׸g^&(5,A>)={CB9V#e]E!a x! &2%Dž ,E'␮^c[_z룋r۲5.7y B LgJ3|"t |ܝS7˹%v#)$ͨg%q ^LEWGQ9#?DU S)UR/:x;=OQf$:C%Đ {$峈!C3)#R,x"j"q5%~"K ADd#o(A#KrH\:WD$IWBj7[/+ xV-~V󺓦lU 1&\BBm<K&<>BqpjFDqFaEII;]V^C߶r%3y[N@̄"jk@ܽY#vt V}й)/Ұ;q?Lc͞,JuWM㸍d񧚢ڽݫr]ZSyX^3-Mɕ$vdn2"KrhT `@~ F  w9%&BKym`/^(DY6q Sc}zmh_`ǽ!NSnR! W g/L oU/%C&CT644&oB 'p!E_G9|cd{#(5&˚m Мpt#0J_}5!\aSmU& $'vu@zEkGz'97&!&O'8fR&8@Q|C{Z5T TlI SpxlwZEVłtʧ6䆙}?X>v OMZF ^ H _` >6-qC% } *H# 'He$z.= ?*IgZCnew4>t gtU M" |Aq͹Y( T u x | <+!]]B`y <) -הnOa h,RP m!j_Әu[p%ğG4e~fGE7oS NLPߵxrCS/ه ݿ7Tggwjt dD (W1U@x?`uWXNMB Jae|!?3'3J}|v p  Ja/ W147Q"[ O?RPS|ꥻ;ĉe5C ٵkF-<ܱd($ގqJ"k^o9E'\ 1dFq@)Bl$pI_^RT\S<⻌#UIBZ _ ?^zP9,j[~2'蜨qs$ϠTBNV늀A ߑzM/?@] arc8g1yٶ 0ގs2o$":ðBز3 O`Cd֨p4ax? mAwO⤜ D *vyx|S> ^.4-X N `S|=rFdȃ%|w)3Dz![$ ^%K$q?zqO%֑r;mR8&r-3o9'3HEϟDIؿ6aG2/DL%ޅe78 S . `ngM̓OxPD2T4l U b> ;7~g :ujI0eۉ鲳]t`U&F6Aw95"@σ$Q֐IJLe0ڴԈbƐeBvVm<ܼ*.vƫߋ/mK,V~B*/D0R@}`|3:ΕߠH6Nӈ-ڠT{>axϔșfBoٜ**rA(r1q^T}7V*? &_ ~>iLN:Zm{k Vj mi6E[*G߁S.@kMa(e,x˙,޲%T!aa"&#fY $ /$#Hu` $**g&.g1 5 c՞}w$W- ,ː(s5 N>]hC6c/c!fF  3&eJ#$2zeCӨmQ"(렛:Uԅ\ȫPs)mQbFs:UKά$}}$P d ( 1ZqXN :ga vz\ BMH B) A' r7 s=-> x@ \9SH1)2Gj:2 #v^x?|s~= |*0a o 2e> 4Ø205fw?@q¿K` (Wl1z^mU n#O %tHkCo:c܅a?"} 8l#N I%*։!&ZLyei/P@{aݐi62sLs.{`Zg)q ]{D5u~A3D+ns{3}+W'w''S0>B61V5O72gz4(:ch3t4z2`)QW ۙбaÉW=*l?$|gs)j,c/w<7N^ 6L/sT'_ΐ#x)""0=ILqs 0r >MTv\!c(fTs`n^ǥ9C3֨MK+`p W홃ҽH ? x=AgYTݫ ֛6CzceI $p<%jA `ʾOτZs\۾h"}f d^ Z~CSm"`ߡ{(ՊbױZR&Eþvs]RA97:b'b5A=)ԗ4ƻ2 K̤ v 7w8!dW h `12 ws ȦaKҶ&R[& >i (%)h,ܑ$ +@R%ޛ-- +Yx#*j0r /1 _}l~$IYg04 KU(o !u (^xc?uC"{gl7Ij[鈧(}gnj9J qOF 5m"s" ۣϥF(0u9E YOKqA$^I6τىEZ BҰx[65 "D VFT:pD R`jG+v+  ><ji bg?*3@^(\ ̇ V,(h,+ܣV NvQ u.R  8'|)ڛp"ll ֒_e6 ,Q E YaI͡-uX;y/&014JF/1%/"\^r $ˬ7aLtE.'.T_ݠdف%c.:[nrnd0t_i c G i!$ q5>`Cg I"(q  D 0$W~ w83K e)ϢieX| ؑ 4/ v7-KA  B 9*!oVB GL,  _ PP`sBiO*W ߢG)hV|w?8_맩 Q:=9Pꪸ˸K"z &7{}[29p,)­)ΛqbQ#$` و\M 3 9 >v R@}Mg|Ž~Vn>j$&cW u}HC[l NH 1 z &P #q ɴ x n>f##yI3 Q (/ )XDvkh] Ҕ\{R_oU*G9;g5e3쵒uQNa|f(i˹l о_Lꡛ, _uLWgzEl,F!sZW7X4fƻ}a=?Ҋ) ۙ;c>r'M+/.,At&o&Kz.:23n/-3w 424D"5 0_+ς Hy {B QSaRcsu;$-"$Q/'L+EQo01='+*&:{%:&8!Bޙm45!"G@ej^Ij 7 ]ܕox1pIkŜ[4zSODZ\01/۩kxTNqwE"&ڨΥ܇VS,M^u…6E%ƳcV, fxijsngwIwWʖi3P|gTw3¬nFk oZ*D\FG@p ٮ .0 R]{8 144vo  ؟ Ј;EX.V'cd&7-yS o#l(;`'߈Q<Pb%1;+*ʈ&=T0 Nd mA6Lj9 LzF$UX ~S 'Z`iL5+X!C8H=0vl{`x: \dpoO0Q 6q[:+H37z=ޱo@R ;m61m+tP'r#S_No QY13+=}V4S΁ @5 1 *b]#o{(vϺg>{0gR@:'!Y䙣0(9ܱ ͨXǺCҖs` ̐c')79wޢ.֟4j-SDOȌ*\> m5걸ͦAljM}ئuaJ鞔 '(SPo*vM'>x< [T/WS@:tv%D 6u=<4޵ '>`vWk'Z, !!$;md*n+&!& p@la'u)ha"(v ͠Cr RVrb9ÛW! 9D $#& Vo ǜrz %$+ !/W +'#%v#V["<fKENp$,Ӝf ԓ֧A&c}ſ:R RT.`%bٮ߫A+6`4Q(1 '8 0 \KM \ jn`a'G]p zoD*~ј Ѩ? 5K FkM=+]UsdzR^D#DrX ,1.)FT]Yh>C* t`̭8E z>V a/ ugc@.z] u 0s2.C] ](mC3QAW~rl:-ԁR)ŽϖYML-. O}WwH,dI/A <Sr>crT < uD *ȩmFTjzH#{gp,i{b":s'jֲ#2>듄*t"?[tvb-ŭoڷ]W#=By@6jKHX;$<,b`ڎ+dりѷPA']ohLU0ɔS@< !ΫI@㻣EijBݭ3k2H sWǔz=iLV鮥; #pז3Ud3rE}:r\ʩiMEz 3(2d2:v& ,_37]=LM=zeLWr:G6љPg3&fO)Uh/; d/fYo vol;f8g`xM%7רٶgHjfM070i si>YGA?"Ur3]#T\D%C<9" bN= { < |9.~ =2Ni"X# g#{oR   Ohm)ML Pdjgn_ R[' rK Іo hO:0JDBjeh0k6?AhB1XA,XV3Cw#ӥfԵ$NbԐZo tNJǼu$Eκ~< J߃萀oƃicḳ9¼ErM:VlA8S8t`K~g#C*:H{781v S {G M   jP  Ҩ v N!*`#;i'L |I#L/έ!ΘMFx&\V.K&,ʦ0Y&)-#6SF^xMdg`H{u6Z 4u!~:#?y2%4(.b-2ׂ7=6n8=4D.=PFZ:AA^/d[U-c7ҏrF*SCW!U߷O~ m-Z|Ia[ɓܓPվqC|*@u&&q5 `Ah4dp1W/+(r"l^K'k@)m4f 1m]1ٶ*UO aX90m{Y}jJ!*|ㅠs 4;=q{Q0#v;﷙צ" FB!9'j"\?(WuE(C }Wc)܅nb@&6Z'T ϵǍv>q෮TbD}}4G*Apq–e??tZGRvUr8*&ُ H#1E6۵d71; Ygaln9*|c0< 6 G5%9m"8BWO{jIm7Ǎ ZdӒM.~$JK$wv;F{o zH"_&6-%E+)R9qOhFW ):W$ 'ۨ]xTg--#fߘ{*89$  g<4 >d*~ L$W_%H0$1,],>&a!#o,!#g'$(*05gz>^A ZD2I,9KYVIx:D-E=yDg`C-3h6je+Mz(,3|(%+}-&50/4.-.!~#bl(ҽ& JVoCz = = ӑW9p{t?GQ:j54nuєAWCR[쟧뽥쨪d ih$۟Pl6r>c:H:fפg ax1ε@ϻuiۏPv/;OCQ =(޾mW;SK䴯a¢lGoЪ]׼~ePj6Zh0p׹un𒝽bJrݟw(rUg_Q=:ݿu@ND%[\*&;LA,`dcURm UA <%̊ Z Y5]j #g !0L%''b lHb wU8HY jR%8oJ&0ͨ2A+l#%Zuz &!<} 3beD bq%7!f{FMD3 YlR/% gm"f==*60ԏI˧̷Y14'q /C3iFɹofl:E)q5KS*vcvF_TD2kbug3u& bT!t$"[U хVOpn0drA䀣["} EB;$.F*HѼ+\.&pR| OqVQyPE[nP z0-[  =":D&B(${J(/*p*6 +S6yZB($$i lR^ވuͤJ Db 1=qZ:m H۰s?(I@5+TN "-^6- ;j9GN>nWmp2nB@Z"Bz@XUA]D`-z s 0[41b+Bjٜ z@+/ TWx# x$٣xߪobۀZF'ӵwL-^Ev9ؒng l ꇦ.񺉧aH6nB8CGM28-8?=$VtA슾{舂|n9dV_%NV Uʇ eULbl?cn2Rq^JVXٛ]t 3!yM$ 1 m|xJb%( #j͊r wc: 00=6{6*!g1K )s 8+(e%"XS"i*6O: ^ \.h3&H"9'#L.!{&2 t+8N ^|I#^ 6&r?^o<:?r,_c#ɮp ۏܰE2 J楪dtwoN PL:^L߿!^\27A'f 2,R/hgӍ^n+L~U,]C 0$Kl 8O%K DF 8 M# zUXQAɦ Fv?d|{<633Bh 6?*yۍ̠6J\bA{@nw"ٛ-y6 [Zv~T@lKIӿ 5e)&kɻ AP \q#[:Nn̳jsn2_Q!vqД<Hb(.KK ql$NoCl.VjbR$-0>i"$ E 砙C6bT"ɉE!4(I| +M,@(&DRb m .2 ?NH)p*&%[ u *@!W!S ESr_0 $i߶ GUu^GX-:(0 / 9c4 LSt }g98 :+\qu#Yst~ n߰.%7ağ؆8݇CGPJ=K1ɘWa&a#ߥנ?o- Sέɡh$pM1c㝰Jxq17;V˨ p%  z @a&R[pG;T䚞#~Z -v  U X#2L;Լ=¸:9ި8;<<:,>;aFoLOmjM%DUÓ80o+TF*s-)A`sK+@!ޙ+y'+^'I(XN#&doQ?|L K!o6 k \?nzXk)5n 9trE5|,vC?+m "}XNw`ŔŚEdeG`jz%c<i=1`Q?WrnesLj%ͷ$"3TDkQ6/D":. H^衅Ttɪ]Fa[rsGW]wl j:g=NYUrTHxIvApQ: mS#tq3r#3a/NWFp/ _Dg wu"<0{AP5emr/(+ toJP BSڡ bd$FӍ)P HrN?` z+)WbpQ,voՑLe@ .=RzzC껝9GR7 /q5q^ -gjIC",g `vg  @u:+%h ^) q(:dz+˫zL< 3FO:%g+s8f)h4_::#@&p$p ;2v/Ig!!V.߄T TKo-d *$-TZ "r? T c. 2#U57? KY{9sڏC0AmS 4 _0mzj .^jb}j !Gu+_YhR,O}V(a aa3j=ŬްGs Ȳ/(;9Q| m/zٛoW`e1 !7M4 Ln )d1 "Q<E5s69'x2T'3gX l̑J?b; #Fx9q.vI-0t"N 2Θ?usF4SC@ C-LJ-N~1(N_NO-NYJ^IǸM<1QͿRO֮"Ev~5-3(5#~C #hjH!r6  uRrPnWd)c!N vCX^Zc㐆n)}oӌzmD`[oAw so3ع ajTP?EϛIÐ2\a9!ӆƈ*O$P020wAS[ &|n߰xY.LX׺ޥޘX-`I5 1pbB: ջ Y\m<)qe輍< yc^W뉋M@KRaI /Ag A ϵ%~9nUd8h8a]J(#e]+0a.!mr&#lrCP{!_ * !B \60ǾuV _ #!2]Evd W@0 Or 8 1*uG2ohjrgF@*BK؝2Fq2d]R]4fly2 y)Di2rh+YEd? Gd!m}AsD t)UZq}S)bԊkkN[T Ŷk 6GiL B  \Ug:Znj+03-5Y $$(c,->y.{C/;2.h'ϓ#"$D {)).4uS7 l4lR, Ez'`6 խa  ɵe U\q2 [~Bi5 'wFh\$t5}"Ř5)A&Iz6K }>>3=h<,yA4F D4])`X9#G$>I;Op0^4Y U:CȠ Im$ڢj^Xj4h3,G,6X!07 ppJn 1?p1 s}Cu8 YBsK*2yZ>  L'" hEws7j~a L Bd]K= k^XE;j2f`a PL+;R8+6^04}zTGVKF-"i_/HpAd Q[qA-dFIlJj pbiϦ=LڵbߓlLUuR=ר# BpЄ6 eH0Q*Cn5ەZۖTԳփ'1PT ?Ծ*Bf/Bxa 䜨 _P 1{SDO h~{,m?N|ߩig_:jl o 7 lgf\ C 6t: 3BY[ UrP>4 )O&З>M=*.ħ1)o$ z˟LsV:yPq, F U|;B,@Mb]} /mC3F2F#: Z'ِ %fzm/!$n%50#A ENVr› z*Zd+eݶCX= sl q7ه](# iݥC\ވdX&\c&Z:br>8ݕlL0V &_ڰGleDhc4e-iٰ7~6?)a@Bmsl#}˳Z et+UA<]f{+o1ѭћt NinmƖE3i'9kWey;Ջׯ[of2&ԓE7d9XOGIkKV  z6;%| RDP$F(#m9G3<*404]4#ҷ$*I1\!%u}ֳ/ Qzv;ԠŐۯr&r.a!,`'L'&$h\FLgbD+|.c&29y*G.s{5&0O2Xs)cV_ҖKDW[d%! 0M쵮gOkNrىWH]9)]UWK\ߢYoJȂL,h^ H6aZ j@AB/q3Չ8܈.VԪz=wIssvt  e \& )K6YyO I 9餩KS=uk(=p# Ŋ,lS)#KC"8"V Iq:Чjv IsW/|T,GoP0 v~D>%"wsW"؟e"5 6,:>"EA</.a,oN%1ĞZ2l/0FE3rC2٧`~[ )UXKٚխ˵}Zٞ: yTn ĩW\Y!a`٢:.g-B$ R D&3K/lHlB#8Pؖ 6;X:~ZReo 2ܣ/Ӭ8 LrmJمylө1U4ucY2 `g~GNK)]kBJ5IZVЇۡ9$fc~$'T[u20 yҖҟ81ԟjק ,.*ޥ v d?ط|gYîlK`o,[AK۴۶0*d@ʒƌK_ė!j+̷Ax9"lW]{w*K40߷sT\TbR|u0xФ99:g/e\3"NeܴoaY)SLGmW#"c p|1Uy;L)VuQ<U& WO `0 1H&3tV"mvW1=M)/ 7l 0Q]/co,s(+U+.k ֖5$16.U+1/'(917%/^|-4RΆ9s9g>/P$MK"ۭ*G]02yb7rA K8[iPsvCV8[T;y4 3+u*Nɝ3T1r7?MF=ͳ:I9=+B;{3o8_%44Ā'$ Vxz~ZCiEu[4Jp} F d^$AWNR$ng/. w>욊z oP۹%4r߱Ux &CQślںá#|K٩kLF:&oį*$[?WHB ia'С,녽Q`i~ IaMYs[lEɛ^=:`(0:;B+@YȔ <˧4`'4>-@:h@537F5-3yҴ0/G73&5le u.Ac*ߤE%Q&n ?T($c9'Jx%ˡ(g#Q+J! x} IN"z +#~,K%HE  {0oz͵bf'|XF`%O*ؤէ \Vd:f/e)<`.;P禶v)#3 &TR_㓲FCuk`P7T5Z|ȟ ۺǽ8U퍬8H!plmfWF֙0=oĝw&ՎE;NF>Ϭ`tbjFQ ;;ȏZ 16/pN'I i\;"% (%dPŊºr:߮1 a74wN[Xe>>_E9_1δs*tF&^0uLBwNmĆBr? M * H=$>O. Sbd&y 4ZtTx:1>nF鿊0;Yp [(pI-W )F+!VN{hPsh+[ެ.0D~=5|ʰ  軂jv1ɌFv_qka&D9q0{c- -c-F'e{|Rh ]2W w4Y" vhߓ%p bmo3Ѷ ixLI ~2n bvKnHZT|z$ߑL5g&8ZvjFK4b XRt-T{B=7LN-2eԁ*ۇ2gGAԙ.P^F== 3?w5U ʼm>M `Y }oΐ8LHB[ F=,(L/*i5z_`rvBm+K=^/`#5l#0UM b? w<~; {$(A9$:jv^VxFaCeYvn,0#[&$f"> f.$T" '{$%qT5Q&1)ܡQ(yQL,ʉY=. ",r$jL<lb ;3zѝ]ixWT`BJi8}Fe^m\?W[*hޖ~j]VC|ː1Ύ;CP <9Uew| Іe[DdQRISvsS&>a c6)[giHH8XF%H4xf zb>Fd <3wcA ]EWsf ę) m5 /|`A0+S& #l@u!3D\-A"zC+ PWB6S`ZY /xTհՇ:ߝYOr V|i v╪ۤ3߭URo`P FNNF.NϗC>K?6*d盿:ׇF$OME+u[*%" o\ H_T>i 0@?kE"j$`'s&B>!\#2!"83!_$u!\ {%9H&4"h?h,4^M5@ Fh 5Z ok!c:zp2 Gc/&bMg22S %G4ݺM{/$wmu]= &<mSo5>?X8҃o[x7$'vlv/$ } ,eܦx7mz W<w˞>$#*#|#=d$3"._"# 'R-[`.[f-s) %`%2$ G*eO!/J9ᖲ@a+o':LYG hyYn=3p)h[fA`y`(\-ĹreanD} 8}<>иfg~# H}窯amN<Әդc~br'ĔFuyP.@1;AMt6fykxDvFV?e-Q[{hW*n=>NKkh{:뚥ЂߎDۡ[S˕ѓbjLu3`՚EWVf ؽeBf= H!ݥZ{W#έH޼)/1>a;;% :evڥ#$d"m:ͥkucCS9XBؑJ5N-: cw FzD}^fgLqEd#'g/Usx כW / G au߷Z&rM \I Je3 s"M[c U!FwL'41v7Wk1YW"?vO!%G/%й&?h+Ɣ1/9m$> =c4),'dy*y18%3=/)+t0j28urA 6MƮT*4T4OL`B&; ;0z;Q4Y.09ڔF#OTj_NX4KY8FZ59`&-M-)Ro))&Џj###%Ʒ).'43M6A4$-?&&@k %ܥqIJlh~5eI&* kFXI ۘcq%4Ey5Cr?6Md!ط<\7Wʁ kMѶq{~~@֒7ӣJzu> X Vb؋ FaOnrZ] 6'_+-'=t!{ W w; `@GX \K*P $iBѡ23͈Swyj5[ l [שL9;I"@|tG[>A9 P  P{ E1 d T}V#!"#˗x S)5U; C9U'P15C^^1r(ʆ)~4j8F i k٪Ä"ՕO `4  N CgD| v|?e׼<  ? KO Q{vuO,: 7jm>s/R$+IDRܚ7۲YMw3zQc)̮붰IirmI8EtВ^J^h = m 3 xpsPs tJTȡ9{3И9yg4?j `AXOZ<8"\2G C o DU"X5Ӵ'5 k~@LDy"f5EzfZٌ׬0qK3r Fd9t Q Ry$4a $>훲33XgJL:裨Z|+Tf{ 8̐vƃ uM:ּ*;U k*!Z SZI=EM v̖KC%(φ%9V$Ǒv Y'O/##f&L,>5HE> FXewnjt1ۙgz=Ɋ :7^FL먢h [aCсCRq5]1M aj9vmYBlqao5>phi/-ϛt|;ӸiՋӎh9ݑOԧ Ք1g`wdE>( e "Ш%8̾7!ʄ8b)ܱ+(7ퟯ`\Tx16I p5Bڅ4#N#qV2ZNzkBԊS(.c)  6R)`C3ߊ<˹Q~Ysj('ͩ=/.+*q# j:Z.#+c0&B>Nx*]!= hetZ"d m#L~ (!>"$`"Qa `(P$n#PXj\"Q G:+)*g$V5%#M Kd#q"/ 1-SɆ X[9yF`  ߊ a]k $*# 财B'H @  5nh#kq$anW#NE4E}C% Q?]PR=y RJ pP$׎bծ Hdb=IB/?./7_z)>%NETE{>zlָ2r MWs͗h欩!.ͥF2Ⴠ6|7}|JsB0 fC #}چq^(. L;$8Vi2 ;cx|x]!궫q[H0Kc *q7 ei Q âk OT{e!ϣ$]$x 3"KaE{N.#u 6=N]#,DFlG m wUO>[4Fb^VvL\e}ֵwBLq/ ƅʴ;> 毼2Ŋth˻q҈{٘z}XS1F2 vnYR}nU!C!l/YH3tc^Dܫf\k^d|.H=}V)ᄂ 9hSA+ĶSQjXbp'yv cmzcͶ 7 -r" *R9Q%>b*!PlP '60t lv؛sj=Ij0[l!P-鎨^-~5BQCX:+ mA0 uD$_. TfC=^9faf5qPr٦U d83Ǭ}?v4䥒q?M8r@fnJp͝NN,J8( *KK+zNwP|Jm/闚`i-g.bK ;# 8. :' b8 ;)- G#fD%;bm9rdy wbO ]h^r&R- HIl!ŮvpV$_ !& q(.g#l_,g0)O5&ƺk ]]F}K N:Nl짹Z]I-NUN:+kћH@! 6 QJ|t:oI$.L<2^su>DY{=SkFI[l5x'b@ٹ_!!;!F}}Y$*\AF%f-HeD(Nwpe{jV>8 4*D IAL ]3.*|0F-@+%u!b }-5 b-_%t~ %+(e WG8<<{uq|ꇙT_M4r%ܨjnɞއȷχӴ5M֯x̻c'ءrf})]O٧ lI#eqj/Qfo`[^ ۡ8-gLfCW4SIiBh vc$%B#d_^$T&0 #Z-|zLRb[#ԓ0M_o0,W0.a/*#3.2BAm,] kDydxhhhu6YrfBv (d ^[(ཿWq#WC?,j5lz [ѸDɓȚdMށ,)Wm|iO) Wx>0#|q<ɅC̎v2WѾ3w`כφ7 "JNci[]~)AnټhŽִL Z!~Ml`qڼpڲSle}~њғHۼv.QQS/x7]ˢO`l+R/J14E3۝hT1b);~juޏB?} Bs8e> *; c1 ItJ 4a (( }xZ k ~GO&f~(\Ăe37U^ [|WĜ #cT@v>=9꪿l@<S?bC(D#lg#oF\.L 4L5.DRX. V5^0PdEaJ*2AGS&3c^3H33D0+:!J )s+9.2X88Hp?j'9l5q!-;Dd'qW$%.^.8@D!-KqS=W U vOBbF`7 0& ZL' m"b8u.= =n' S&'# zK@tCw$9~ 1C  Lj|p3lJ)U#M=w,B먯XKzN]9@}uNԚ  5#yݩ:8*!ߒOk6j>כhƴe.+ =KS2RZ^l E "\ZFBvNd * k ]1B{]jE(Ri~:6bPXf16WUh;"4p]jcH}G|W^cd7Sw{4hvlմ{'Ey'믎&,]HKޏU:@~;֣Gbِnض\;] J'j} #)5n jf@`뀝x}^(gH~:M - $1_6ѷsmurғdx3K9.lT30=!-8y|= d7R'D j\q&'f+Zo$i]$<^6( <ب-;/x+2v(Etf!`K< &&.Dq٘] 4D:/Ncg  uCyTxgy0C苢ɠ db T\Dc jR@c!X SGӏ gJ &/i(1A,߯&.,O*h9C@;>5-6/#?( 鰗$8.)q6M:ڰ40HEb5 2 `'q'{"4t1!$0G))G:$x^ 9zo*|?N[<7y^4 j&b.l,YSw*'+_-p2FD6M2ƽ!]d .GI3P &z[r WYlqSV,% )cD[ [ W ? < z 8מ f) '[l]kt ։ F1G۱\0Sbh4 VLw aOh ^ / ncA[b=1brwFn$`%J_XsX>zP#) 1 cf@AYM%IoX)a1q|#B´zW f[ EN%( v.SX[X"a*! sGa @]#'"<&f7**“& %kv CE $ }O ;4I-&ҔH(gJl6nxm]/l|Y?EȘ7)ebIΓ'.=bJ8K\m246ގ6N\5#18H+͜q2ǂ/Ħ­Z Q1Ac־MQ-@Ud`DCiQrV:j֡{Nu;":dnH]ΘѳI׺\eޘ06zh#8lY sj>R\Tb-;(JBGDgŀ̽6{UW 6AQ"`.>"O*H GWcj gΰ TOT#'-z%?n%=WKT}Ȕzz"i0 c6-=$"0.x?eMFA"Ԑ8 =׎qp܎ WP'07'  ԠHе>/ QK.|m+:(thT}1ܸ$ {] Nj0ǺY !_ q 0 U!h-@U`|ꏹxTI{$zk|JU j Um"Sk~T(m]nFo} @Oi_>x"kX -| mX D4 H{),N>gIوa\t9k qFkW0N$1^.){5'43)q }IQƙcN3e_M} |AsK@;S+CZ@|v iD,()Wڄؙdijn ˫ D"X6 ٯ l ٥yl+@Vs+^꧝*W }G (_ s<XoS-+Xi9`'U qU ǖ"- ?,Znx7FS^J¥ x !/z "j">RCu#(d"..1,#AQ=A.zt] _ BR+a#JPO2_ogi )ml꒣MK"iq5xaTB*ΞcyKx{⍣[Q`3R坡#vaLG iK iėMQx ~Cvгnܟ ?he; !y,/#N'D&r#I!"Ћ$W&#kj:zv4`rH-WbU839n$}$)(ɐ("$ !5G#&z[$i(Ʉ-,-.Z2i$1(F2i&586K6v1\S,;,- Sa/91:0/<,k'It$""d17 `qnñߟ`CWjwoE4KTI~26[]0`WRNAVx|J|_Kx*By -8>w f9`4omVEM ڿEخY5պ~~6(kIwuJeۚXq&M,6 P[7P,1%<4eμCmچM?; ޡ(Ccho՞'%@(7Ӟqov㼼[ͻMZ0ոCq5~Ă=1ǴO_Ъ|O֏wP\⃓8yl-ܼ@ߘW^77aYT,qD6&ܥdؕ,c9UĂ!/P33b~jSHEk}H8&p޾h*Է\[PVb֒žnm['Nkh] + s3 Q& z1 Ƕ?y^:ɔ7y)={&|Bʊ{].jb8d].=ʿ yؒϔpJ|b Ip_&BW'.$`%%5& '(V&9x%3D&ͣ;*nv2y9z:w44_,Ӹ'M& #hHnAi~aM[ .Hl:, |%V*G)A-3W;/HA9DGELko>?C@͕=':6yr73=.j-y'x")YL;}@aA 1\A-> "fS ˏj/u8;.{<? N*  l s៪ Jfaed c RmnAR?/ɬʁ<P" äph)})R(㗖貅MA* F}qܜwʻ Hfvw ='׋/7>k5o7ky %5ލU8ْSvhގbp8eqa=:q!GL h؃jf2RԑQ\f|#t'C:sIlv+^QNR$r`L dM&_v˄w@h}QBTa\& `Cao`s ?NP x6B RVzqfcmPP -2aTL3!\#w9!V4C6'n=|,DT?ZKn=9G Hyӗ,ט u)9lu vV"f6-U⹜*=j|ܠR#8x璀ex-J3SܳC-0?mڀBec%[btuJ1zK@udʨT-RX(^NkxJZHl bbĠpьto co{0ZwӝX"(4 ǣ d URe(9ȇʳaR`Y oo +=7  oA _u aq g^ex =$lA[OOg@]GK<*5)n%i'*#tj[z."Ik{ 6pd.(]!~7Q 6pHPq Z[^j"~"8DcvB2,\_桺]|9掐(^&F>ɟӡ ud$ՙx p۬*F+'EeDWyDLH^~vP"*~+.U-ECO}N4D\/ ec\T-tT7,B@繾~00ر`DRU3ܟj| cYoY;ENc.չcElvėv bk X"5 x(TX|*~};KwiܝfR܆ގտ;"\BKvŰE-ܹ 2[b_.xC&NC ^P0x9Um/~⮱_vդQU0xGk O_+48y%3s6h0B {$Z;핬 b5B57Qx#N,)`\S-i N:#xjqB wv* + î R E`6^{EoB}q?gβ}n^sξ1(Yڞx;dn?f{*0󒇗62E/AQ?ʈU*)}Qp3TgҘg2჆&% O|Oདྷ@duv؄>կIɼ̶Gٻ=*#&stJ 3"pʥK~ggrTrATW Pܣ^1ۻdj-7sŜyD 0vMyݣDx,ܰW4ڒISEM/]߆ I7 !EyG2{7a>K#ehŏu >J5 U|n%h([e /L,25][-=%~GQs! ~(3 ;^gnAY , d:K#G4_*m#)Q)ټ7;8v-T,j4Tb0f~,ak4RD2n_&Q.h&q&_),.ԷbN{s!!#)͛ R̨'zU,ةRl \ \8a<]WsM](+4Tn Ӝ nw[e(Jʤ[!;2]Ө.ʝp_"VrX&& {Q SŌLvIc}%u u.RbD%B^"c{遴xATtTRvUa@-Ϟ'ukHpZ%aء2+ 43PWPW 5 {:J e_l%YU^FRibѧ9&L}>ot"g2}bT~:[b܌8mUfyūv(sΑR4esu!Իl#܅oH֠+>@ %p6?l(Ȅ;BBɝadje$ШGuض]ٸ,.s^^&Kv"flƼ}ߣr䟜6ņ䱾ݒBJ÷౞tݶ\@gܡkAZ sK҄T|x8 9!#S<6!q-KۡPOޝ+y`IApt˥ii [ҲLA0/&~ fT nz 'UVa &+ k 4B5vyƚ_p =' ` ǘ D8&I'AEq=a[0I4Ǡs˗Ss |OLow ~pr4uٽי;V8:0QX(t-%21k6yʛ(޽~)^/ Fh  [  ( TlD$"$TB). 24 *+$ *134bPg˥\?/3=?*CRqC V+Pbʗ•J.xV;~e-S Ui f. Ɵ&+ (KTz w8_ntC^  -Hb`=r/ E+iT6h 2 8;_֐(:ͫu=V{7J6so,uL!qY節xz>i}'O (ܿxѰEɂ2*$voD>d*?pwa~ni#r %(}! ԙS8D, xmKVS /b !Al%uBFc |iDYst?hY"_h͞ްV\饸0AEZ{D1*J@I?nq& F7  uQ #OR.RB/W0!b ͷG6N.BYv[0mon ~^ % ]xb [TYS;(>aSAͶHOFVNn޿ GGk*JxSMųXAb  hy.t?()*uc冊n="kk݊؈].#櫌q2ޮ>뇫,d{q[W|cYf߉=n/X߽XѢX??FxƅiӲ_M{]=S_?Y”5ƕٓzPu]ΐg (sߓߥ^'5_Zˁ7qj kdD!J1 Dˑ\lJAi[w,a#auBTK+(< /oֈ OB4.sDK+e3#y"vqC!KH"s/)#mB#}W A|w jD G4; PU-0~ ji# i 1`: FSmqh&;LVB"\LI(Tsd,8mi'GZ1hFzniLC" Lm u BzQG8\ 1tk&x 7WWl޳R{!FPjG.rH_D{ = ,2b}C"I"l$m&ۆ#Ց>F="B>)\1$3-y1c2Qqm1ƿ*%d @xRT]G uC (k"O!w u=H|'G?3vo'O%~+*`(S$Nܜ{ ' e`Oh"20 "=Ş8qU ؆ ' `d S% f%z'.E#7UZz,k0 Æ r z{ΌpATTum$@R p~]Ab%8'Ӝ@>uz?̺ޤ9eFFD)xne#` j U'/t/ B ck=_e;lhE|Up r6$oهdnf]5).j-6J[2yÞؖX5uF5;Wxe+:w54 *%ܿ t xĖ"C-- 88UYnƢXaL鯤 A_U V>xaH Ryt/ BePs&Xi*yk @F ~ :1e^ڊ'ozMw J( y'V&m Ρdg og"a̛K|7SϽ"&\2&a6(Д(Is$F 0-c z"f"z$'6( %"4##8C {S b II^9]LMhLoΡ)Uu)qAQ&ngy"60)+l&(,+ C8)L&n~%Y"ɬ."y!"@$V&4e'.(!%._q@qnf=4 Mp{ 9\T Hzp2`X"RO#l22Ͽc.1Hiqvj*3n&GKY$D u;X~GGzpk~>x| r6f~ҙ9w¸L0v` wEآ!ÛPK6jyoFo0~y81CՏY&ú.£F b6opX;;@B@`!cʳahj<69`ݻeq.7gfe}` +*z=KT6O!?k&譏<{rS > r)@zt(/pJ؇b?&7lDN{l =LWJ'Wˇ17t!υ6|S{a>=v9?2Wˁ=ԟV۵c]J"(WGoH, S^#[޼DOH72#ҙi5Ije2 @R:HyˍtQ6aŹoV0UG܏ (ߥCWgr{ :x1=@(&&&#N)U^1W% >าHƹ'69㜡k b18@`wۆBL%`e%-\ߛDx'^0μ9MkkSm"It8mHZ5f,̦ VyzgxP,T53/E:7 ~O֩B> 8S7Uqh >Me*53u4  pހv>6V`) ǟAF*U3xC*k\&3֐whBspuי䒯Zq߇tn೜r+Б雴wz5LTZ琡 Q@s vi >LS2@N2~Mޭ cMt|&aSHDG2u8KP# x N&Uq n!^*M)/H}lkŻ a ' z x Pj;lR OA ʱPbkl%'y*v+ *۫+q/M-4|::v"8v(6M4tCo1+" '9%Ej$ cn p   b ]Q,H&q`; ]#7"")X276F /.(ј#NL/$>!%!BοX3-b! " "f Bj6f@< sx!!$R)]>0]23eA2s2y4 <=AA)=%6h,R $l-%*$D0I2/-W28<]@C B<>8l03=a,(&ҁ$#'/1;W`6b5V32/ӂ+$:_&Yz?>Ms5 {l!  @EnqPT\4b$bq:<>ȶ x - / `  6ԫYZ I) k"GA[m`YqEC$=7f6C*"XT) A\)8Rm&}(y]Ynm׼n F;lKD *K: .pRm !9G),Ho-9CA'1B^TР-6~FUT Qܸ·VMfBkq -r$ z 7zK $04%w̎Ȟ\]J>c ]49aXc+L l+17cJU f?8r`fP/'߶T3[ɷ2"!8i1d]3'%EZk#tOK]nH2&y'I>ڈp_?Z|hvYc- !?#3nDQo"O<T^N0ksA䧷un z褖 skXYCw<O(ԅH1_JHh)/{'ě Z<:$eQ1X.3ۅwځz4ژH>/Zޗb6DޜabvSrjN)®H1A_ 8VDj[p43g3W4ȵw +#X~ڜeu? Ga׭kӬ:B\ WkL|^ף7mxOpP₞|@Y -C4S.H^ g̎m0O?..^S̪-ENшyR29{xm)ٰam'1 Co_an?M P .Vݾwi q W Q&d?~Tpw}^$| $ T B 0b# Q; ܳo 4>LnRa`Pg2j:X݊_*ލf } AI:ׯf&e}`Z74 1 2N ۧxUJgll+OMĶ}Շt-  Xj[o[ QW>6d$)4 5).0O463e;'W< 49j641/FB,&i/-J\.\/NɑEWP; BC'Ҹtͽ66o |s\B&Hj߬n#H; T 9@mrLR5M!S_=p /h>D2>u۲5()hcPX<^CnGЈ~Fz,` 3  [pS2Dd RN^I6wƶgnYZ50셾Z|맒.Y }g(,CMPn6 1,L4`i%:3YbU_П"Uzm ]4TEojI#2ԇ@`g}L|%obzR[N 1  ¹&Q RΝ(-7jR!YDNZߺ # *ӂ ʷ| # -!r0e q e` > xyK2 }`,a2 NfNNZM Vf|qPjm  v'0Z5Z5/ 5a3(J1%C0-{1<Y1xI.<$) !AdMuNld__K =zJ_IN 28xxK]r~ F4_&# >'x+3|09U3[5?7aP8 &85-c-6B#b^I<?;  L]p"7mg/*&K1Y ^>oA>8UH$z^Hӥ hv*=ӅxYM#%@ S'E( D'$$*I N d'ZJ + :Z1|U&eHFDqA UPPVp 5`Q̺=WbsގT^woGW 4B:H8m.l͟ BSgG {^p7ݕWEv`)kϰ)m?;Cԏ44 xbq{O琀5J]lEW> 8Z-qSC6ni2n홓| !֖&"wK*1Ֆ̗LvFbjim4c^TflVSѥJ#Vb/ 樥Sv"j2T'P3jm> (#$j#-?(Fijl "(m:3Xv|ciP9|eqh)&!W,\қY'%-oXX3\DM}dKSiE vM NU~֍,Э m}Lx9l&$<ǖzo3$ [健~/x3^(     L!G\H, iL:: iM>ܢԽ O isZq&eܡ -+ͦ,{;^v /lm[>(  vi@7 4GLUyko (Kr ; ~b\:(C8XS5Y߱+gnϓNkYȑzfn (.zg)Pt:sM"U4 1E@7! A.*HIve\rPc]ֵE8آ@!.T빘5 DM>2癩?]jnҴQ FJf6U]fҴiWqx )z4yHeXrZWO-nz=(Ad摽 .ئ$OjD={*iV ޫF㷆g. X݌`jAVѣvm V9[A@5T猪Y#*.WKg' ]"OY@sx>6!-Uɜ$˩=]TԧRF/fA6^,D #  TLr I IjWqlf W;JCQrq/䟭MFwf,$'SPf ٽ?;2wՃ1Tϴ ƙCݶlSغ E"gXX8w:a8] + B @DqXeF/lo? >կ ya sWC+Q?i/2GF8ߨ"m!'r>;#etd#$|!(=5K3+^v Xx)C+npʤ' 6mFD</)EFM&#Q 5 S>[w) di'|_RL Uv,+Q 97O6_kH{Z # \>x?#Y C ɮ - aby 'iS>N YYa{;ݔ;9-am=C #a7'N~+P0|@I5\7@68*2#-f(&%6ļ$S/$]VR$7$2a# Ugxq܈z3E :^âofCR*M vG?"-l"ƪ"^y"P"#v#z*?%&>&#T>Kp n$FBPf)GمP4ܕS6l..!_HGD=f9> gYAҘ 67 " g-4mA> ZɊ&gHC(T]U{NA߈Mxc}/^差-V<7igwP0F t {Qs>υf/δG+O:F=ݻL z: ]Y)ii )$+;V'2[I-MPDU>jsQu]hٯk{ό7OGcVpQ NVTf.fud[>FȧHI%H2?_pI|ab_NDhV r^,k,!fJ);ṈWr @ p,R2 霌""o;5nAY]9]Ye P ײ(M(B)01C6TK CG{ ћ`a!''-*[3,9J=F?>K p<|b95=t1. ,\~p*h%\g  ć  B ^ r~SM&d1m^xkUZ7gU"~'-1584: 9735$I2-v.&z*+:$hJM:# KY !%<T0`Vr ץ ?ſpTBB ylh5 DD$tffco#N&m( ̈́)~(\S'`&Wr%"-oe`i j- es$&VUźn =OVDc#{iGN>A*>$WdvxL/!<>< $Bu d?)W~vVl 9i:v ߙ2c3狸IyE^DQ8eَ2GZ2ȟ2[+1Y1!N~nuMʺ% !_&Aͻ3?7;R & %s!5OG DaNp.& 1|N-?ߣ6wLiJyz/9?{1ED%7) N07D: / F2+_]{e2@e\P:6鼲%2`xN?p;ZqNosܱ~p'ԑV˭KTZjrt΄i0g꟯6cOR8T$Mb+RO .R { *P0C[G$Ґۇ=FfO'?y8%΋Fǃ0WU@G$O bƓ@_?P Es(vXJ=tCd \T_xl- QNd]o{ Y+^m!νSɂ44˅>kϽ7J}0Ł)-_ $-P w.acdt`n$&Ŭ(=aw ,c O r`û!<h C쪀 P:]Յ-Bv%Fݷ ia<H78/0HQV&h9t7c\% Pf~N\r0D: RhvG d 2p2~- 3'9hL_{ J;'9wBX]Aj+2$} ~R!"$hD$Ͻ9#}4^3SmD66p?!7iۑIl&AP, `XCNHm)ߍSs9禍 9\"lqLX x E suX߳D4<4ofB#6kEYB>:juP  fު,"p+sr巋rבX&pc 6(?FEH   L eT + ,Ir!Bkm6VzHWL8{Smo|:<2\_-#,W- ks*r:쵕ꡊhgEZ[`jGɜ)L(U#Y3D5|X1&XW˚F){Z[h&Vn&y/0T-_%N@fƮqxOO☶n]W$jo{%(C.^jfTK8{'*+: d   k,t_qayq{=,y/E~zہиښ"d!ބ )GvR!ʠ`zf,E9𠭀AfMUR1&l쏢rV\wdt1$D#)ݻxLn&NpB+eСN-͜[̄ IK/Hϼ6'Ճaׄ/؋hٱچev[Z3ථ;7c煐 }?Bb;rIgF&wz^@t;RJVz0!Dj}k[*j q:+GDi3n2CS7,Wb'-{w۹Bۏɛj'6;qo [#8d40e񌾅U aVvu|3Pe E,C[PM? K G 5+!گڎ/iT-TBZf܏v^uo,u [^lWӶ< +s N~rFRnJo˶ulLzo"2=  06w!Noa9%/, GI <- 8 j9 פ iB .j ߊe M֪!a8W, o+Lcɝ P[@RT 裀+dGZ҇_zC rxvγ.j[%K^^ !a!z 7?U@V+gMX2%u@D!2a% (`+ -G// V/S-{q+9'.c$A@S"K"ξ|#>%-&o%jV#!CƝ Hl!ק$K=(D}}+.x0`2835r21Za1X$/,w(%V!rk$!-~ 㝨%),- -R*U'$K"EFς~`1 5?v<&*3b)1O1=<Ȁ]^Q i+L 7Gd,K%x-6Fp #t+e%eO FɮMq3{;w #꘣>A} %!h;wWY/ o )z_z@1dȏCVGXI[TΟu_]aU!mIX/gơd; ha?@NaSG<& B* zL])W믁켚 m-9oȲ" (-\V3,]'nr!d^egWayprku wNxgxoU7 6A4GQ~ cSS=)8pLOoD~R,OtR5嬞܏0_cep6磫2h. ;X8!lJ:Wj;.Z k{ڊ9Í ߀p!1-RƗ רN*Wq |ם wu PQF6[V>]6^`}Rknfͯp{Qmjp$@,f`JC+,6B5})\E36n#Lc[?眦v/߸ rb 7KDE|5Y엛h.9<-~rv=nH_ w}le4K&dԳ,gµM0CxQ]`uI!$9 ~DK]N~te0 UKqAAdM#xS^2< ̬`Yru(E{Z愵~6䝙`3USMNP㹓J\9}Ȣ&[OJ0J;:䥇kuGi-fKK 梎r^ gbfQݕD&juB)ML CBpm3{7_<%LkL[d[A} T~P8#s[HBk4:)e|98VQ5$%x  b4  ۩b\-#;tb~%EŶoӥR$Ի!1"I )h."}X /_cjCdX^в9e*/ec y"~ٰd.Y( }|;t2~2h% Ynn8lH$YZDkE6e|o^f9`[i/ / F=$ )-t ,G l֊ Po+  %;$jOzQ cǞ!Z$!EhJFٴ]/vEo_4~ScÒxN]ZЊmO $ Maa  P w { |E Ig &2P :d+f e piM(`Mm9yfr9 ) ) } , -jq --oR\#i75\G-;m)Vx #J; a< zB;m, E{OCۭ0zq)' Rifb V/V2 HԀTVX^!G`57nqwDI9+ !V#MyҼsQ)뱽pJEl\*=FKqLd8 z*cVDo7޹TuM\ pE,?%\979w } pզ'_K}x]$[c^JA(<<~/BQ *ձ^m8cJ:ameR-v@mөh EA?ƳB)y{"X[Nf8uckV|6 Nv  E ,^ KF9SmI)Sga9溰 vͮ єId&b\y8xACdu?J \dxX0iOM1n6"6ܪvYݢZ*AO jdSt|XZR>5,X&"_J@wA'e π.3zϬ^и-='Lh:WޭX ųWYf ^0]9MX3\|4Yk0bo#S*iosU/_/I^MƅvO*ߞ1%?N$Y:Q冶pvoRL@nBG h\f'N kZ\EbEW ŵ!wv1Q(K Q{fJBFm6R"Fҕh23<#c]MW~fa$%ȒZ 6V}pXl I a(^ @ pB@  wu  Tٰ;> AqxN缣J =!V'2l9#J~D-@ݨZ x y( ? μ DbO6KVX3 . !4' di\Y^ Yi!l?{ ^"Nd$R%!%ď%L% C&b'c*!-(1 495W?K5;2-i'=k!4!f%t4ex u`w+u,a%W~ 6$Nԝ)B^.x=1Sb53c>2 R.j* ͅ&{,$:C$1D%&>c'#'&5$b4_!E}u8Q <Cē0ZɏS7~NsOC;A0.Nr(Ԅjj0˓I{nڜ.B"j${aX-EF`ٺ)6[V3j)3, dD "bg E T0i f2>/9Sn|bK$]mLitIgSOy:c*7 lS~j}!buP/t{K茣 h 'oېBHJn R; A 7-dmn|BQ>Dt11NXyzbG7y_p FK'É;  ˘F c :DY73C9uV9k"2Pxܷ'x/FG}\S)a靪^s`Kv첗﷔{k =}M_p%t'[SE z' <~cWW7xu>l Opqml")xo HS hQvGqVPyYq$sDd__J ]1ttqpFw~`J{<o+n}켍eꃯXΝ 5/ZpL9栛dXnt#rU1>۾\~dOs*+bd*h@Nԭi|b`(Rd 4mg=AA{v3fD̦#  +CF8o"`u첓v Ӽ*a{4 ?z:/y>%\Iܴ^|Dt~$nB$Bdxwa!R!8LXtm;FxF\^8L[jl2?E#4 6uOc$4œGa6 ;|v ǺXUSwyć 䣽jcy|7 CKJ99,r},CZ$  ERnec$p(/3V1`Neܡ3Ph9D]Z.x?a ;#/&&:R~2fv4  jLtXCyvEQ9 (aP*q,[uDIu%VƬ*hFf0З tB1B6XOl|gn*"CPvgoeA^gP~Pb],KHy^C/9 Ht Hu7KF!3ٸ76x\i# w x^Do)5{!k}#P A? ?fɳZ?}  2T ؓ*Lȥ34X t 7/U QJ}ƞet.Dk34pt ff&'_x_Z)MmZgm  I 3 ZwwPSD2FFvaG$ \NϻHWi+" 1WaܘA(Z_x<>u>tܫA/iv54#w% 1Zap!d?5W;u.}LJ@:TtrJ zCyVFx{bT& rFzLā.Oȩ I[#W q! 7H ,seC~]@#<9UX` b Ċ ) = -5 C $9 *0Mo9AX]K J<7:ċ&՟XT: /"k1@C2L+rz!6v EhR5@ e qZ~jo'(S?L1ve+)v s  ڕ) f o  q 3 9  ~p 6XkI? !uy ɇ 6?y=Y 5s q   u ! &# 6 6= c2"8"?2 5'āj Ñ0;0tYE@? n TN(lS;%A! 2EN 62!>s IS+i̜3+@`϶ɝdS@P,sѴb ?Aes7v paƿRy ^> r U+E >K"+N0%S.i_,a.[|x"nV_bLD 2" 8k= [rxOU1pW,Ͻ>Zik(zNlЯ< @&*iTgH߂VM~? #`JjCY凛G(QUnW}x}T1'10ݶ/n+~XarQK V|IE爅eHpUHI/Ah}Z^4Jw5PJ7δMbm3s_DE33x/+X!pc?ecQyC ImPꪹV)S(亴nXo屘BOcAaݎ %z 5EE5 W [~H&!*cL]d/UMuzg꫊clHB8q!wԂ*ՄюΘy1tl9ǀfD2bբx43ƲP[+߲n QW;)ͥ̈́p,k}f-NhA[KO'm t1bZZ^ q@__<j|0Wu҅ᐆ @ 7ꌇ Fq갻sN{:fGҰP%a 3*bNAd4^p nk*3|QM? 3HV[ Zhysl*e_njrir|1vizD ,2tqeؖq9ցSp{ T _ w6Ie . ʏ orD#YSIa61lF Lt{G)[F"3j#t #"l!'cQx;1 .I,#<~*5-!l 7J 9 -  AI ': ? ZzZY;DY'IQT5QBNX [1 Q/\ KK?  [, E+8M V vr  !EsJ^U9͘yb^z!4""}!Sp^]&cgt&o:  zuq9vnZ)A 7!}H"_N"P;"kG"t#"[S"աE#s6#M#X##-#g=r#M0#Ms"sM"M!xO5Yo*ӹ5OsВG,: sXh! hNH;mL֭ d MM [ f[ X8pا_O llnDDt3T~ sAJ^e6 !"c"y! vDk_3*uvl͎_$d~ W4& g &f:Suķ1:RE  ( ȳ VwoMҶ1=Wd Jl B飯c %LOI A6]U,BR**xO TSl_8\TOױ'<~Po K5E3U* ƌ ?B.Щ)<pvЏ:n**KQ#:p"z>bބj`kYMP6rӃYL|;tCNМ9C?:_nD+Qֲq^Cj=jd:߲Jw v&Wh7o( dptCJ)_JtkRg2veRvtH(P%7-VSP1We5bpuPf(8_e&9&Qy[EݓQ/:Gqs6O{4~>thm+4R"|~v2)[ĻD0{1rex3Kz$yA5'H\5i=B&LscosCpH2(UOdü9: Z𽡷 t:`G}ً£di ߷ D3 *3 홿r8EW\b򣲎6@ mKOY%J;g8U~[I* ,$  T;"n& 9 hQfH F򓸚pczuP5b|)'58{-O J7qy(d7A0=. K*H߅{q-£; r`2mN2*ycM+: 2d\XU`@ ʀgUg(97 BZv!: 737wg- #5SptʅDօ*tX$a| xu=W(fEqGjX`΄askS ҂ ][ׁ~Kw\?˨i L 7~ FE*ep1aV~ ++ 2 Y a$IxT WJ R < 8C!0' O  %=;Qg<HwЯ {Y$qvdΐL>w,Lwgp'c) <<\Hۏ9vU C \VE!*HfzǨ5?Z\mrR!ToWa'\IVS%}etLمNzˌS+C\0찜ꍲ#CPZJ}<y`fˀ9Dg+RJfpr}Mf} N3`x&Nh,I!z)# t*nn L ^偱 w ?C x '6 \)Y }:,y f~gqv>ZO^ bT)h @<(_:N&"TQDo(yR9xʹ.v)9rUۥ=6\>>'3 0M }uO#Jd/sh9gely,%' ]a Y3 ` >' ; f % r^ } APMzmڊ5=&|wɥnUhYGhw. f k T Dr%>p+.B?BZeruAED Y K9&l-8EТ3zlV  )mO D ʙ Ш +T a Z q  N  uɈn7ElWqK dm C5,kcCh ò s k << A ؤ]|9;|{Hӫ'üߒ Dh)o`Mw09^gO;2M 49WLϽ)0ZvGW  p>f̕'q /Ph5z8Pa{ Ljfz%LD5$K, tN9@nEY4sH htG( .]V#8Bݑr/uIp3QLph9c(UˆF^;lOz,>W cp&x^^]w3_w$Tm$5/nw?ye.+ Ģ5]AIdGNMN< Y!>h^=q_ fi;^t"נIprt-3PsGtJ/s)ﮌRkt#,aax)HA%cL+V( 8d#vV߭|ߦ >"c_qqA&gbK0C[=f=?kp>d.S\g1tᆨ-7ܪuG@l7  _ߧ]/)ueC``xLكKD:,ӹE7pM֑-ej~Y}Uޮz~X#nI1X$xM·#]޲F$3"^Q I+zsF({> %DiY:GCULc]0` 8OxUG|Y5^48q)fZ\j LD3ZWQ%zV .LQʋXGv1[Cf #SBHmLG I D O K :}e9΢kY^$}UNwMmRt/ l=7sW xyA I%ԯ BG d5J6r X/ u5a(ENrBuk7rZJJ R{k] 5W'rN!k"HG#,i"] s.S(oQ9U Pf j (w el [¼ r 4 vGjXhk SL!ufcIpH,F9Npf F $K _ * F qi :p R 0G Ei$ ` ୺ z 6 t /Gy K5ļL_LwS =t;r?W_{MbO`p S3;@R&ۏyź5E!C#X%w&''c'rj\&$" NqcQUY rZwkX8!άKfk(='k))i}3?s 5x>@p k< * ˌh9%͸<tu%\LZU4|6:J;YF% ՓSR.ޮ,M# !X !G$ RmN?v?dRS0VP1^#_CzZ\"4(ǛV_6Ui p  }v;:.4ELŒ{A) j$; /6Mey/ZCL  } /( \ 1V M? vQUn s^G((ב 4n>O%rm- DЛ3 C<ã rh sf{*l;4&@."^']`s)gY`[Li@sRLp+|M񣔊IkLh5{$j@# UW^0 3]G뫹gѿq3_}pN*&PnQ5> z 4  EOr5]*  9oHZ 鲗 pi G96Qmј+VYP m@8eV/UZ5#nNJ蚗7]ߛT줭8ɖgNME^6u+A[a8j0q t)m! vbmC:D5J/l@MUa}rc!CQ5#*~rjZ,{K8]~! !^/Jb렰ض:u,12Iry 2cBMutvq> (QѴSX%0#!3. V7z<(=_L Hu {6b~{#SK31 Ly; Dyg7w]\0O;$G j ĞDkFm#o'?goYQl \W:@h ;S6sLھ%u[]#`]JSp^2Y-lmT?y.Iq4G $Me5*aO/:bp7ZQRU@-NI\B'_ j`2#4Nz;r M0x l ܵ C(Ĥ lF mM ZΎ؝}[I.$iQ^DDdIiUW_qW5{j W~EN{ $ouH.,O-:?v-n͇_mU͋9;J P@5"H+i/k O\#q0wvvWmvQNjI ڶS g (V& =f E M OO} BB z  !43DWȫRvղ>%gk)tQR L IC  J @^6k[CM,|"sc$?[<$END 8W l3Y+q@GwY!UDαMDg `{np q : }R0<,lV ;{`$|KZ=M < mn $s C?Vwg³@LAl|+~K z? jv =< 1 j ey Q,Rs.B% KC>$=]deBW') ,Y7%0_eZ ICΗ JWk_n! bYr; a sv Sg 3a ?i}=5mmҚBo ˱@Z'%fuomZ]~.i\o~vAo(ZQxlOVeXJXg4~PYk(i2:^sP]؁#%zM]˼>t`kD C  ܘ$SW=/Т#=k/L_W KM'_ yW&xD>b#SncoX; Ŷ扅< Z3t88j nG `ZB뛠Wf8Y癥\ۮT||sƴ/]ukLq9s|ze$6Gd45 <^eHQu<E.zgxS]u[{S%9DQ@Y~?H ԑ8};)&zxW sX>&&_A7 D܆7ڛqqQl:iڻܞߜQAȯ^ ːsSD;W;.t tigUMi:b/3b'Tm}1,.;%d!#s7^FgP f@g|a5wW ;=p0=bCuЌ=m-͞cP;j 'L](Vj^jDOea ;_":!t Gݭa]5JTۢ_^/]ێkey.B,&}4dF>J9HQpIvDhNܩC,(R~N[eY2[dxE0`l7^J>>pyuwXA_*XSƱ6iEd_X17j¸?PJ d٨ Ӡ Ɲ/ /  BA,_6VM+8!m>`\yiU !T S! JXu<5+XBw$#* m l K ]#! Ew>  E 3t^C5]5-6[D#\A G$@0tmyTK r,`BerAt)"C;t^{G Bl\MM$-r{[`}4g G t{ (O/ ; q s5)QlC8]\0 9 ա K{`C7 ` td1s1ܻmq] N 0# a`!v"I"[#yK$b$o#Z"Y!rxW|4Uqib?!_Y;Zɗ-ˍHe6^7rEcM m֪ ] + }vkt^L M{ $_evGp+x%w-입 -kӫ^&J" .?>i'pydp9FgI.T =|ha!pO'(LCiWsӿ~H+>1inwjD6H3qUYߐ/"+ rp"]E+ a|o3R..rgqE*n ? wO  B:*vL׋"e.U~ qi\4};@+ `V\9&@h4  QbY w x؜L/h.StpF"H.7J*ӖFBq#k ,? 6 4@V58ʿJ  ܂?qCKuR}X@ Sz !V ~ X y= d m :? {X ÕD!qďM@TXC& (;x.,Z_wuxp Ln f_ 3B G" P nz$uEJ™  Z˕5.e_YIӬ^W`h%"BiZX )r[&r1~W]z8 J('`&j> 1ȈVI2RH@] C.#.3ׯfN:IGL D( #H ;hp*t0PgzK8 V[bV|(2iy p2qdYO 84R_u{9jiQ660+F ,T < xz ^V F&B_ $s!|er fm(T`yT2 Q5:OUahdGH/~ʣۆ/j]P#P Y V 0 4&+\cl4%cec!fpag̪ګ knjds:cߑm+&Ծ2Aՙfw*LO-ʴL fyJ lBu M 3 l Cw  ,) /^y{@ak7Ϸ p3jYZ$ r] ] X b4bX\;-b/Qa7Xb`e9TK q"23 y = A 7 B cH F9 os Od2K`0$QB'sdNam?<T{ǮJ"S6"0\'mo v &Pq lb\ *F pmN r { * ct s ~|"Ip`Xi'w" HL PkU9K 8+XLL0GET1//z%#gˆ͑%" Ox ok 3 ~Fŵ2x<QfXlJP#7}bh` 鸶)eYV٨SI@<32ӕa0$/_37z)kQ ֥dW4 &x ?quwSO"her*5#1{i,݋-0Nw?jԁIm2xPDqlDt򖎕v{PaE32|d_| ?d4oe9.\U^w"ڔ : ф^g⩤I !W)TF 鋖s4J7$`Mr'H2Tqy7AVfI\#lz۳!)v,_NoqH9Fa^HYa1iYH+M8geh|Ҩ&3۝-%[7أfJ؟uz0ꘁ~\x#ahIg؈-D2wYX%҅CM E:d?AxTI@{,> Rk\ə:zPeB2#ښ{GV,fAnWYG>4WPA"Ax~oM<ݛ:w4&b̝Qf$66ǔdRms;!{r# hx;#xL2׻L cu 9 {  5*8KMb"LW*2.9Rt=å%e|eݣN4iln+1q&r=,3bCI%z_ty   q 4 j c%(P'n+Ӑ#8MtQq3Xei. 6y ;N - $ &K>F# F_]*X a][Ȟd^01b_;c;H6L H U /vouSrg~m8.fN2UAOLLz{R$^mPT|iF|}u?Ywmt6"~   L>% QS 5 }9Q V#KFۿ<;4aZ= H& T% gt{O':  QLÝ0iGS֥0҇UE-3"30nj! [Mz;co i8j5^)&9I_t3fv2Y ;L @K KuN*lHN"ku: R Jزx+ɦM݌X1w5_Le, zt4XI'nT$(U.S%.MV5wcS?q^VD-WC4|a[ ߏ 6uu=~!&3a xr \DF [KtT j:.y^a'G4P}Ɂn[_@fI&R< {ClHٽ{#*HZ%mL%kt-( wh5/U,%LOldA~%VՇE A `|G? fenrir-1.5.1/config/sound/default-wav/SpeechOn.wav000066400000000000000000002735201317357605400220660ustar00rootroot00000000000000RIFFHwWAVEfmt (  8qfact]datawOUY^S Ơ$5N'bH5<!H * a8G P>ci10/. (! 8 Mj/,}kPHaef'0 L ;^_5/Pu&|3E8`Z0_C~ RAՃ 6rFj0o1:Y8SzokW*w w `$ 5 o% #R*v{p0y-(ϸ&5*j,Upp&&#?3'<\'w+ӭU/^K.rZ'5v_}-9R&Um{1 zI ra1ÈԢQI"z^z蹝j.5 fAr qdHV 'zue`[Qbdl\ۯS; ZHb|m ! 6 o?4V> wU:C>5 W]Aߎ5,FZؽZkcGJ2 Y0ZfB. 9Cff搜sN+i{%XRFvȷ+3i,w⟼p&}t) #⻩]Jq|s횽B~Na"B*, 202{+\wPҡPbg鰘|JOO(ףۜ2 ~dǃ91k498x)zy1=3君 ȍ2VDT#/ v;A ⏩ܱZRv]ϑ6|de@[O<$.\r>*4E0>`V,!;g荨!ZĚ77(!K3B7z{엃ޢk7tD:91` [Vߤ'ë8ts\XWݟ[T % C(> BY};=[W(a&2FJ/g ,j+ٽLa@K`>98B:h RBh4_//nY1:R[m.}pg5 LSHB,1rJuBR(4/h2E"})iKHm gM M^b7᪓YZN!x`ix?EM1AwNA1S83c~iMx F :Jkxeҋ [ bK7E BfN,ec6. L! X\t. 'ydĉ ih{9=-"Ia[ejm\ۿ%t6PGwfp(%.Ҟ&${PTM.oP?lDԝ ͭ N:g. 1 N%,N&L/׻/,3npku禠ˈKGbr$5eqmw ?W FTø?x*K+ s"f8i #~t&QKU0r=kU [2 TSZ[\-)0^Gg!YC`UO_Zag7^fK. 3q   m1mX k Z_hH!*yRc"a>iy?e> ^ V 86\ι#i$AIJ\+5FC! 0q5ui<rj? T #Ψ al_#v:CtYM Ē(p .D~kDA9;"ɠ4 + d 8WR2Y, m 8; .JC ȀrRB8(-rYR "xjg 7>o ;/bT1$[@7o5vr &Wy,//N+()aU,)^$2#&26'C$K*h%.2M/+ߎ$+]$&lfPr|h\,G &-^ō ڍ t] :W s4u>cp!LF;0OĂH g B!:W#j Dp.}R} CBt F' OwU]y S MiygeZ.#^qr8n0U`ACikAIitbln+2?Y0@ZMdZӏ S BCg0]2H&!Bn]Atk05_z֠;TJ: [Ҡ[l)^"(*޻j䙂D5\*<+f΀" ܝZ'/2gu4SrA\IBU[逗a$F 0}6@DֿF|W )*/DUH"fb\ ]ϣ:ō縷SD pN2.׎wۂgAKLf ^ 'ٴ(τ!bw3xW&gi=#t՘42+T uk PR.V @׍ 鋁SXF6>Jkc~ނ -7 L,,פӡՊM;Cڪ۞YOcwcvnLӫZm!hY3~ %O8?rWm tiFWGW˙`Vj:p>VWݦr:X+bl4H ,eC )! V 1Lc$6t~N E >$ ^ Y nAx6u\}~=v9Hz C \"l81Fc 8. -I j)Y(nFUu|&uF0NK1{۳Y, V: <^t#"Gx%(HP-8 M-k)9*s>+W+'6T$%)'(.7d,{.eW-*iH( d5TVm< $Z+S < w % 4pΚqhfbQW c+gd[ F$H ? xR!Anb]%|UAK7"x~@nM> pBfV S( ) &X m̨XӅ 3\$/*cjhcÉ.B5lFQ(((OCOJ#DXWs@zG,Ykk<-"EK֌T֟gK{ڭeCUZ|6bHLfӅ}Gcq"q iVߛ,d`̒]B)g Өx_uzBb:m`pk|$Uk)X2]-i|zil 3hCdoM^$n_H<ŷ(h >C>sHi w\%:ԐCm;Y21fڮ75#ԝxaw-%;'5)jCO7y{ڏN :;J*N, pљ{}G;ON r;K q`.A?V/O}n/PMG:=U L2{fASsk DhOmoJbvkH~a Y[zaF,:|TnǮU 28O ~,8"8KQ0?r#S%I="F uIa(/{ 0 hZlmKd7:2@=+ {P =# aRP=M+_ut{E-  w 40 gCZa#T 8Fy&))ڵ`Pc;fe^ .L0${CpDpuOӿ}5g$A[eI-Tzt qװ q ,  9/ p<u}t!z[p\bT9v T,E|Ef<\*(=&6: 3 } EGZncWny[/g&3W|e{X } Y x 0ۂ-$! 9\v.fD% (Irl("(J*U*(V6%&6&C (Y)6,h,"*$)%)@ lA}+^8a $7iu F KcgԒ6,cB2!ZҲ1"=Zs-me4nDWqTZpI?|gB@^o\3)<3ue6+ ~ 2Iw /'153sDn0=@&se҇ ~y,P3ؚCzSv'b)8R?evP9jMLȫX_pG p 5UB&5 J o99EJl^`;S&7˸d,7aB9 _&g`Y8ꈜ2e` oE)F.yiY&qMCrRH[{Ak[lV+`术N|}vf7yMCRJX+WtČ!Z"<0sIDe#d_Iԇ I׆Htw^$G-_g\CSaN F@j󨇣{2'*;M<.uS &JKk%"rlSf͓u7hEk ~ o8T'C>UaC>wGx[sٰLmr.ݔuӟm[=`yҎ!z.n!Jq]Xe,;/4> *ӜU&+q>h<uZ?=XvO֋ ӿ{=~3v SEJVx<aA5/s.̊l>r~#:ZI-b,,ZI}m' xo ;(AXjY0Ve[D/JvM. ycGxlW_sV0/J "g`N $=Jsjfʬ4 u\A/w~1 was\0/p512R- @!C e&L*TեGV]poާSB j 0$I!?B^)f7*$Ow|vǹH-*7U^sTrl+.< s 6K#PP|!!jr#4x "oZ^R &r I, ] DO99[-~zX]bD9?>I2"yuIU]Zm3!? (wLGƱ"E hmgs0kauD8ٱ (v:t#'@`1a1\w/w"_OL5q+  DcQ@5` *9@; Yaף KRt{{]@.X4w@#z E>(<W.-S_0f9=DK  Ix1TYlTȾe-Wdл[ | Ay |-A%*x9*P KXnKEvcoX4_[>G 9eć44  tXFlN4՘X*&)nH$Y} cs <duHWv:3 1 dL0AZY8߉1+2d@+w?z a'  H FL o&bMV LWX$m#A!!$\o$#|#麬)j,P0~:6C%9S"e8g3+G^$W_\&j )T(#?"cZ!$j+,O$}!7 @]IS ﱾ-h~?d$2MkOh)C8G+|;Hz2nO_t$3G %E5q-QAv^h!e&hu.pK` weƝٞ'!FU4nѴjS4C}f?gCB|\ r$ &S%$%ϻ'T$8&W*.K/%L!^z9- D 8N  B Hsա^  V, Gֈ J 7 pe?3I| ö{肀 K # cϮ6u { .-` % NX:$ɡ)bLM6l%5795 ;#\ P%:&4 L% o f  ݣ caxG XPb{]d}6y*3y!1ۿ[xc[U) o)?*!ky}$o玢ߐxۍ4fܦvM ꊉ*뢂 wS:h-ߍݑ Xc. uS[:W-%P&VD[3 r<,8ngmA1G:L:^L so%bE$d)m|3FE|RT`I'3/!74&3ȋ.) E5x A&J(i*&"q5Z9fOi ' .i  %փ6  ] \4z$- 鞫m lp,唘8z+gAS`>ǩ~k@#C7lJbXɲ e ة`Y1855Ъ1nG!ׁf1f+0wVuc 0G{:z'Sg-.+* * ([d'wO)XZ( #Y?~ሮ'Q;S(7!HԻAKLeh+O{ raFFR\?vsb}'$De:jW4xrL)^uhR$+lVgu8Z:kJsM"|?Θ"S:#ׅ< g͙D/}۞lT;N!Ҹp:&拗1wm.wTr2ѫ} [QAv /=5IzMvwr>[lߌf<a &P[a`GQPnG540 0|Rx2A`UJ, T ahs @3BÎ h<}'U5_jaZlHt4i((~So|P*% )&}^p1DT.l~;i3h]*ˆ 2`|gq]bGB! +m- `ya\ٴE_Z v yH{<ͮ $х+fK-+b"&>#p$D $&"1'9*],X 'R"!_ $z DOPMr7Q efMKAYYt6g&H'p&"&1@((1~9o:%̘:75o2.0P4س6=n6%-$&,e&#S<\D`>p='58'B> d:P2؍ŏdEFqgE9x !QwA3 S^-Zaj)u-`$WZjZvfa, p7BO-R Rf V~gŽrM#8H$$O$`U%!%#ƺ2!]Y#), 1 7_:9f]8J$6x#2=U0\20b ,5M)?**f){V#b].-N_ a+)ywRC;tydouq#]?OKܧDky.6WWhXr͔ SӎzRGʑDsMF)KF 7h ~$*8@|#`5aO4pJg"  -h'Im=QDLO0sH(O(CBʳ 7V֮լ _Nؚ۫ݸ꺁5z_)VwL}):ܑyPڀ.C ܺfMN u. 1h㩾*鄚2)>¦Y1FV]0,ݡ$M/P% ѫM ][ʽTa1Y8 KU.;nҿSRU cޑ[Cʕ5xEb҃!:Mo3vׇʈZaIPOӃ4:Eۺ_Τ<Ƙiܻ)oe H}Gj   X_no/*CZ2GerO쁱셲|AJ17 60:T-s3W`͈M~4'P?Ԡz7 ^낎,Ic{{ Sƍ#-e,\R!dSG[G▙{摪jaEM  )fB f@F//8Uk ;=;Bmذn3DޘF| bZ2 tB |"8#:a!Ra#~/%Nv%N#.EQ~m 8т0xA+C<LU1P&he5Xo$\~.lv.FC> KªXGui,H$®"n(+<)_#lSwf_ RM$h"dIt(j(cT] vTIuŨ z *i0B vC 脀}]b&@ v1H _V/cBV恑ŷݔ7=Yφ$+ A(* V טSZWZ(a N:u7x"q$$c$kB(!-.0 P32Ȱ3< 0]@+Vy)*׬,0*ϓ&*&I*/?,ˢ*n$ . $  9= 9 ~B^܃>l7l=ϢlcCiSgUX H[N*]=(@ik3$ l;)v9'H?N x4yX +g +1`h%-j5B^U$ӹ } q ;?;u* ; #Cz&+(Ʋ)3A(˃!%g % kh   Q ( LFl tO rW mm F " | {\y ;O ? */ Ea~S k>bz1Kh <7' tQP#KXyk cwg֍SzVFT~~ڒ׍ޫSBrcW!Ց䒑 ԰6wy[iح$u\YᾘW(ͨMn 5nYXXyZMe A|4 F2} S g g=` S:oiu*7c -Yv sH #?ø^ @ TA jCbZ 4\K* Rˮ(KqF$A NyiaF+:@ NKѢ2ХxJB^;,{1ሆx(͌}d0=ݸ㎅G)@H-v2Kd; tl@d#vxSH?E}Y-髵 ZuNOJ6Ao TTw*,#Z141]W%Ey#WqxjE+-!g&&d%tAC~zL۫j;0tBH1su `q=eUL%2<lL m iWJ ; *3j,)5S5yY.9oV="*T~ _ Ps G`t^nD-X(C)1l8w]ܵ׳&5]s]쮔F;pVA,t[vbsrB5yu//<@F=fue!S$OU1<~W)aO(#KASRSM]d (, K(V1`AwkNho.ܼ=b,[Ҟ"|t-g>r9 nSqVY tqH2 PM W{ Z_R^H}w0V52 0 &i%5n#aPN"G(+hKR+<:e5%x1", f8P]9dhZ22A+1#5i,ϼ-FZSJ*G镘 gaYQD`eiqT.EP K4zi`<'Sg}/4Qnb 38d$r:˸Q{% |μZc:.{ yH 'U>.  ?lW îh; 5tуOZ `L 5>{3zro(ҳǫEƀ`υ~l2r֫!+\azI?+7j0Up-Vhp&Ϊ ͻ҂J[ϔd%U)H߃ _Gc]m4po+dchfH,UetE1ƽk0 ۣ[[vMyw@, y>`҃-8Q!jib&x=vp)B[ks_ޮMIh)/ML8ӓ)ѹ2oYԢqݹ8DU炗4an3^|%_#W /Y/ %аl>:l jj;N i[s0Y4<- ig97A gJ!8EQ+[c@e"//`W+堼 hE.w~EpHVt4~K^$ AlLGoN A}C䜬H:yw  7VsޚD2!9!)o.g#O7h'4(R,w;p;8 Tyl}a\NJa]/2[ 8LETGW'=ƤOx_ $Q>H*0?25n1/Čh/ ґ14g+1v*40cŐ7q+X8j:e=R%?=SW7< d/PQM0+4f,!+&ӲK%": #;մ a 89[ ]m Y:&8_  ޥ)Zn$$\$)L,;+o? X 3!|7L_ Ox:_[`k2{5Y )5 G Pa3?FL!qusw# Y͵NRZBIm~Xh_~H[!?J/SA!)] VA$"\b|$B!4!# d&$'Z ,u)-wLpukژkI|~7%n_[ ģ0 U-7 )cfJzVw\%ȽdG=3cMkW)1Ioc#RGE%̾77fIO)*(GajnǴ];If&br|4يNE舅b5bwޫ^nR# =e,JE굠4ۑۏ[`S韤ݿg*K0{m. 8!W82A*;@2SxZ;I߈[g^FXݧ3_gCK+zbA2 +L6Hes;FQA MW80Kh m)uj$2й`Wuj  >y ^ߤJUvNƋ25˹CDQ0򊍷B/=GF9pV] ' ]qbNQ>#NXuhRa#,Rqh:~0_0D?hjUJٰ)y~ o [; X [&Nd;09( ?j[w; {Vu=c]V*gY` @x(bs16A!BੂW ?ퟔX4 os}0|TQYLL@TÌs袑F4ʃy0e#R#HES|/vE&|8,)՝ Pˈ]!"ƬNўֳ+97#JqU/'Q0oǪhXgBWR i 6Z8qn ɉ'aB . ՚|NMr+Q&.H\dT剄PܯSRl=*r@)V,_Փ d- >?џQcWqzK -  st(1v Kgi$QUJE#fJu+9=sNh7Wv pkL g,߆9.e# UĀOP|[f}o xPW'b / FitRn:+~<e!ܫA3! >. }vzlzELfZ4 -7LmFç . Pq*187a(' M+ N%s5֧ kuA #vT/FE8c3[J" NM}+uNVS ]͎t:M=.&8)T,nհ%!XL $T20t؅\J5- , PEL$| d &=l[,%^"#;TFY+ .!$LYsY>]@r\ . Y4H4O^J  i?[JjI8quu~G n bȷ  {$Y-[}1/#>(c.I&{1 @(7T0%%&z\-)1Ag57V8v'5 +j(M)M#S 7$uNT D n%[}ƒ$cKCI<5 ؐQɎlr_} : ?Pwq}5}J]@̋a-^s\WEu} ze 6GNQnfgp&l Cu  ^Ks& A m_Kz.8W dt a3~4# ?X=i Ҟ ̄&\b>O7ѠݵfރO rJ^RXq?b}7(߭܇ן~֝/ٻcpզ4܇%bib~ڡv`!oq#Bc1 {(X7ަ>n* _ݖ*ͧNt\3UŠcض#8t>fv{ DzxmB%xilJynKO > ZѯS-8 l$hKjuUH *lM VB$~ \*En6fʿAu(J=`L&-+ ,$8ȴ Ep [F%)v%à/*`Ô /v ѹ o$!:f9bp1 8NyKbjh>V#5~%>$ jN\8$K&BhuxR ES4d 9'ڞ\W t Vh(^x~}.8RfFS aз5n )r*b'&9ѓ)gG.^H.J+(`F+o-!2DX8A;m[: m61.jU1Dһ3z.{%(-s$8 ֘ҒJqO?t7%diռ7+t(o;3ޣ+L~Yr'z][M,jYd`Rc_z`O(.oKoeG:q FK DKcŦ39"<&wVseӗjrkĸۜK<L#6er`vLn-'Y'O]J>?XyDF69yOPgŸsWyx UD|\;+vt$8E" [l4t@ tRV4WYaEtce]Fgp["T$ARYn4K 5jPv.2G %!:レ1t*C|2[X29aKY(wY`,A)j{jX{AKo<'3Z̫;2's ~DD%6R&?.5590- g;%(Ez </ < Hg & < 6 n %np Uڄ&r>q  2$`; /G@F}v.Y.<44|/(B{aB'Q Y:{x*Fs숎_8o~30 O?)\ xWm 8QM%H>* W ^h@+[p u %L,~_a$ƴ~Jg%w(A4k""`˭/1[?^.ϱdI@jtlae_YJM  ?! D  ;`@.:zSTA&4u Cky.w-A}% Hh^ܟPUo_|!߭v[ݕ }_{ߥT 誑ih[]5ګJT chbM 0NR2P ʜ ~ot 8BrrU ?24D9$ZVY>e["(Jz*Ad&* +@a gQ  \DT5SJ\g|m'z **Y$|=y7DFWD@_KeݳScXo["a0kjye v?&zpqI 2D Yj "=6Yat[MΫmL]㲱 :Y`1JvMFSv>&VBA8<7)X'i&Re)2+BMp<l -NtaE;緍c.}>EK:mCz&sQ 'cSeca*mwѣ6H^'+LUBXLtY>XP'ؘW2VJ6vVGbmzEMciLYHH(~@ԗ'@tH󻒤##A|Od _j& D u (x  _( aq T8(O}+=U{:T4tp:u8щ (sPv´3E!E 7 )\( iKf$ ϠrmB3 S Į3 2yĬ ۵~r= '2?f+W5x |gѹQ M -oϦIm{  ";!Pg = U۝ JMkEx "~ -\ (oq%yB h+ E#%V0s4b]8H܊UKD):? ƂT =k QډYtouM)a`Ԇx G8e KgR S>DK* 3pe ]VsJg1%i x1 r f Gŋ%}SvEӣ^ ` 4y(1C{ 8sp}a?⧦ 4 6_ 00 eÂrZ -S/~y : }?Tt| y bztz}`JDOPXr%)|Dg~<'tbf1M7X  PJ\5E#:,w{;L^# j$wvo~fY$i AQ: Fv7f+)vDft} ZOYECnVf䎞Iד!@e?tV<  Jڡ1܄R):g!:p.wcౕ-:ΩO$_,}xJd$Z @+n +/0i+Z񣚠6ZN߸t&Ph%E3>IVkEGttٌKm ӣsE֪ӻwIOF'`3)b{_53=Afsדr>o޵/mPcTbƷȦ 'o5,HE0y˲+lW\Ŀ lyϯ:Goi>kߩ$wsZe4}tc#C=|e[gؚE 6ѷd=K4=qݹjo@qk.ߞw "\ӮGU,MhwE\D̷lUA 2'}VM؞5+A/qw|ށq4;|hr%{2Qz`޻ 9z mͬ6D!.Yכg7A+_%^OF < [L\d3W?{<;M`0< D Ud.rVqn@]%_Px}>jЕ@*I'#1p_|JPuo5^t IZb̆k Fg7PA绥 iZ\AM*7c% Ӈ+BNk osX^ Jt2{xDоq!yZ/c[Yx:!dwoEP*/V[K)뺶, "5c]&/sn (kXɕzMzpY6JX1et|'EUqFSֽ*̀qUZu>FrU*%燫@S۔ʎ̲ ?Mz |'C'Qn8:%:TB8' >rE Xt+WP/[IF@ =XG{Ҡ%0 B15"3_(l1u J{32"MT(])+{&g\~*ܜ~“(H)Q'8fMVj V Wz a@A,m߯KDc윓dv &t3۳?T7V oB육; Q)uu2?Az*FU5nɝϟ[F^9oirQbs(a#? O:{Z)iZ) ΰ0$#Y@*ܴw*S٥yiLB\ b26@bמ,T1mc˴ (eC\ŬWރ~DuI 1kS^{稹I.7W"`H9뚱K5Y5= fp;ijH B^%K-6y >,h˓X!>讌$ EdN{Vr[ 퇽y/,5L5a1Q7_w|I 8w%9hit&+34UpEDPL99FUD> ˆ7p.*HKv(? r %Jb||B D< Hͽ|%0ف]Ό@ 8/ ?zI ù`  P ėIO\2#[1y Cwm8 g%m4d3D!;''.3dž.$c):Q#(IeSRK~ZlB9F ΃mݞag4z"ba), W''9G+" $uP%͢\^ƳI Wi`%Lͬ yPd|iT*qM4;Xl٠Ow:DX1,5-̐sVrHg2 dOE}TU8 K8B H,~+D_WZ!a!l}5mYڭrj('v+ݔMZݸfA`1D\V>{0MQ ]lC +Rn{4j&)@,DHpe\V ~_ȚwN& ^')n])SHBFNDto-ФmP@s`E>kI@ga 8!=17 gcyth384Fy!ݳb7`~O_1! ?._ lX-7M}23pp^uGÕHnDJQ @s" B IiDq}DW b U$)!y"d "oW/ u FjF{4|U w)*yW 9 n#_%TI{6~pHxX~l( .GJ3#t7ip52O-'(#- $"i"OcDmz~YƤ:B > " w%.pY(gS9 *t# ,#R:)S;2Y/!/w.)#{!Lbks>5Ԓ jOхvm+/V< .BI:~T!3՝Qz1fCO P jRЪkҁw&̣JG+%GW\ik!vZ:GQq 1|t AQ %TLz$:6,+:D!  m Bͅ= H 2"%&.&+LC*3)`$^U~"@*{@M: O((-\+ڋPհ* 1/Uy. l> k ϵ(16R CDiMs5 n<{ӷhWYNmQ~;%5Bd3!7 .D ȼ)?4\ӿ og!D  X@ ګ)= ᡫ 7Xn/yzJy& / >m V\?ĕɑ {hr~}ע#n rC`yU m^9=O@21t+- +u*P<  ϹV )QLd$cD=ƽb 5%_ĸUR;#u4a=+LC8S85v+NE8i\@ { Eՙ@U Fc* [ "~ `RZ8}񑭕CnQBDPjQ@0'ck/ (7.u%بKquCğ _ߚ'?+' ''t)Ac*D)aO"6#Gg*h[%lVNRqs fQ;S )3Ь;̔?n>x9;t95F<}M>{:DC4t5ۆ<9D,LyUbXN{ETxxJBd{@mCD@c 6--g>/'ՕVRxF(f$II/u^99;e9+}$Ŝ/eX im{3 [>$#UB4֞sD  Ehj>I.6̝eD N3詡?_OGQ-Xr\>!xq#F7ac#^ٕucra$j (W >YSc 9 r{<55>'M7,=:8w5g:S*{wkJ*&EEm %"G(NԮS +1@ہE5 + 7R!ab]C2E@{& \Kx(iY  W]   s, pCAh `uj[sq#B~aN @JzzDcAߍF&j؏? ڽ|덈qd0mjU2fq)a\Dm.Ӆ@'LXQ*[9wҔo'Cѫ mWaȿRQ"6ܤ56lٱ_ʊ LΛQE(b/c/'A T9!R!_N/!)j',D1 6%3w+!dͦrJMxv9&w>2P Z;52OM>OG3*"'n)@ wU1qi^bU7G jå4-S E)(c_ [)N(蔽UM 36_WH7(1~  @xg2xmcWݲ 1/Q|Lb)4p#?8@fb)(U>ԐlN$zZ㪻wPRp6J?ts BZ$  K<;P DՂ[" yB@Yٛ>25E'WS ί >!С񐐐 dW_K')1zFBaX> -bY-{J 4 m ;u:v1}VMzz:\c\ 6yFY~l*}p|.4CF|J AWx,>$''B%H!Et ( ^  )%vl#> kfH BVXrjm"/l}:aNׁu ѭ`rZ쳯=5e2eIT]Cu#)!쁡ܔղrenpа  K7USsD[3\ɟƕU%otpI# S5"IuU<mz[?eQqOoe\ YFZe'}FڍYn'۾ 9ƀ p fKoO XyKllK vnWD ! f բDZY ]hչ^=hOH+w宅7sN{\6h@!JAA2 MI YGN&  s-v?ڸkq!3e"b:#ȷ$$Q& $> N?t.W!i [] + G 9S["h$h ]R}N7Fg6@-*!笯#$$v!U0‹ 'u _"=",Na%%4d!\B^A2;7v'R}R>2;鼓!]#L5)_)؅%! 1 ɗA a2H w mC Dc:R nӌ[˰߭oYqAѧŮq.qeOVυ̪n]x pw^ K~:tFqlP?1$U  .S  ҫ7 Y%#jFVCцH,on{CCU @sځ]9&MXn5A$'f*k:29D yFTK%A4C|'q-i 1c:'&i"xgћ)Fh- .;OM<(R`T&*64|0^ 1CD@R)w엨29w|9+eX9vc v</u@Gl n? Rwd ކ}˦=i+rgDE2~0g9<vS׺4~O OJ" ճMnT?t- !ԁO* U,ŵ2(d\hp  =Sz$ tDB u%DRw D}^V5:&`U$lu<0 \%paXiZ7 }5aﶶ3\`X _"C <`n6YݰvFj6օ=&ЎƳ>JxB({L(H5#`ZAoG~Nߩ~['ϻzȰvε3—lʈP8Ĝ dbק-}V_ҬZ螭iXM`^\3!ݷ{"*B`^ z.u/h礘?=o{svTKjlɅ~?)aw\͏[7J٨LV{?DQ<޽:sE?PTJQ3]2f!=m =044 /A(+&#NQP(i-=/.C"Ͱ\  g20z 73qD>sH6<}, 3[} .*Ar! ^#̤ +Hs\u43/ A iep#e#vD@J#먣TiӲEVӒ&Y߄EOu:$ԣIC 9_cg#&-j ܔ@ .kx8+[9#5h&y@Tq+8JƝGX_;Bs[tdFDG#| JvU  *fx $:0v (SkCS O+vvC5 }2G4i4i,i}N %~_8'EÇH pn Q;gk| o ]Q=9x2= G%/ 3 YvF \L%E b!,!?l|r]Ukfp3 >|G8NKH5@v )y c` ӂ-d 7LL$Q޽ټdal ~p!R_'܆!~}+G)j")a {2k =W ^rB&}(n:TDLhdO1B1>BJ}?^@4 :ӷM%UGb2~>*<ѕ e.N9`a>rvWWԡK)jK5-VKަ~鎕}T~ 2-e⧗O9 JT{*=Ј@;[B1<"Z?y^RE^'#/( d? TCI1>VDq;K֞Q* W1 v{DGCWBْ?}$~ :\ hq֠f jDE{%i n'ibsmja;q`Fޣ&n<{s 硬 GNr|  NE 8bh^o}^z :<TBq^=z#aez`[*^:}9Uw\B5^5 >{\ϧc5R<~s+[Y)fۭzZ)ɾ) nzA8c|'3'/+NFFR+?PoH(0Q҂r_gd77 "Rܟo ' 8 1*Med] " 7F\ A)Y5|sy- ~S zN~v>WՉr'. gFj*q),+-31s*%ȇxj}' KKKA ^* 5NKT u *^eG$iY'zXgh (ҝᑬ?# 'j$H3 +L9ęFd Ws{ yɡg@]H 9k!yZ\Jmw5% 6W#{& ,.s!M.{O b&>ACb̈^ɟY qoq"f1>`*(J="/8J5I`"y?}wiZm0׼Fr%&k!hm)`. )gK`a b p +Wǫ (| GM m I R !B(n>({%+cD_:%,2AK:+ [Ns ;d}+WB7KLD[gJ,I%SER@usDV|H1!MiDp04k"~)Vb/|hh195Q{9 Jr]x%=+45vU ܸlEU e-NA]Bս)Qi])~8g>KOCbpugq1G!o : )Ns=T]iVZH ,䉺rލl @ DzK΀ ~`֋9|߼73"=w=k% 1*&rh eH,0N6@ Dl >CM6^Yemuf$v7l(ŤSO=[ʉ rʎe~amNXnMQ2 Br!v~ &4)"o+\؟}Il0C @d{xմ }I>\Ի.vҩקnKw`wxhfVcY̘rάVlQv 4YQۡ ))Ә=k-\4̲Eq%-'}ώޅ-D-vJdr ~ Dí騗 T-,J\a!ǙaϘ:DDlzFH=O)6ށ<؊c;C~P-ӳv a½[ѣILF.砶5[x!{S p2 $4P0^uHTZy^ X<L41IF$ Q%_ Y [`a$>dx쥼njՑ@GLXVv#oz |" e e#UyخXܤ [% ;ήbZ[yC#/A 픧\c Bj % CT7(2V(s> y3|8 1')ڗ&r#W!."E%GglH6P >W*f E_"(+I[*)6HP"S^;y.="đ + Hy䎎_6փv߉!M*L?,[;@1$eŶڴ{O&+ӼAz)Nx4 iLlѶߤPw.Joukud #-܍VNkZ#6^ǧYPɔ|ˮAxcWE\As 3[N" hb 'W є" [Ut~{OI1$fk" bH :Ng% lBщ +XhkÖSm!CI72E hx\o9MT1K`6\H^k`Pd($t*Rʽ]X `IԌa?1tBX rG G6:Gc ޘ ]"_S 6ʺrxToa>mKnM^+Tq Ҧ =VGV3."eڼ xei` dTi *ɠlMz4#p7ՌS02> `zu*8;4ϡ٭Q߭Ii &3w՟$x&M+GڄcxsٰA;?]zRpYƈ.ˉ/G\.OcI>O2VIԎ. QUȒņKϻ|ke+9I.=w""A7G#mP &*O+m@/Є"ś͑cbauX8aىʈ&ZZ+ﮒ`XfL^09PthX0KevQ~4)&襥zWq"9qiBMILཱྀc> w l_sUGEMy4|z30fʱ&+̞*sѯ E[e. nPQd@X`ҶSI{iG{WPO/tM'_TmuSDO:Ac̈́$kS-vה\zG ͪ &  Y PM {1iYybypf4LDע;yQRUze;4K&kP-Nr7'gk=uQJޝ&3-3(OP,R4/!^:+B'D(:&,( 5jD$;Ձ/Q&v% -/,i5A0$Nd={"96#1N=]KC4:2,O$Ox9SGb]H!*0,+$p?3H^?zA~ɐ>1IY JxGIO꣙LkK,RCzn=! y@pB3gLYJP= ZiG7H3Y ݩ š…M{eZ_0LsTp8KyA^38rB?i3Ю ' u.֔ C$$E$Tx z xZeWZsq(Y-N!CL KIݙ}kv@ =__  &:T&^$Y4VbqY$>Ґ)=_9x+~*P%eX;]^/\ Jq~l]>l9esŠ)ޖ{ xbz>; U Ϯ ͟^ BhlsNX vŵgJZxۙ?3 }7(HוAlJU`9Foumxƚ39K-(̫t?_ + y)%-FL/Q6\=S00;|YWeWIk!jrt%ZK$G\jà/U#T_h#_#W#jԇrTuLcZI!A̽OXRvxޛ )ջZQopo箜r& ?w(lGJvE, $g\̯zW&hE\YlFv*a2,U =r!8 b^R0 AҶ>܉"~?Td _Qa|nBaRy 0婥R0v qN=6u["zﺔ/N-P]dna4T&~&] t'⏅Yo y@+WA.]@< lNWz㛠nT1^AhWvK g LK`cɠP4  h cHs]_ X (/DUlP(!XWv~Jc: Z1uOXٿ9dD! *RH:V #&Si+Ii:, ""$C"̋n!<?Eu&R &hk\T/Zҵ_,b0'mDs'(mޣN߭`[bnLԼljα;; ᅜCd10ѩZV&%k:K孄G!԰z%RDԥFۃ nm-l6 l8 vbHuC(h2]m"3D WJP[M1iDAn@ih @0HSuz"Vݖ0almZmo ٽ?^#?v7 eÂ(#R4*OsPਜ਼ +R>zl^ < n a/Lzszl(VԦx gP ;ݕqSU||lҘ{m:RoO'Acc*4K1Q 1= BUf(4$\3< # +|`dӿ@SMa'-"_&czQ8 c?.)я"K+"ru$xll2"D%> *ˤQ򗈶lexՎ-2`# Xu_9&-SQI ?e;v zN s`CO伓:.!IqnMnL,]p̧ " ɯw4DJ  'R/ 6>4 LDmb Ar.BLhBE86zY.M'"H ؤ.$3)*$"%VMbr ;q`= {$-f LF햑ֳ4NuUP ;cF+/Q A7nkW bU @yC-= QXOyȡ''*ױ% \qV32g /])  1;m 倷 s, r eIb &e" RL i`ga@"u'Lh) #[>QID/-qVUZ= QM7"KU\=cy\`V0\1Haz&$7*=f?8%5e>oۖBœdāٙ&Tۯ>ۥCGQ9ƶvqjK6zs% ږH/86 ; Yvvcr$ p ll(~<x)LKӺڦMˀ/7 bME%;s怸,S1͙Q)O̤ݽ؊5Q۫Ղ0np<#C̙^] g"d~2ݚ(5W|w.&ֆ }Zc@?4~HM/Ph׺q\T2ee-{ROkin9-,y4Ǹ;BSyfw?'ד ܻsC]!ũ+qetK&/)&|`:u{ b6<TUwձX䑪P+C;vR<54 8{ϸVUT![Kh7#N~C9?K&6 e Dw%-<$}3y@y"PÈLC4ӃY 0oKl 28 K3qn pA :x>,Ty'm// 2r}<㎠=L 7hN3(5,8V5D2Z^:C=2%~%!!" ,)S-Ɔ)p,!BG4|%_ ("Iϴ8 _ J2z*ʂv2 2-4,A&\v'kG03z:2I:i0"$G%݈,.{.^@E1v;>;V?[@y@Zt>R3ڇy §::Ӗ$R<&E:HB4o.9|B1W6A.g[+ܡt&,L=OdYf]iury}SF:no72%s @3 _y ;a* 󱷠V (2g5 kژww w'ܪ`jܝ>ۙ E_:S>V+x~DyOr@m&ZQVj>T- EP2 8F+8cYYˢ){Q1,'dr8|8 w񖏐 -={v%kjN@*Kp܇-b8 - "\ڹ"Q t=!I!D" x۳ zO ~䧠 B:fV"FH" ]TQmY d N, k2{ ~2)]#2u795P,GxS` 3f OnGBPQIk J)h֩I>x V<-.Fi$P 7@aR,B뿠4C=5Eldh p  $O)MR;mQ+<*֟ :" >2so" lMh,)3XT], o:wZ+iKՃVg!#!o66_8Z y؇Z>m4l5܎f}o_juL;- Uú#lE#=x^Oƍ|F5~/K *fͻ13tu~wb%QY5 "Q Է sNE JrS,,LAfl4J*%&i:s[c y/O] ,gy{go}4.+֪ޛ~n_zhɮ5~-bafLdր 2gy6sf"K-!q1gˆފq*@:z!d2z%laZ(,:òz{l W o 6\u;cs]bհCTA{hX)&9_ N5*c m.1vMT,l)i)*OZg$s "-L])~"Gc(y$<^[3 # e?;m*+_u:븥1S)7L^ -$)2m,1%2=f5B)t3;4:9QEýBMFD?OI>pi5+ӝ,(h%$}RMS\f ߴ:tt# V-g lUJ:n @i),"-kR9 32^ЫM-I؋'>߮*g,[# rcu z<ol KבM'co70lȆ}K0/وьSؑ1amr^2Tmi㞢Kݬ֜@ AB)vM$ qRbY0_o tԜ"W7W)¢ٖNT$0H[JΌkԹAȪR[췳zV)&qY g+ov ʓ  [ۿ" dz5 8Wfq>s{@`o!kQXJD( Z1 Ǡ( gIaò+91N]5AG Oɗ !!&rύ E$ =ןm0<3) ՟U&|<+x-+n #.y?rKkj QZ-0 GAw.)iVB괔m p  q7*-[qogl_g-=3wk1/@ixCX2q>z;Fzhiw.xD!>o۾(E1 _iZЉO& rIX<(,fN  VFVv71{+I)^$)r@QX 5a`)EBvڷ \шF$RIAI `rRBʩw1vVGF86ߟ̿m" {GBQDyE X] S zq@n ӟjTQ 5Ni|/f | Ex )Q8`c e8^3O' (Oq%Jw.~TAvPcl"CP!wI*9Uj/\Khm}-XM7¤[&6Urc 髏Y8KN*h.B%+ lW? S*y0 1 t tȭ eE O  `B.~Bp ޻?A=sBGT rG C!- =uCl <,, ۆQ!\)^3@=߶A?;&;]7W-8#UHAmu$S&(%[ :$*#@J7e"mtN9Rx:NPt73 S/wCξJx TLl o |S IgH  Ś oq'Vc!qN"-~g #pm" tY3? -w c [S 8T4>_j"%yN)p.)c"}*1" es&S$`xiU0Fhg#~PH0G]Ӣ"lh妟[Kb:Ia<! L1 dN ysu!نګ7 qˁbԯn׵)n3oo=7Ռ>Q*դ+11רpJ6ݍ~ 7RSF#C3jd֓ l q94 R1Pnn ߊحZ΅І )O3_-;>j4$Pw̩(2UeЀiWfɥ$1#߱<htRA+St06 JyY>K^};- %t~>aXL*^G|){,VH(* m_V&Z ¼[gg/*'UoY%󂾆=(@&f':!Zw߼-r?t5,_"irдtVٰ ẺzF0R<Լ23J6!%)Ҁ3\߯9bmݫMCm``}mj{Ip< &SP1]j^=w"lHt]&1?d4&t2CC#|6$^%гp=cr,`C%s iJ л9Y?;h|_ ?۝/L?Kޒbȑ%$|%*0_4M1Htc+'' I'&ʂ')qu(YV< mkk=#Y ).)JQ -| op/ e?^a`@+"= "Eg.6W(a5mo.0%?Z{l _~ G{$; f!Z20/#*;@W+˔?+i-D,Y,B.T}- 9#)=!dsu Wo  ˠ(*&y{,$!g,5>3n)/TKzh8ٽmy ptw 4 <`8x< a  6( *$`65ICJuُ+$OSnz;Cwځ߀p׆-\4Y>N1 b&r8IQ^}"}=R>zA@ Y藓Z"!HK' 5Pv ŮUx7jVD)8p2y+;B? 0 D#JCm+$bYtv$u  CF N' R (ł^ȣbVƑ fCc4p  `b>!t{.WZFJ1x)(/cH.味 5} 9ʴ 0gOxt(J&W E;F+N|ĵmYW!t0(7 W b 45o:z 0 d{Vq ړ*nKOƣg"at7.#/PMC}WLI P9*%N)3O%kFjʽ[m$~=<!_庎|GZ&t=A~{uN^}f2 .M8KUz":a"C+;v<(}sO 2F)5R ^0^nZu (+\p$&1'!V^)L-k@-0%LFBd 9- [WHBL_Wz)A0a$#yR&5%.#M$R*GRo/z10j(1Ad6m3BmLN.Ns*E+7k`#ay%Ob`yʄ4FL.=Bô w_-]"5 >Q5hݸ% @ 3FWN|GRkQ~5e֪2fqZCrtX'Nbʇ݆*ea܏jd 2쌹斷OR;=4;:=ZWp=E@bc=R+p |-t\{& &\ M=ySljzP_ !O(4.9I ?(V"@#Oƺ MYG$3fm[\{_l@]J8x.%Z∊YO ,>}<`X о+MnBpHu᧽Tg⥑"094v_Ae5f1'`F5G=!GJ]wHOU $ F GY?Y eqȷBuhhvJ4 hz: 7qN(zv4Y:ԛ*(V7t VM\6뢘ﱃ 5Kǘ {x\ D ,< m%8!'"/(dC5 !K\uچFUIvW{8@2v5z|>)25PtKs)lh*7`3Ȕt J=Ǖa0*̝ӫ- (ݴ#.$eD.vTh* ivc}U[? A$M$U'`%{$&d*K.0<0d,Wߌ%Xu̎EV*\jT3]71!q%x&E$s Lg/wZТ$YP(Zr&)!+ΦIB$R+#-&.&$Wl"V#%=(\O'Ns# 1 Їy? MRYxPnYtζ-O1洍ju +`o֪r ۿU+ @ `QΜaSh15yj9a l?nqbeLm|$_̉(52:-ݪl5ܸVLըq"A+jˍ֋0[D:*q(!Vߕma˳OU=:ZjzM&+ ` ׭ A {ԕG30O B^Jjee@/O-\vq3.gۉnS Fkl{r;ưyuE>@.W-\y 38> m4Иg}~Eg5Rfx^Xp[B c1aMO](SRbB 4i' /$dKͺ( ~p %Q]]]Mh\<ޠڱG_؜֖Scgaȹ0ŹyafgɰQͶKCSo6*<"֊֡a Uor/? Bq ͓g_!xd}6\x ]닳]{Qׄb<肃-zg=2u)@힖PX<beB1d % V2 SMqJr#c{_,j8iWTΕg(llD6A z ZT&I#ߑ[u *B1o>zZd h?7n:n`k,}d  n%1&5&<"M5Nv^,5 9t ~<;z80Kzj>cxlJ w9lMPTb"%cF' ,y'yN( h7+*'0U46b݆4a.,'~1!'>‰[ Aj|{_^)K.CTL"Te 6FE9g INJIx!4,;6G:2&9f52]264 ΉC~ρ"5ۘ[n06.J2{OͱHj+Y@1ʑM~+45+>8L  ,ВE@X>Fm$N,I T ) { 9_ ivRﱘ֛p J * t)#ҕ,j {.|룰7@蠧,]ZMi,ZI/$f;,QkIjrۻRŸV%X Q&@I.wq2?J 3T3c0 sp$KZ ]DT j U_4 K r 3& 4|  D}\#IFn)6 R Iܭ -#V1 6<1HaE6ZM`tZ3QS~ k z10\Q h4<W 5$qJ@˔*3n9J^I!8)/kٖ2Zw51-cq'vK[75}{ei szs?K̓#AwϞp䥐}fd}]rp?0+t;ՆC 5罒#:bw>H- Gf=S-qCqgo|+; V? }`u4" qm\y43o /k)JȋD.4ۀņ>>ضIWWnOdK9.lm TXiGc Jj_"Y Y 95Aaz`P[ei m]y_iQq`yAOƁZqڡmҼ˴Zȋ+Qʗ=b/4*ۡ7>$\  h ЖyiI-pE]izPW0$_|@BnW 1.5_ ot6~&F @q}KgoaREqg" F]K)2E-(= :!{ywU? @`)*(4`ѣO( Bqf\a/= R8?[+XVU5oRchIuB cάbjfٽ"j ޙ1m@:Vx d2bUezY ܏}ٖX- ,γNM-L(V @Rkgf}E| !$֕=%ޤ!m+JL|̩@Wǜpƣf0YP 1Sjcefi| &矵d$| s(-ifXl.]Q(ԉrcL8uf  Aѵ4, rćrSCݬ}ۭz]ۃIšȆ|RV %:UY J^H;j ^ \%M デ[d>XB  Mr 5 r ߐ 5hAB}˪?;W["= ݲb;`a( &S (4(a5κ &?b,~tGwVg ^C 11Yp\Jrbg' EyWR_ U5vkqe$6iʰj" l]>* "9)"BQ  w1΋ rz Y  YYxm}^࣢ /YϲÍ&༾ TXbήW)7q* !p쮍`s*vK&CEkJ|wkWʼ&|:ypR ` 3 b W : n&S X^ {߷Bo2<0/3eYI$=ʵ[d{Q,iWTW?Ϭ  tkzI5 uvz=aT8A- Oco^10#ʢ7^E {q`SpwypzO Á-Q jγ]5 ԗN bdh(wDFHI$%(?b9S ;s tDc 7oP_v!.Jk Gt(ՂOYTҊ#Ug aj 7K~8HG8.R1,7&(pQ@^+#HA01z~Is<D],'"hLx+'q;~}{b]xNT#܌Փ |^ DZ ߄ b|eV6 ^ |J擈ȭcb;M軰B{D#r? $] .M*š  m<ѿ=G?"K;U=Uoh QgM9e?5Ф x/ 2}/3rkywu"^q o9QYĀ#t+ϲ11;n3 1(+ɜw&ك"6E /rD6J!5r y VVs,V"jS}4C&3B⠫1fgeb:gX曦 >->-3[$?M*<[ x t_>Vź * etu41J^],{پ b.>q=m G)xb䟂ᓾQ 2xyN{ kW  $pv 5 '<51` wv ~sbE-o CS Zs^Z vr"\IAO |+/ : y0k Z  il*{5sb#{F l 0z^Op.4*P|ŗ+f u&ٲ{?n]FM0!5_Mw)FL<_4.1l+G muϨ|tሌz S $ϭ p _: %@"<@}vN|S 7?r=ʎvjNnoAߵTu?K 37Y&zqS":z1 j;ݰ Y^ J6I> ] }i x+!VñG ) ;oeO (Q=z*ޥ책&.AU5Nګۡ$܇:u姊\n*gUd / C 19t\Mx'EG_# <#% 5)/IN^FO 0 WZiZYqްnC)Ʃ:m \Bj|u20GAzR}ǣwSbwDxKG~[ sSG ѪK&L9= *dqq3 ݭQ g9/lI9> {\|PNDKH_AD?<%Vx1T0X{Xp^l\#j[cm]V,xf4.5eu۸3\w1Hb-,tlN@}} :y^P` @A 8 lF >e Y<_B!ZQ2l ϽҜp6|>"Wh:/SpUW ^{*s*gqr>L!ix+i/td@ P 06"yJAB\H~Ry ޠZ "dC ~T5T7[z ݤh%v *w˩!Y~OKf2Ǚl"F;C&\(IꢘOhI['Sq^z96xY8Y&'鷤1pvz]3T8X?Ost'5 ; ƷDSY8?g2g66SF ny&#r.SQLb-^za5Q(7A^K-a(zs ֤Э\-#x"O"\ Y fdһ!x(!D##Ƣ!|Sb+<6 kӢ # yUphYZ(zGڋJYb&D_OY- Ji E; I  3Іkr *ۇi nVq^ 7cj {@ گh(`&n2p8YuOASygUa+&bsu㌹N^)ͫ]2۝D#VؒM,Tύ1&jCu5lѷR%|81VFX/X=6I" Bܡ8UmFGoơ ꙍ[KTQ 8t*mCaRyH Kxe (UfZfE!|J=YRnePgcyjp+71TH|3YRs 5v*J(ƈ;!tER- k f D" D0bK* 8 DDڑ  A%h f i jC äC_w[/Qlί 4=/! ̸v:#J_) eK 21, ^OTa1}+άT/ExmG9Nױ$#i9)_8.{}2$`55W30"*%u_`rmvc F i}ah  |FW6c :m/Y:<;@WT'i ]_&7,  FO+` I`d!w!%KgD!7Efs( 8 M  9ooll|2@4q  Kj :ޏDG4i1CP!o1$OpHT52Q1K;\c _L їý f@_t< ;+F 3i@hjG' I3[|lnT$du P y lȲ jz݁Ux"Jw"ẗ́u4P$I"ywK em \22V#.)1,Ul+%z_Y1 ~q]ћ+&;&k"F)RKeeڱ"c޺ w)$T馍7t:#Nʅ2r%q㝢uc~'H^E@"oVϵ_2_T{|<Ƽgn~A E# Eepko% ht 򺽞bbgE됻2?[C&A:>S ӾU$ E8i / n ( fG {<rDX m RͣUi{gdk T 8 {n>"6H)qL ~){F%un  FOQ( %@C1  \L 68OwBC@1IW }q zUc1ZIQvUE5z qM E GdX 0R"쳵[jrUy^,$YJ>2F.7'K[\NrQ df j-y7U./,LD9wCe\5(?: 9oN(Jj  7 V+{PugR(Xcx{HegOH$|dN&$q3Si&iY_AפAl*iI; Z mZ|.ZH~\ҡL(ADIN.x l 8s*A-"e7"B6-UNv|}\ vmVUVmou?՜ e>~|-z_D, u_H|EF"FbA)=e37sU8E*PT)·=+A0`  j C00" Gl"+϶ %! pu p g Ym\HA)`,L`UegpE]~1_v4)z, y|!Iwy{%eR} EvübZ, 3"d;AASQ)ph75$i(Ú/(5e2'`(bKi/pYf06R*dDG+ 9hJMgO 5)^ k.wOR }HjD3B$qC$)GIz {}4ݠ󗩩enF |giDmkJo b/܎{5j0gxF$;ʷ3kO|Kx4߃J6 l 6S3 UG8I e!ua@Cup1~{ZLnwcOo\sgnkOO3,K cl ev w 2- e l y 1e_ `D+ F +!SpYgC !8" "{T_#S!TL1q@5+VZL4Bl $)Ä|j#U5QmA& o^8v%]c:,wL{$U,n Df<&r8;@ ^nG/MG+𕁌%\R|+ԝcb7WY2x*+cT粣fb,Ck\ @] $U'PP"; 6N!zucMa̭۟Ji3&Y#efmJRk2[2 } &4ǂ;>q#dm sN2VIOR+?+uFw+A$J8.Q h %M ?- l ~ 7 16 A Z)H+ fLb&Sq*< X7W(*HJv5mScY@qÉ͚t|]_}_~0w #JS#)a7_ $?&Ϝ$:nDC-bm351:Xo.# \ ! Em 3) = |k B .!# P/N C{+ X2 92Ĝ8M+2n|Bjyk2_ `K k{ Ԑ fm5:S 7`:6{<rP2$QHSweI~ U jivWW/f>r94 T Ng@_:v?uE5jycg i/IE6@x0踖}A)ݕ~]̈ ?NOz\"{g@ WӦxQ%} nd]`҈nlA[%DN?c!Q'g=Y$Utu`:zȱ1G;(;gKRh~cddS޾b(6қ8 (P|{8 Cz]SH@&v^aM+ :i4ѐ5VF%w+3 |_5 S _ zf >O" = Y i]r+011Z ׏z1f f  ,E|@rUh9)~z,&o =d \ e ibt.JhҮ cyh@L̓w D[_M9.ofh~1 ]/{Z=*]!aC_2jj3E2(&D߃JoCHx[h Q󒲐AFc z &3 9_u,ٙ n  ,m } M eV`SKX 0 )'$jBt 񒫙sK3룔e鋃5׼a萾 @02uK ye j F  Y ` \=-93 rz @z V W d!rA}K^Ź0rX$h%@zWM, &TqZ3H WH ĺ нSFlPF.pIv3f+PyY[7DO_o3zKEՙ_,ߞM'8%YQv}}yӠ Q kDl/p%>JȉR64#vmحȕ6W*ԦVN/' 2hStL;ፘwřc]kYf|Cb &YQ^Pgs7 |P LS|W52xHԔRr¹$u'%jFCL J? + Md2,p+dn"^^l @9QAvd Os? ;" ΋ >-^w 268S  7% &Vz %Z"@mLR%Ñ.Pz 4 Am ~t QE &C{RgQh~f "h]^<'WgWqqus61Njj0DB|] ʙ"4}g9Kw jc R5}j5c$)myJ8$;y e?q:L[4 LXHH򖭽AFU3'7J85tsǫԥ0EAyr,s=,V)p M ah [z  R7{5OWX 4buDf8.߼1;NEc羗t=(wL9&] Hw5Aw $Iz" q } [Y ak A [^ חlOg=HsӜj91]ZAH~G]{Mtk SH^ޮE9}}7zdG;Gc7|%]^s`6vM, xN͹Kdu.n aT.06AbpUZ7+9>Jaq6FMhcNLgyZ{3gw 3_>#lMJ6} .| ͶT$ K+ 0 =lqw 93IFǞYq=,k)& $Dm0̙CR284K$W @ + mA 7܊ ; (ry+n; K#C1Y &eɻ&Xʳ!BV I'| 2 { %pCljj*C 3S8lٸ#cIR=JmwqSX)^ R*Jkڸw @m@'tw? K" E b @  m | y N $6 w)Xwjs"Nipj#ˁy쪔&^㢮'c۫ںfzڭ߱b#^{dM@/|)BaT7&Sm=8>SO#)+N{{MX-c@K*%#+#zbʛ@iL;%tVXН NjBH\%%' Mʧk (Tp-GK  l ( ] ROO  Fޫ FE<}6yEMݟ0zTU/& @ /d o6HkoXyp^ R4$QXs ;lg e%aQ 6e Vn*`$j@L:3;[Qu MiQ j\#3(+.,z*nw'P%!s#i" !ˎ!.C z٧O4MD ab w yDq-tc^ڒ yFi|^ EgI\uoK `u*T;P]1Yg =&jE&9$4&t7a+l(L5Cwwi<S;mHf ~U>I{V J%C-Sn]Y]sxoMgfFY^ Ta2Ȩ\9֢ƌ+ ox <}  p,LLCxepH3sǂ6< a(QqkGa6EYeQq%9>5b}S 0 eF GƓ?|J <XGwEê 5 ~ |l3O {F`),pĺ  L ^ l չ)Wr9hjd7SLR=u.kTSV9o\SS4{ E QBC AyK7nU`MrVk,]s^_ "anzTzH˜&4C 5g  ؤ! 4x U) ['0NX }Ґe`2L2[SRJh^ c# li1R.cu'; Y /(B$*%9X%$It#nq!β8EdKT# H k{Cf>AUov zM0yZɃvȓ1&Cf(b_{^q/]c?vZh  e ~jJgnRASCZzR-֠ ξw <R9Xy >  =}koLM툴-qaKNWBmiɹ.=繺WF2(z*:pMчo,[7^ζn"qUH6w.X x "vF9 '9_@/B₊ u{vx:e V3K e1#9c9UhN.P:zr?m\4 -j}\Vo$o u&'rؐh^GIB`g h2 }$ekdJ]vh{ <wU8f(|כ'uKJ {q}4Zqάe3%p ˋoͨQaTzev~ uFi0v*g?#`jÀWkڃŧ@ vyEwb 97@Ds:/ PVm1t&/P21 ^ꩈ ¶LHjs3#'[ 7 j  m^R d 1 ~:s^_*^IۏwtP 7y?ЊkkS5Ϫ'papsr3 ͏؎Aj[eJn85!E8&3iTYwp+< [ Yvk$0ި$N/6y`@P%mJ-6G VroPy |z%!/f',|nqa[,/ ɐ*#K 5ܧK] I Ó [y . ]aL(_8kɵ4Qkta]ySPkknӦSEKs-+`ӓݧrfցjJpѱ`o)p=T[|Vq~O*exlm=8+&=B.?"a׵72,WfRiN)Q8K F.be..r^e d+W Jp}5֦>:t;D;M4* AP)1nTmt2_phL~A5=Qo_&*۝#xޕ5`,_ %]%dٖ  vyS~N~vXz :q5 Kv*T)( ; 4 h & .%r k !U= EIv8&n. Dz/SQ`= YHΛa ŊG+ ߣM"c#HϜe/8}ZT% r?8s_A q#6ϡIJ>4JC!86Ud{Lͧpئ[;|cM}=_KXR!q SW2&eeGR \ ?/D&(c)e"2%( ޳`A\Lq(E )T~K3PFx^VY|8+RoM7Hn70zM0W p l{k(i8vQc <7—=gvF0lG pHOI^`(!lIL .1N,MHz؄2HÍ*ق\p`.Z m oz ׫5!_pGzP+='>O-n ךR(  YJ0 oYu Zl~@fFÖ[#c$v]VxI 5(fC.6tjyԛE;קI?h y^56| lXot\cG}r ; , ]E S V S 5 Z : UÛ W thՌGS#D{s@3ak 1[wU6\iGI ?+Ft['Y%'μi M* 4v>/;%E^;y޵<&nߥzQf1qG~ > :5Z˓ ?zwU͊ m o 9 p{_v:ܼ:fqxxLvO] ҶkHHe hSvO8П% S MF G!MO.c,Մ/jtq_*ZedL=rDl>ꧨb_*^%S|i!Gd " -lnYtO?_&ν~ L:3_q" `1x G"=IP%.Q\&'S>i@d ! 6u6h1IԑAUI\2p-ȘG(kKg;5nvGJJ;].xBA+@Q5UacT \+ْ^{ @6$W / u6 =O<Z<5 V >aIAZO1 -P Q J U۔ ; o ? pB  | = }t~ }Se-XWN`5&CX 7#҉o ȉm72hmt\Z'lR`j_+Tn~kH9}E6[: 1sDc_@fgn$ýofl'ӎ-Hv pC](t8/JAB0IH6cXf?Oѝ[ިGC9?$IR9Ln" s.E Y"@ > "zؤ a - 7 20 g < -QVk$M<]lTgߵ-#Ч4=x/1ߟP,Ê:\c  | J& " Y y \JD ' } <|9rhh(V d@"(ֺw R}c"B ] r `Ŝ*sӭ +4}~'l~l#zީ>Bɘ [%.gN2qq;Zl>* JCBd L` 6EMw;? o vwYY࠯'6i|J_ 4k(DYIReY[fbMR &&7 ( bz8;+({m8PUTlϫj[\atէږdޛְB} Gi`X;*PMiB/& q"9 UۣNI.]roMR.ER< 6C9.QG,es0rۤ`IRO&g"  xuwT1pw} ̪6 j^V^, Y<{K! &\l8l@ohLO7E]0R3*]sRaF6j!3|HBQ^D]M],Da@yKp#yTYl-_CGS D ;F2n@ P e _FR ϊ 熸DLu3--? z Ov q\ -DcK4 1Ic<}u[J;; d "cՊ>4=SxՖnIbh&X mNANM,w{ڏx&W:!fV9U2BQU*ۉ/ ;z@#x '< o1q~z 8= ǧ`5k8M@D:r4TfMɏ4Q$tK $ }dT RP% gO3fͺ!r-'1T:lZFa8)R*K8$+6쎻 Sd=}!؟zwmK(S_Zng ]1*F]vR|zBn?!ˬvd^ebI !Ŋ--wbuRtBp  mNZ8lqmf1oqW>*}tt'"Qao38HP$x/ #./=Uwq+/; ڸ G  PcaV ȣp{Z4m&94 --W J l Yϩ kg J, 5ԟ |= Wged Nl. !. do<:p>7~Ex}#9Tq L% x8 aN#$F:Vk:\/]A!rW7RosMDQD(:bU -_bZiNɊaؤ= K]HYW Z8lfƉL0c?zgT:zцz?'?Pӹ-|Lt_ozWWEFm$EW̒r ~/M;g[OM=;fO2̞k(Yb[%lGI{uO~xhY&k}"W}x:9 =cr||5 j %J #D  ' j 40 :g4 o~ ?#Eob&3CK aΌ*O _daMj?>WVJ D{!<1LxP 8 8a 4 1 > ]Ft 0m ^3 'SluqcЮ܌]> ;#kp;Mx>c}kҮRsk@gcark 0, %yK d t0~- X:V6NH^/VnNq@CĔr͑=z<4k:T>R 7IALSJq#]*|;.[$Nq&H$jH ч@t" U Ĭ ƸįD|BBo 2. 7R r8X   xZ]XCDp 3h(6 ]E : zr*RTy~`v/+xfw  , }x!#5 b\6^~E2_R 8i%+;@bbRB̏Gb:!i{jO\@] PQC)+$QӦ-_@|6A&V%  $ [ ^ i8 Qʛ@0,a*L'x*F%&9z]j"O*~L ^_gl"\~;-^ r <ܼ80G#"&|6^B/ii=(JD:&EvlhW[:j^ HUv(^B7L=lpZx[\;[l(KKery`DF9oW|M1t'V |']ʶ<Ők@4[_a4tDhVBXW _G w {'̓(bwehdL`;g | & rK?e)Ώ { i Ӏ m Z 9 zE ɘ*ORz>G \\ F E$ #e0&H o[ YuIi= !rH3hh~-PyWpr v僀V#B~3P<帤2@d&ROg%"vٌ>*FZMT o63MNEhہ{u􇲄3F?n'|Yłܮ=3|[$a0:39I:.xoT<)I2,FQtنUu ) = & ȩ  R /B ܉ W9[ RtyoKHYqfenrir-1.5.1/config/sound/default-wav/StartOfLine.wav000066400000000000000000000265201317357605400225500ustar00rootroot00000000000000RIFFH-WAVEfmt (  8qfactdata-̌٫a ڈew.B k`<KTHJݶ+u=ݔ7 1XpC%NO4f*[ɟg^tr~Ԃដ |ܐYG6ܪq%ћ30ŲAdZwAkP _T^$H 0D<l<ٽ1oHn%zMT)` l-$w'W+힏/{3+X75ͼ;9@ϱ?ХCGjҙGӎKUՂOc)vSc@kWT_[qS_)~Hc5zPӊWȎL4zZϤ9hcvcv? j#_ "S.MH:<Fw0'nR %ƮK^5(j6 μv C`  Qy_V3Ims{2 bv >]j _ '!S - 3#G ?$<; KF&0 mW'$I Jcp)! 'o+ %W{,)/.,e/0Y14sx28U4<36@έ7DB9H:LlTa ?vX2=,Aj\!B^`@,VDSd8EGhNDG;lPI0p\l\J$tIh?Lxj&tM |iOxPRꇆ(Tދ xUӏTRWǓ2X|Z)\]7;_`E `fbu =cjS!&e^!1%gRa"=hG"IOj;o#Uk/#kaym$}$Hmo%%yp Ӌ%8r&z*g)X6T4BN&bYeP!pܩq%܆}z)~c-@195Ξ9׸c=!AЍE/o"zIK跦nM=)LcQWUK wLY @]Y#4ay/6(egW;˱i4G`muSq^tjx v|腂I׀c޼̄?s&4׽2ÝđB\ƆnzPKn(c^WFKl@(p4zy4(V@4L/XȖcYoϤ{+ײb9>BGlUΖ+cmzJUnq'b WK!? -?4y9(UEi#3Q]1h("t&?R*.Ma|2>6[:;>iBe Fw Jl yNI$nR &bVOWZK^&y?b(23fx>(j6TJ8n2VrD bbv myR y } !"` #օ `K%ˉn =& u(| *̟+4-.k^0yI1n%3b-5V6J;+H8?793IwCr;(SO=W1[>g1@erA~[CsDF܁_HOӝCFߧ i8߅,Ta" ?.(b: ERpQ]|~imuьJ;'аٚe!澰/盼$xȹ}=UNr2fKxZ OYC87h, `'b v>3? J! VbK n$lzu('I ,&ӷ054լ4֠8C^ؕ<ى@Qx͈}DTqH_2fLGZPmOTrCX{7\ ,``,1 d=8hD[ lOo[s,gws{:kDIÃH%nV߮-dwW}rTq1fZN AC7%k +#_1 <= 1I* øT?`TlMx~j[H$=i߳gw  ˑ v&!} S"q 0P$e %Z {'N) )B *7 7*:,+_6- E;Bd/N0SY2e#4!aq5%}M7)oi8-Gw:1}$ <5=9޸6?=@A`BE uC|IREqM./GeQ HYU< JJNYKB]J#tM7a/ O+eX^;Pi:G3RmfSSq^]UttjVxvX|Zـ i[΄FF]ˆ#^p`% ݽb ɚc3!/e!tf|A"QYhp".ieO# kY#mN]$nB$(Cp6k%4q*%S囎G3ڲ0;ڏő0Al [$IP&! -^8ݽDDlޛPٜw\nzUh"1t&-*¤.ɗW2⥣짌6⃯:+`u>=ǫjB9@^FկRJGjGN;RU/Vk*$ZcH^%&T bq2f=~iImUqva=uTmy0ygĻ}"ůꐑǣ0Ȝ&ɘʌ>Ṕ_uL:?.Eh"fA#E.BS":D E%FaQG]OIoiJtuyL}PN.Oً 8QRİbT UȌW.\!Yt9Zh<K\]]QJv_E a:Y b. g'5d" g!D3e!!?_g u"Jh"Vj#bl $nm$$szHo(%Op,%-rr0&&7gقC6kg_Oːo<[`sugwr{~ ݱݍIkޛyGsm&%bƝV42Jǣ>B\3v'PS0 ^ $Fl0ۮ+3cu'RVr/  ) 5A?M]Yi#;e׾!qٲ%1|(ۧ)шܛ-?Rސ1߄5Mi|x9El=[#ĦaA;UEiJIe>Mw2Qt'UQ %Y .] #Oa.d:yh(FlRp6\^8t:jxDvb|RЍ!`hKxnEl"ua| U I4 > 2s_&P-- (3;?HKIWr[cW 9o {1e В["s # % g'x E¯(l !D*`+Un-I$/>022s .2&P3A-!X5  -6O88D:]P;~\A=k[h>"8tk@&yB*C.З*E2F6TH:fIw>D~KlB* M`FިNUJ8=PINQ=RFhS2VrT&ZTOV^,&'Xbb 2Yf=Q[ipI\mU{^q~}a`u Zmay 7y:c}!d!df!"Ϝg"i/##k#elw=$CMnl$o`K%wqT% sIY&R;q/Џe eY!NďB/ܣ$6܁ܹ+=]N;Ky Z߯#8 h/͢i;bvFG#S_! j#vK'䗂ୈ+tu|/'Q p3.e75 4Y;ɵM?C^BC6GQሺ+K\O_:SHWmZr^{(b4fh@1jELn"X[ʶrc˪vo͟z,{ϓ~Ї:sD|QpH-nd YV˜M-Bd6W*r[9 !A-乜9kٽ#gEDQ1!]*ɸh?tTM~r{[Pp,=di YgMwAߑ5~&* [8Q{)& 2 7>: fJ ECVd!b Sm$y#(a,M0oq{4Owp8}+ d< X@ 6MD AH `!5L }"*P Z$T. 7 &X '\< J)_ +*cJ7t,gC .kXfO/oB[31sf g2wr]4{t~579 p:{NFP.g"LDz" Z:hϴdݳvr'ѷP3Ż,?# KÒVMb⿗ˠnw'~z Ӯ[t586hۼ\C`QϵEQ9._gٴ"CIm! s{  3 q,O8],Dݹ P߮-[g";sF&}*IZps.7h2W\6/P:eκE>Y9Bs-Ffރ"JBN RCU Ym]$%aq1e2N=,i+Im@UVq`uNlyx}\|Y? sj7 hi \xPͿD(9 ׽-eR"A| )7 <紾 *ܸE p6f м MB!S *N# Z%%a e& qO(o }) |y+}X-s6.g80[1Pb3D 49܌6-.d!8!A9<L;  <Kv># @ Y/Ao;5CgLGD)S_Fu_GjI#vK' L+{HN~/WOr35rQg7&S[;|TP?41VDCW8GB[Y-KcZ!OP@\S^ W^_ZEa^l (bb 4odfz!n@fj"KLgn"(X.ir#djv#oXlz${m~$o+%zq~%Wrr9&Dۍ٭Ppzډ\ghx͈Ct/l!ĕ`ՖYTۗIݤݸ=+ޕ2r&9OB,נG lU,d}ZVr8&뫽 2=IU?aԳ fmiw$#Byk( `,1(T0ڜI4?鷨R=8锴1 ejۭ!f_4"3hS"ֵiGB#]k;#l0P$lهn$$Jp^%&q %52|u)6'Y :6>54BɔEC^IܪMQ݈QdU_B YH]m$ݟa0re{<iHmpT1{qM`Ƨou*l[cyxX}䃅L,A䞛5:|D)XٲH6nV֘-dºWبrd̬A)©5AĝAŒMkdž#oYzȪMeo1)q*cи}X?TL@M~4{)[X5=igw& c @Q# .{):F7R:n^zELjdo#(vc'SW+#K/a@3M47oz);Ww?}4 CաG6JN`R VcZ.? ^(b<3Jf? jJKt nW rXmczvKo3nzf({c~]WtK@4 y(VF 3 p%  !3 /#㩺 $׭A bZ&˱ >!'O -) 8+]D,PC.k\/mhm1zyJt3n'4bՇ,6W7KݕV9?:4x<(*U>2Ӫ?8?ABFiDEUGa)Ic=&J 2SLq=MI}OUQaR lmwO_(@T`DL 2ybH dLZ!eO!8gSh"hW"cj[v#`k_#<+mc$7"og %Bpk%NLro&LzĦ)Z :h#ϓ۞/dvz;~XGs„4S#g _[ʒjMOvDҠߩw8' -ڮc!5@6˦ C`QՊ_nKIm)߱t| ( 43y@ȹ~WL]r3Xfd[!-oO%{D);먇F8-녓,1Ibp!5?9W =/@eDYHsLnPKT( ԸXC֬\!ס`-mٕd$9ۉhyE~l2VQ,rp3]ft@iV[xtO|NʀC8\,b?!j>i xӓ( ۣmRϧJë'})&72<>ExJf}UVrS3bfn%ZayOɅOCo8y ,}a > 8 b .l!I=&L  K +v 7 Y C  xO5"}g T[#q 2g_%f"u s&Z& ~(O* Ȋ*C. +72H-,6`. :=r0>&2 Bќ3E415I6MB[8Qk9UPH ;Y%=]^%>a0E@el. BHE>cI}LPUS%WZl.^a&66ePhj>l=oFsvTNz} Wm#ۄ=_'X㋄rg>owU+lE_ &z஘=$TDZ2-Mkg5ȁ%=قE<NS:VT o^jǣf$n; w ' AR\v i##&*-:/$1I4c,8Q~;4? BhvwXz8s~~Q ܎ h+"F`#z9+3P䷯; g3DMȽ!hL~ۜT8˕\Oe֬ ;mfUou }}ھ7م O(B ]fwÑ" }*72/; NJ#dC'*eK.³1S5|8\<6?7dCQFMllJMtQdT|X\{ _$ c5?fYjsmLqt!xcݥ{)|,2F6a:{BMƗJΞdRץ4[{N߬hc5糒kLs|c!;Vzp׊4ڑٜK ))bC]1xy9֬3AIJ 0RKaeZbx j$2's+.I8{2R5m9`=@Dw֓GK1 N% R?UHZ(Yt\0`_c8g޼jv@nq0-IuGxaQ|G|Y݆`ajw4r1OizHӊ_"v¸F[ʿNr*WD,__щygC۠oZw2qLf+ BИ Y% 9T-pn͈5*="%AE) ,&N0XA3[V7v:o^>̪A)fEHnL@O.wSHVWcZ}^an ȅh(los?6vP$zj}X,4oԸ<) #E=ə@XMrѠUW٧]ne(+nE_v?zÜ~VɆγ m2'Mg#>꛶+ЯU3 XdSs菰l jt%|+`FO w1KW1f_Hg!$o(_+x/92vS6m:0= A꼐DGHK O^&R@%V[Yuu-]ҏ`/5dĹg=kFnFr.u]HNyb|}Vvڃӱ^0⊍fGo5Pw^ju /"F=Wr$]ƺ,t4.=؋*DEE_yM\U]sf-2LnfDv ~[ r9",T%n)戟,C#03+7Z: 4>'AqA>cBEVkILtPm/SI|W'd[~^b>eilUps7!wlQzk)~(1⺵?9o BV$Ɩ>JYΝmsRʍ֤'Zޫb>沛k+UFs`{{lɯ&σ=ٚ3MTh 䱂(k0%9 <;AUoIS Q jY$b(Bj#;]&wr*-Rz14 8i<?#0CJFdJ:MQTQ'X[ 0_hb78f"Ril@m܆p9HtwP{P~ Y %݅i?aY#tiݨq:yQ, Gha{"9&P4/̭N i7gĝ?!~G8P!;XOVp` fhÿ p}y 7)C]Nx  e$'+|.0&26K5e.9GdJGNQ{8OURX5mW\__cLfgjmc pq%t@xxzZ{t6 Mސd-Gb%||ٖ-65幰M>·5FdOʾiN{Vظ5^ВgL"ک\AEؕHsL O-'"SAV[*ZDv]2ad[:h߾kBorr.Kv,IycS}}׀E[߇c\玹ls6tP-k|矄DԌ[ #>rX!r,)lj1CܵѠ9Z+BܷE`JqzΔR,ZCb2kZMgs q{ ζ+уB :"T&Yo) -0p(4ج7*0; >'9BABE\AIvLXIPSQWoZY^)a/beIh@djl~orsWvzz}p*7QkAXգ' o$0>)Y8s@@ĹHWPĴ,YnF`a({Յi?qyV3Nmhʂ'њ> 'U;U/pl7ɤ&?#&G*=-(P1B4T]X8w;`?kBhF%IpMP<0yTJWd[S_b fjΑim$pt7w;R&{l~.T6ֺk> Ó%%G?˚YO <hVFp"N ܿV9^P)g C# ^o'gx*Ēw.!1~598< @0Cfenrir-1.5.1/config/sound/default-wav/mispell.wav000066400000000000000000002261201317357605400220210ustar00rootroot00000000000000RIFFH,WAVEfmt (  8qfact%data,&&!)@!)@qoqSqoqSla_la_ee] si] si$j$jAiAiCTfCTf]`]`$X$XeEKeEKq7q7HbHbmΣmΣ{L{LTTݳݳvv8!8!+V+V‚3‚3LL:7:7Ыjjii A$ A$i+i+r;E`>EUUd$d$E?E?5$Q5$Q@|@|1/1/ZZRRYΩYΩ??^UE ^UE L2 L2 bbv&v&G*G*!!998C8CLQLQDDIIxx0 0 +s+sF$F$M>+M>+h1h155c8c8h7h7ZP5ZP5;0;0''ss88..||ەۮ*1ˮ*1˘ððX3^X3^ssݡݡ泥泥nAnAmm9lj9ljc[!c[!;;/a/aU 0U 0CC8iR8iR2\2\bb2Gd2Gd{&e{&e%vc%vc__?b5Y?b5YUNUNz#=z#=&&h[ h[ *71*71TT]E ]E N>N>22++ɩɩ㾍㾍Q~Q~eeEnEnG纗G纏w'Տw'hhmm$/$/{KG{KG$X$X:r=b:r=bCigCigK~TjK~Tjajaj3i3idd^^,5T,5T6E6E>0>0]]$$pޜpŦ TգTգ⚇*k*kuuJ J %%B B  w w5353ÓKÓKVV~A~AIb4Ib4!.!.)><)> [P> ``&>&>OOǂٮٮۜۜ۬۬썳썕JՍJՍqAKqAK®£ޣަ'r'r~6~60BL0BL@ [@ [;0]c;0]cggiiS\iS\iXfXf%a%avZvZ&OO&OO)>)>~'~' yy7؟7Z[Z[qMqM|ܲ|ܲXX%rp%rp~~cc++ gOgO*{*{TxTx WOWOOF.OF.z:z:dBdBolGolGl0Il0I}CH}CHoDoDU?U?,.07,.07?j-?j-LD"LD"7h7hV V vv11,$,$;J;J3 3 bbmmv0v0xx!!:U+:U+44ZZO8MO8M#)#)סס tT tT'gG'gG==(A(A縨1丨1ԨԨmmՖՖ*5*5!!ggxxW W 3E3E"l$"l$S//S//V9V9ެ@ެ@͝E͝EHH}H}H>OE>OE.?.?66S*S*T݌Tt t U]U]iiD#D#ߧߧUUmERmER :Ȥ:ȤSrSrC C Íٍ }}C*C*9A9ARR& ^& ^!y?d!y?dL+gL+g~i~ihhdd/_/_VV/KH/KHS3S366]O]OS+S+\\dd})})GG{Ӎ{ӍddXXвв##HaHa!!iz#iz#<<PP\\s cs ch+gh+g9Ph9Ph0Cg0Cgmcmc^^VV>H>Htz6tz6,P%,P%  뚽$ԛ$ԑE9E9ææZZs!s!xx0@0@hh\\ljىّee(f(fx x Я-Я-397397[=[=@@xHAxHAO?O?%\;%\;.4.4\I,\I,##hrhr߿߿\ \ E)E)88j0j0jjxxT0T0ӆӆ2d2dS*S*  !|!|??TTTTȵCȵC!!sDsDffgg{ { בWؑW'n'nܔ hKhKN\N\avavjm jm  . .gc9gc9FBFBޢIޢI(M(MNNUMUMIIBBV58V58F\)F\)\\k,k,4"4"Ob(Ob(ԩ^_^_RR 7 7NNOEOE,i,i[[nnOƪOo͌o͌ ֋ ֋GK=GK=W2W2ΩHΩH[IfX[IfXaa)Vf)Vfiip*Ljp*LjhhOdOd]]SStCtCkқ,kқ,,J,J Q Qkk^)^)w@w@ڍڍ&&  JJWwWwӅWW**AAnRnR]]}c}c9f9fqq]fqq]fddr`r`M7TZM7TZPP;A;A2-2-**W JW J33НגגPZ PZ FT˥FT˥eͧeͧFFrӶrӶW2W2RnRnL6L6upupdd11ג ג *+*+$}2$}266ת8ת8b.7b.7L5L5#/90#/90))EA"EA"rsrsF}F}  +.+.GG(ͭ(ͭ-K0-K0IIjj22U U nn$$rbrbYYq q <<uupp_W_W55yUyUU.U.11]]c]c]שש||;;s՜s՜bb<< AAѓѓ\\-T-T G}G}zz9kx9kxE vE vss^q^q7o7o4l4ljj h hpfpfzdzdbb``^^\\I[I[YY[mW[mWUUSSERER)P)P O O}M}MKKdpJdpJHHGG#F#FDDXCXC'A'AS@S@$g?$g?#'>#'>R<R<{;{;::k\9k\9787877i6i6`4`433221100v/v/....--2,2, R+ R+u*u*#)#)((\'\'00'00' i& i&إ%إ%$$+$+$7s#7s#""""na!na!ͷ ͷ   nnI2I2֘֘ooooPP>>55ٵٵG8G822DDRRnZnZyy_ _ hh88mm` ` JJi9i988͔͔EEcacaOO { { E E 9 9   R R ? ?   #N #N   a a 0 0 o o : :   ) ) ; ; Lp Lp U@ U@ Q Q ==ωωk^k^335 5 YYMMkkEE  //aaEErrRR11xx]]0~0~EbEbFF,,    ʭʭ~~ggzQzQ;;&&GG--vveeSSBB[2[2""00HHFF--99__XXvv j j]]QQEEk:k://##!!tt@@ooϮϮDD}}hvhvnngg``YYRRKK^E^E>>88b2b2K,K,W&W&} } &&B B ddLLRR))11[[MMîîJJJJ۔۔,,cc^^~~I|I|yygwgwuurrmpmp2n2nlliiggeeccaa__]]\\-Z-ZbXbXVVTT:S:SQQOO]N]NLLHKHKIISHSHFF{E{EDDBBnAnA!@!@>>==c<c</;/;::88776655z4z4o3o3i2i2j1j1n0n0y/y/..--,,++****A)A)p(p(''&&&&R%R%$$##$#$#r"r"!!!!n n ((WW00~~((IItt  AA""llffrr##AA l l ( ( c c $ $ n n 5 5 X X " " [ [ + + vvKK""ZZ55ddCC$$rrUU;;  tt^^HH11cc\\33AA))  //  jjT T d d  OO= =   ))mm<<77T*T*EEcc>>bbppddXXMMWW}}2e2e..t t m5m5ff%%ԃԃ__nSnSCC ) )rrllPP??@@IICCrrVVfJfJ]]~a~a``ff  ssss~.~.4.4.vv{!{!jja'a'T.T.//bbII-w-w00XXցZ8ցZ8ݖ&Kݖ&KjWjW]]bbi Gci Gc+åb+åb)*_)*_^Y^Y٪Q٪Qy Dy D3030ZZii66_ݭ_ݭmmE6E6ΕΕ**zzωωʶʶLL!!ŘŘM'M'77'C'CKK_lP_lP`Q`QOOLL5 E5 ELa4y>4&m6&m6X6X6O?3O?3!.!.&&M M p`p` ĥ ĥɑ;;[o[o&&ИAИAϱϱ8 8  ʧ ʧHH'v'vH[ЩH[==>>5/5/MBMB-Q-Q[[*a*adcdcIdId'b'b,^,^cXcXgsMgsM<> f foOƦoOƦ##ltlt:g:gμμD:D:,#-,#-J;J; F FjN\LjN\L!S^O!S^OӄOӄOMM2 H2 H+x@+x@p6p6ġ'+ġ'+zz++y(y(I~LI~LMMEeEeٗڗv\(v\(88{{􄑳b..b..[®[®CCQQVVll|A|A<5<5""5X5XmmˋcˋcJWJWRRCCp%p%8.8.@6@6.<.<夡?夡?ѣ@ѣ@M?M?$/;$/;O^$4O^$4))eu}eu}  KKFFxxҪ **22U^NU^N~~#d#d{{00__X X EEa#a#Lv3!Lv3!^98^98KKxsYxsYx`x`9#e9#egg~f~f`d`d\_\_9W?X9W?XsKsK99s1 s1 HaHa!2!2#C#CfLήfLήаϜаϜbbWWW[W[퍚ӍӍ啑啑kAkA¯W W ii66-:L-:LZZTcTc;Śg;ŚgiiTiTi"f"fΠaΠaO$ZO$ZGOGO޻">޻">&'&'. . 򶸪ض1T1T))RROOCjCj"E"EL߽L߽.z.zϵuu#s#s8 8 HJHJV.V.ru:ru:_B_B?ChG?ChG*,I*,I`?H`?HODODd?d?&,7&,7f-f-@"@"mdmdR R acac&&)].)].NNXFXF^^HSHS?&?&uu*x(*x(!2!2DJDJb&b&@@'Q'QDD…;…;[[\/\/hhⰜᰜDmDmQQ{e{eyy͛U ͛U ]Z]Z$$W/W/T9T9@@EEsHsHHHzMEzMEct?ct?66s*s*f0f0:h:hSSc\c\ Sh ShӆӆZZ_T_T Q Q^^^^wǤwǤk*qk*qqqϖϖ$w|$w|I*I*1A1ARR) ^) ^>d>do8go8gii&h&hdd._._~V~VJHJHR3R3!!11N۾Nۂ**ڣڣcc;;==̹̹ӍӍ0Hd0Hd  NвNвYY˭`˭`煌 z# z# l< l< P P=\=\ c cYR+gYR+gaPhaPh0WCg0WCg4c4c.^.^ V ViȢHiȢH66c$c$@P@Ps$s$88dd'æ'æii!sx!sx??*zh*zhQ=Q=bbDzٲِ##MA MA --.f97.f97Ђ=Ђ=6@6@ 1HA 1HAJO?JO?L;L;448,8,Փ#Փ#22ԨԨUU" " \ )\ )Bp8Bp8303044vv 0 0UUAdAd$*$*|ޖ|ޖNN;;**++++CCKDKDuuڶ׶׆ ׆ [3[3ئnܦn▤떤KK\\FvFvM M -.-.(E9(E9d(Bd(BII} M} M*N*NMMIIPBPB=58=58 C) C)\\**p p K(K(G_G_77NN:E:EiiGG}}ww== ċ ċ9=9=F2F2HH8fX8fXaaAFfAFfii$Lj$Lj—h—hrOdrOd ] ]SSCCě,ě,JJDҋDBkBkZZr@r@ڍڍLL~~ 䘬@@""kmkmӑMM**AA?R?R]]M}cM}còfòfh]fh]fњdњdS`S`z/TZz/TZ,P,PAA+-+-KK**]J]J--暁暁gђgђS S M˥M˥LL_ͧ_ͧLﵭLﵭӶӶ,™,ºhѺhǵ6ǵ6kkdd,, *+*+@}2@}266%8%8)7)755*90*90))AA"AA"JoJo3y3y  U*U*zɭzɭG0G0]I]Igg__M2M2B B kk!!__WWy:y:UU>S>S%,%,//NNs[s[թթ{{,:,:EEӜӜ᱘᱘]]D D KK[[[[RRi i \F}\F}UzUzixix v vss]q]q6o6olljjޖhޖhJfJfydydסbסbӇ`Ӈ`r^r^\\C[C[YY`lW`lWUUSS3DR3DRAPAP O O|M|MKKoJoJHHGGZFZF±D±D?WC?WCjAjA@@mf?mf?p&>p&><<ϴ;ϴ;::[9[9S78S78h7h76644x3x322t1t19090//....J-J--2,-2,Q+Q+tu*tu*))4(4(''/'/'h&h&m%m%$$*$*$r#r#""""a!a!o o - - 8n8n11nn66PP==bb5588MDMD.Z.ZByBy" " --X8X8ll) ) hhJJ797977ggsEsEȫȫ9a9a'' S S E E   . . ? ? n n l l N N   A A   n n 9 9   1p 1p :@ :@ 7 7 $$S^S^33  CC88kkEE  NN22rrQQ11ffLL ~ ~6b6bFF , ,~~ggnQnQ};};%%==""vv e eSSBBN2N2""$$==@@''  22XXQQvvjj]]QQEEf:f://##pp99kkˮˮ>>ܝܝ}}bvbvnngg``YYRRKK[E[E>>88^2^2H,H,R&R&{ { ##? ? bbJJPP((--XXKKHHHHޗޗ۔۔**bb\\~~F|F|yyewewuurrlplp0n0nlliiggeeccaa__]][[+Z+ZaXaXVVTT8S8SQQOO]N]NLLIKIKIISHSHFF|E|EDDBBlAlA!@!@>>==b<b</;/;::88776655z4z4n3n3i2i2i1i1o0o0x/x/..--,,++****A)A)o(o(''&&&&R%R%$$######p"p"!!!!o o ((VV//~~''IIss  AA!!kkggrr##AA l l ' ' c c $ $ o o 4 4 W W # # [ [ + + vvKK!!ZZ55ddCC$$rrVV;;  tt^^GG11cc\\33@@))  //  jjT T d d  OO= =   ))mm<<66U*U*EEcc>>bbppeeXXMMWW}}2e2e--t t l5l5gg&&ԃԃ__mSmSCC ) )rrllPP????JJCCrrVVeJeJ]]aa``ff  ttss..3.3.vv{!{!jja'a'S.S.//aaII,w,w00XXցZ8ցZ8ܖ&Kܖ&KjWjW]]bbi Gci Gc,åb,åb)*_)*_^Y^YتQتQz Dz D3030ZZii55_ݭ_ݭllE6E6ΕΕ**zzωωʶʶLL!!ŘŘM'M'77&C&CKK^lP^lP`Q`QOOLL4 E4 ENa4y>4&m6&m6X6X6P?3P?3!.!.&&M M p`p` ĥ ĥɑ;;[o[o&&ИAИAϱϱ8 8  ʧ ʧII'v'vH[ЪH[==>>5/5/MBMB-Q-Q[[*a*adcdcIdId'b'b,^,^cXcXgsMgsM<> f foOƦoOƦ##ltlt:g:gͼͼD:D:,#-,#-J;J; F FkN\LkN\L!S^O!S^OӄOӄOMM2 H2 H+x@+x@p6p6ġ'+ġ'+zz++y(y(H~LH~LMMEeEeٗڗv\(v\(88{{􅑳b..b..[®[®CCQQVVll|A|A<5<5""5X5XmmˋcˋcJWJWRRCCp%p%8.8.@6@6.<.<夡?夡?ѣ@ѣ@M?M?$/;$/;O^$4O^$4))eu}eu}  KKFFxxҪ **22U^NU^N~~#d#d{{00__X X EEa#a#Lv3!Lv3!^98^98KKxsYxsYx`x`9#e9#egg~f~f`d`d\_\_9W?X9W?XsKsK99s1 s1 HaHa!2!2#C#CfLήfLήаϜаϜbbWWW[W[퍚ӍӍ啑啑kAkA¯W W ii66-:L-:LZZTcTc;Śg;ŚgiiTiTi"f"fΠaΠaO$ZO$ZGOGO޻">޻">&'&'. . 򶸪ض1T1T))RROOBjBj"E"EL߽L߽.z.zϵuu#s#s7 7 HJHJU.U.ru:ru:_B_B@ChG@ChG*,I*,I`?H`?HODODd?d?&,7&,7f-f-@"@"mdmdR R acac&&*].*].NNXFXF^^ISIS?&?&uu*x(*x(!2!2CJCJc&c&@@&Q&QDD…;…;\\\/\/hh⯜ᯜEmEmRRzezeyy̛U ̛U ^Z^Z$$W/W/~T9~T9@@EEsHsHHH{ME{MEbt?bt?66s*s*e0e0;h;hSS݀ɀc\c\ Sh Shӆӆ[[_T_T Q Q]^]^wǤwǤj*qj*qqqΖΖ#w|#w|J*J*1A1ARR) ^) ^>d>dn8gn8gii&h&hdd._._VVJHJHR3R3!!22N۽Nۃ**ڣڣcc::==̹̹ӍӍ0Hd0Hd  NвNвYYʭ`ʭ`熌 z# z# l< l< P P=\=\ c c[R+g[R+g_Ph_Ph2WCg2WCg2c2c.^.^ V VkȢHkȢH66e$e$BPBPs$s$Ԁ88cc(æ(æii#sx#sx??-zh-zhM=M=eeǯٯُ  NA NA --,f97,f97Ђ=Ђ=6@6@1HA1HAJO?JO?N;N;44:,:,Փ#Փ#22ըըUU" " \ )\ )Bp8Bp8303044ww 0 0UU@d@d$*$*{ޖ{ޖNN<<**-+-+CCKDKDuuڵ׵׈ ׈ Z3Z3اnܧn◤뗤KK\\EvEvM M ,.,.(E9(E9c(Bc(BII} M} M*N*NMMIIOBOB=58=58 C) C)\\**p p K(K(G_G_77NN:E:EiiGG}}ww== ċ ċ9=9=F2F2HH8fX8fXaaAFfAFfii$Lj$Lj—h—hrOdrOd ] ]SSCCě,ě,JJDҌDCkCkZZr@r@ڍڍLL~~ 䘭@@""lmlmӑMM**AA>R>R]]L}cL}cIJfIJfh]fh]fњdњdS`S`z/TZz/TZ+P+PAA+-+-LL**]J]J--皁皁gђgђS S M˥M˥LL^ͧ^ͧMﵭMﵭӶӶ,š,¹hѹhȵ6ȵ6kkdd,, *+*+A}2A}266%8%8)7)755*90*90))AA"AA"JoJo3y3y  V*V*zɭzɭG0G0^I^Igg__M2M2B B kk!!__WWy:y:UU>S>S%,%,//NNs[s[թթ{{+:+:FFӜӜ᱘᱘]]E E KKZ[Z[RRi i \F}\F}UzUzixix v vss]q]q6o6olljjޖhޖhJfJfydydءbءbӇ`Ӈ`r^r^\\C[C[YY`lW`lWUUSS3DR3DRAPAP O O|M|MKKoJoJHHGGZFZF±D±D?WC?WCjAjA@@nf?nf?p&>p&><<ϴ;ϴ;::[9[9T78T78h7h76644x3x322t1t19090//....J-J-.2,.2,Q+Q+tu*tu*))5(5(''/'/'h&h&m%m%$$*$*$r#r#""""a!a!o o - - 8n8n11nn66PP==bb5588MDMD.Z.ZByBy" " --X8X8ll) ) hhJJ797977ggsEsEȫȫ9a9a'' S S E E   . . ? ? n n l l N N   A A   n n 9 9   1p 1p :@ :@ 7 7 $$S^S^33  CC88kkEE  NN22rrQQ11ffLL ~ ~6b6bFF , ,~~ggnQnQ};};%%==""vv e eSSBBN2N2""$$==@@''  22XXQQvvjj]]QQEEf:f://##pp99kkˮˮ>>ܝܝ}}bvbvnngg``YYRRKK\E\E>>88^2^2H,H,R&R&{ { ##? ? bbJJPP((--XXKKHHHHޗޗ۔۔**bb]]~~F|F|yyewewuurrlplp0n0nlliiggeeccaa__]][[+Z+ZaXaXVVTT8S8SQQOO]N]NLLHKHKIISHSHFF{E{EDDBBlAlA!@!@>>==b<b</;/;::88776655z4z4o3o3i2i2i1i1o0o0x/x/..--,,++****@)@)o(o(''&&&&R%R%$$######q"q"!!!!n n ((VV//~~((IIss  AA""kkggrr##AA l l ' ' c c $ $ o o 4 4 W W # # Z Z + + vvKK!!ZZ55ddCC$$rrVV;;  tt^^GG11cc\\33@@))  //  jjT T d d  OO= =   ))nn<<77T*T*EEcc>>bbppddXXMMWW}}2e2e..t t m5m5ff%%ԃԃ__nSnSCC ) )rrllPP??@@IICCrrVVfJfJ]]~a~a``ff  ssss~.~.4.4.vv{!{!jja'a'T.T.//bbII-w-w00XXցZ8ցZ8ݖ&Kݖ&KjWjW]]bbi Gci Gc+åb+åb)*_)*_^Y^Y٪Q٪Qy Dy D3030ZZii66_ݭ_ݭmmE6E6ΕΕ**zzωωʶʶLL!!ŘŘM'M'77'C'CKK_lP_lP`Q`QOOLL5 E5 ELa4y>4&m6&m6X6X6P?3P?3!.!.&&M M p`p` ĥ ĥɑ;;[o[o&&ИAИAϱϱ8 8  ʧ ʧII'v'vH[ЪH[==>>5/5/MBMB-Q-Q[[*a*adcdcIdId'b'b,^,^cXcXgsMgsM<> f foOƦoOƦ##ltlt:g:gͼͼD:D:,#-,#-J;J; F FkN\LkN\L!S^O!S^OӄOӄOMM2 H2 H+x@+x@p6p6ġ'+ġ'+zz++y(y(H~LH~LMMEeEeٗڗv\(v\(88{{􅑳b..b..[®[®CCQQVVll|A|A<5<5""5X5XmmˋcˋcJWJWRRCCp%p%8.8.@6@6.<.<夡?夡?ѣ@ѣ@M?M?$/;$/;O^$4O^$4))eu}eu}  KKFFxxҪ **22U^NU^N~~#d#d{{00__X X EEa#a#Lv3!Lv3!^98^98KKxsYxsYx`x`9#e9#egg~f~f`d`d\_\_9W?X9W?XsKsK99s1 s1 HaHa!2!2#C#CfLήfLήаϜаϜbbWWW[W[퍚ӍӍ啑啑kAkA¯W W ii66-:L-:LZZTcTc;Śg;ŚgiiTiTi"f"fΠaΠaO$ZO$ZGOGO޻">޻">&'&'. . 򶸪ض1T1T))RROOBjBj"E"EL߽L߽.z.zϵuu#s#s7 7 HJHJU.U.ru:ru:_B_B@ChG@ChG*,I*,I`?H`?HODODd?d?&,7&,7f-f-@"@"mdmdR R acac&&*].*].NNXFXF^^ISIS?&?&uu*x(*x(!2!2CJCJc&c&@@&Q&QDD…;…;\\\/\/hh⯜ᯜEmEmRRzezeyy̛U ̛U ^Z^Z$$W/W/~T9~T9@@EEsHsHHH{ME{MEbt?bt?66s*s*e0e0;h;hSS݀ɀc\c\ Sh Shӆӆ[[_T_T Q Q]^]^wǤwǤj*qj*qqqΖΖ#w|#w|J*J*1A1ARR) ^) ^>d>dn8gn8gii&h&hdd._._VVJHJHR3R3!!22N۽Nۃ**ڣڣcc::==̹̹ӍӍ0Hd0Hd  NвNвYYʭ`ʭ`熌 z# z# l< l< P P=\=\ c c[R+g[R+g_Ph_Ph2WCg2WCg2c2c.^.^ V VkȢHkȢH66e$e$BPBPs$s$Ԁ88cc(æ(æii#sx#sx??-zh-zhM=M=eeǯٯُ  NA NA --,f97,f97Ђ=Ђ=6@6@1HA1HAJO?JO?N;N;44:,:,Փ#Փ#22ըըUU" " \ )\ )Bp8Bp8303044ww 0 0UU@d@d$*$*{ޖ{ޖNN<<**-+-+CCKDKDuuڵ׵׈ ׈ Z3Z3اnܧn◤뗤KK\\EvEvM M ,.,.(E9(E9c(Bc(BII} M} M*N*NMMIIOBOB=58=58C)C)\\$$r r K(K(G_G_77 N N:E:EiiGG}}yy==ċċ9=9=F2F2HH8fX8fXaaBFfBFfii&Lj&LjhhrOdrOd ] ]SSCCě,ě,JJD҉D@k@k\\r@r@ڍڍJJ 䘫@@$$jmjmӒMM**AA@R@R]]M}cM}còfòfh]fh]fКdКdT`T`y/TZy/TZ,P,PAA+-+-KK**\J\J--暁暁gђgђS S M˥M˥LL_ͧ_ͧMﵭMﵭӶӶ,š,¹hѹhȵ6ȵ6kkdd,, *+*+A}2A}266&8&8)7)755*90*90))AA"AA"KoKo2y2y  V*V*zɭzɭG0G0^I^Igg^^N2N2A A kk!!__XXx:x:UU=S=S&,&,//MMt[t[թթ{{+:+:FFӜӜⱘⱘ\\E E LLZ[Z[RRh h \F}\F}UzUzixix v vss]q]q6o6olljjݖhݖhJfJfydydءbءbӇ`Ӈ`r^r^\\D[D[YYalWalWUUSS2DR2DRBPBP O O|M|MKKoJoJHHGGYFYF±D±D>WC>WCjAjA@@nf?nf?o&>o&><<ϴ;ϴ;::[9[9T78T78g7g76644x3x322u1u18080//....I-I-.2,.2,Q+Q+uu*uu*))5(5(''/'/'h&h&m%m%$$*$*$r#r#""""a!a!o o - - 8n8n11nn55PP==bb5588MDMD.Z.ZByBy" " --W8W8ll) ) hhJJ797977ggsEsEǫǫ:a:a'' S S E E   . . ? ? n n l l N N   B B   n n 9 9   1p 1p :@ :@ 7 7 $$S^S^33  CC88kkEE  NN22rrQQ11eeLL ~ ~6b6bFF , ,~~ggnQnQ};};%%==""vv e eSSBBN2N2""$$==@@''  22XXQQvvjj]]QQEEf:f://##pp99kkˮˮ>>ܝܝ}}bvbvnngg``YYRRKK\E\E>>88^2^2H,H,R&R&{ { ##? ? bbJJPP((..XXKKHHHHޗޗ۔۔**bb]]~~F|F|yyewewuurrlplp0n0nlliiggeeccaa__]][[+Z+ZaXaXVVTT8S8SQQOO]N]NLLHKHKIISHSHFF{E{EDDBBlAlA!@!@>>==b<b</;/;::88776655y4y4o3o3i2i2j1j1n0n0x/x/..--,,++****@)@)o(o(''&&&&R%R%$$######q"q"!!!!n n ((VV//~~((IIss  AA""kkggrr##AA l l ( ( c c $ $ o o 4 4 X X " " Z Z + + vvKK""ZZ66ddCC$$rrUU;;  tt^^HH11bb\\33AA))  //  jjT T d d  OO= =   ))mm<<77T*T*EEcc>>bbppddXXMMWW}}2e2e..t t m5m5ff%%ԃԃ__nSnSCC ) )rrllPP??@@IICCrrVVfJfJ]]~a~a``ff  ssss}.}.4.4.vvz!z!kka'a'U.U.//bbII-w-w00XXՁZ8ՁZ8ޖ&Kޖ&KjWjW]]bbj Gcj Gc*åb*åb)*_)*_]Y]Y٪Q٪Qy Dy D4040ZZii66^ݭ^ݭmmD6D6ϕϕ))zzΉΉʶʶLL!!ŘŘM'M'77&C&CKK^lP^lP`Q`QOOLL4 E4 ENaP>PElElV&V&D,SD,S\\^i^i,,MMeezz~~ ? ?XXI-I-44uu^ ^ ]E]Eڠ"ڠ"))//y>4y>4&m6&m6X6X6P?3P?3!.!.&&N N p`p` ĥ ĥɏ;;^o^o&&ҘAҘAϱϱ; ; ʧ ʧLL'v'vH[ЭH[==>>5/5/MBMB-Q-Q[[*a*adcdcIdId'b'b'^'^cXcXcsMcsM<޻">''''. . 򶸪ض1T1T))RROOBjBj#E#EL߽L߽/z/zϵuu$s$s7 7 HJHJU.U.ru:ru:_B_B@ChG@ChG*,I*,I`?H`?HODODd?d?&,7&,7f-f-@"@"mdmdR R acac&&*].*].NNXFXF^^ISIS?&?&uu*x(*x(!2!2CJCJc&c&@@&Q&QDD;;\\\/\/hh⯜ᯜEmEmRRzezeyy̛U ̛U ^Z^Z$$W/W/~T9~T9@@EEtHtHHH{ME{MEbt?bt?66s*s*e0e0;h;hSS݀ɀc\c\ Sh Shӆӆ[[_T_T Q Q]^]^wǤwǤj*qj*qqq͖͖#w|#w|J*J*1A1ARR) ^) ^>d>dn8gn8gii&h&hdd._._VVJHJHR3R3!!22N۽Nۃ**ڣڣcc::==̹̹ӍӍ0Hd0Hd  NвNвYYʭ`ʭ`熌 z# z# l< l< P P=\=\ c c[R+g[R+g_Ph_Ph2WCg2WCg2c2c.^.^ V VkȢHkȢH66e$e$BPBPs$s$Ԁ88cc(æ(æii#sx#sx??-zh-zhM=M=eeǯٯُ  NA NA --,f97,f97Ђ=Ђ=6@6@1HA1HAJO?JO?N;N;44:,:,Փ#Փ#22ըըUU" " \ )\ )Bp8Bp8303044ww 0 0UU@d@d$*$*{ޖ{ޖNN<<**-+-+CCKDKDuuڵ׵׈ ׈ Z3Z3اnܧn◤뗤KK\\EvEvM M ,.,.(E9(E9c(Bc(BII} M} M*N*NMMIIOBOB=58=58C)C)\\**p p K(K(G_G_77NN:E:EiiGG}}ww== ċ ċ9=9=F2F2HH8fX8fXaaAFfAFfii$Lj$Lj—h—hrOdrOd ] ]SSCCě,ě,JJDҌDCkCkZZr@r@ڍڍLL~~ 䘭@@""kmkmӑMM**AA>R>R]]L}cL}cIJfIJfh]fh]fњdњdS`S`z/TZz/TZ+P+PAA+-+-LL**]J]J--皁皁gђgђS S M˥M˥LL^ͧ^ͧMﵭMﵭӶӶ,š,¹hѹhȵ6ȵ6kkdd,, *+*+A}2A}266%8%8)7)755*90*90))AA"AA"JoJo3y3y  V*V*zɭzɭG0G0^I^Igg__M2M2B B kk!!__WWy:y:UU>S>S%,%,//NNs[s[թթ{{,:,:EEӜӜ᱘᱘]]E E KK[[[[RRi i \F}\F}UzUzixix v vss]q]q6o6olljjޖhޖhJfJfydydסbסbӇ`Ӈ`r^r^\\C[C[YY`lW`lWUUSS3DR3DRAPAP O O|M|MKKoJoJHHGGZFZF±D±D?WC?WCjAjA@@mf?mf?p&>p&><<ϴ;ϴ;::[9[9T78T78h7h76644x3x322t1t19090//....J-J--2,-2,Q+Q+tu*tu*))4(4(''/'/'h&h&m%m%$$*$*$r#r#""""a!a!o o - - 8n8n11nn66PP==bb5588MDMD.Z.ZByBy" " --X8X8ll) ) hhJJ797977ggsEsEȫȫ9a9a'' S S E E   . . ? ? n n l l N N   A A   n n 9 9   1p 1p :@ :@ 7 7 $$S^S^33  CC88kkEE  NN22rrQQ11ffLL ~ ~6b6bFF , ,~~ggnQnQ};};%%==""vv e eSSBBN2N2""$$==@@''  33XXPPvvjj]]QQEEe:e://##pp99kkˮˮ??ܝܝ}}cvcvnngg``YYRRKK[E[E>>88_2_2H,H,S&S&z z ""> > ccJJOO((--XXKKHHHHߗߗڔڔ++aa^^~~H|H|yyfwfwuurrkpkp2n2nkkiiggeeccaa__]]\\)Z)ZdXdXVVTT8S8SQQOO]N]NLLHKHKIISHSHFF{E{EDDBBlAlA!@!@>>==b<b</;/;::88776655z4z4o3o3i2i2i1i1o0o0x/x/..--,,++****@)@)o(o(''&&&&R%R%$$######q"q"!!!!n n ((VV//~~((IIss  AA""kkggrr##AA l l ' ' c c $ $ o o 4 4 W W # # Z Z + + vvKK!!ZZ55ddCC$$rrVV;;  tt^^GG11cc\\33@@))  //  jjT T d d  OO= =   ))nn<<77T*T*EEcc>>bbppddXXMMWW}}2e2e..t t m5m5ff%%ԃԃ__nSnSCC ) )rrllPP??@@IICCrrVVfJfJ]]~a~a``ff  ssss~.~.4.4.vv{!{!jja'a'T.T.//bbII-w-w00XXցZ8ցZ8ݖ&Kݖ&KjWjW]]bbi Gci Gc+åb+åb)*_)*_^Y^Y٪Q٪Qy Dy D3030ZZii66_ݭ_ݭmmE6E6ΕΕ**zzωωʶʶLL!!ŘŘM'M'77'C'CKK_lP_lP`Q`QOOLL5 E5 ELa4y>4&m6&m6X6X6P?3P?3!.!.&&M M p`p` ĥ ĥɑ;;[o[o&&ИAИAϱϱ8 8  ʧ ʧII'v'vH[ЪH[==>>5/5/MBMB-Q-Q[[*a*adcdcIdId'b'b,^,^cXcXgsMgsM<> f foOƦoOƦ##ltlt:g:gͼͼD:D:,#-,#-J;J; F FkN\LkN\L!S^O!S^OӄOӄOMM2 H2 H+x@+x@p6p6ġ'+ġ'+zz++y(y(H~LH~LMMEeEeٗڗv\(v\(88{{􅑳b..b..[®[®CCQQVVll|A|A<5<5""5X5XmmˋcˋcJWJWRRCCp%p%8.8.@6@6.<.<夡?夡?ѣ@ѣ@M?M?$/;$/;O^$4O^$4))eu}eu}  KKFFxxҪ **22U^NU^N~~#d#d{{00__X X EEa#a#Lv3!Lv3!^98^98KKxsYxsYx`x`9#e9#egg~f~f`d`d\_\_9W?X9W?XsKsK99s1 s1 HaHa!2!2#C#CfLήfLήаϜаϜbbWWW[W[퍚ӍӍ啑啑kAkA¯W W ii66-:L-:LZZTcTc;Śg;ŚgiiTiTi"f"fΠaΠaO$ZO$ZGOGO޻">޻">&'&'. . 򶸪ض1T1T))RROOBjBj"E"EL߽L߽.z.zϵuu#s#s7 7 HJHJU.U.ru:ru:_B_B@ChG@ChG*,I*,I`?H`?HODODd?d?&,7&,7f-f-@"@"mdmdR R acac&&*].*].NNXFXF^^ISIS?&?&uu*x(*x(!2!2CJCJc&c&@@&Q&QDD…;…;\\\/\/hh⯜ᯜEmEmRRzezeyy̛U ̛U ^Z^Z$$W/W/~T9~T9@@EEsHsHHH{ME{MEbt?bt?66s*s*e0e0;h;hSS݀ɀc\c\ Sh Shӆӆ[[_T_T Q Q]^]^wǤwǤj*qj*qqqΖΖ#w|#w|J*J*1A1ARR) ^) ^>d>dn8gn8gii&h&hdd._._VVJHJHR3R3!!22N۽Nۃ**ڣڣcc::==̹̹ӍӍ0Hd0Hd  NвNвYYʭ`ʭ`熌 z# z# l< l< P P=\=\ c c[R+g[R+g_Ph_Ph2WCg2WCg2c2c.^.^ V VkȢHkȢH66e$e$BPBPs$s$Ԁ88cc(æ(æii#sx#sx??-zh-zhM=M=eeǯٯُ  NA NA --,f97,f97Ђ=Ђ=6@6@1HA1HAJO?JO?N;N;44:,:,Փ#Փ#22ըըUU" " \ )\ )Bp8Bp8303044ww 0 0UU@d@d$*$*{ޖ{ޖNN<<**-+-+CCKDKDuuڵ׵׈ ׈ Z3Z3اnܧn◤뗤KK\\EvEvM M ,.,.(E9(E9c(Bc(BII} M} M*N*NMMIIOBOB=58=58 C) C)\\**p p K(K(G_G_77NN:E:EiiGG}}ww== ċ ċ9=9=F2F2HH8fX8fXaaAFfAFfii$Lj$Lj—h—hrOdrOd ] ]SSCCě,ě,JJDҌDCkCkZZr@r@ڍڍLL~~ 䘭@@""lmlmӑMM**AA>R>R]]L}cL}cIJfIJfh]fh]fњdњdS`S`z/TZz/TZ+P+PAA+-+-HH**]J]J--隁隁dђdђS S M˥M˥PP^ͧ^ͧOﵭOﵭӶӶ,›,¸hѸhɵ6ɵ6kkdd,, *+*+@}2@}266$8$8)7)755*90*90))AA"AA"HoHo5y5y  T*T*xɭxɭG0G0\I\IggaaK2K2C C kk!!__VVz:z:UU?S?S%,%,//NNs[s[թթ{{,:,:EEӜӜ᱘᱘]]E E KKZ[Z[RRi i \F}\F}UzUzixix v vss]q]q6o6olljjޖhޖhJfJfydydءbءbӇ`Ӈ`r^r^\\D[D[YYalWalWUUSS2DR2DRBPBP O O|M|MKKoJoJHHGGYFYF±D±D>WC>WCjAjA@@nf?nf?o&>o&><<ϴ;ϴ;::[9[9T78T78g7g76644y3y322u1u18080//....I-I-.2,.2,Q+Q+uu*uu*))5(5(''/'/'h&h&m%m%$$*$*$r#r#""""a!a!o o . . 7n7n11nn55PP==bb5588NDND.Z.ZByBy" " --W8W8ll) ) hhJJ797977ffrErEǫǫ:a:a'' S S E E   . . ? ? m m l l N N   B B   n n 9 9   0p 0p :@ :@ 7 7 $$S^S^33  CC77kkEE  NN22rrQQ11eeLL ~ ~6b6bFF , ,~~ggnQnQ};};%%==""vv e eSSBBN2N2""$$==@@''  33XXQQvvjj]]QQEEf:f://##pp99kkˮˮ>>ܝܝ}}bvbvnngg``YYRRKK[E[E>>88^2^2H,H,R&R&{ { ##? ? bbJJPP((--XXKKHHHHޗޗ۔۔**bb\\~~F|F|yyewewuurrlplp0n0nlliiggeeccaa__]][[+Z+ZaXaXVVTT8S8SQQOO]N]NLLHKHKIISHSHFF{E{EDDBBlAlA!@!@>>==b<b</;/;::88776655z4z4o3o3i2i2i1i1o0o0x/x/..--,,++****@)@)o(o(''&&&&R%R%$$######q"q"!!!!n n ((VV//~~((IIss  AA""kkggrr##AA l l ' ' c c $ $ o o 4 4 X X # # Z Z + + vvKK""ZZ55ddCC$$rrUU;;  tt^^HH11bb\\33AA))  //  jjT T d d  OO= =   ))mm<<77T*T*EEcc>>bbppddXXMMWW}}2e2e--t t m5m5ff%%ԃԃ__nSnSCC ) )rrllPP????JJCCrrVVeJeJ]]~a~a``ff  ssss~.~.4.4.vv{!{!jja'a'T.T.//bbII-w-w00XXցZ8ցZ8ݖ&Kݖ&KjWjW]]bbi Gci Gc+åb+åb)*_)*_^Y^Y٪Q٪Qy Dy D3030ZZii66_ݭ_ݭmmE6E6ΕΕ**zzωωʶʶLL!!ŘŘM'M'77'C'CKK_lP_lP`Q`QOOLL5 E5 EMa4y>4&m6&m6X6X6O?3O?3!.!.&&L L p`p` ĥ ĥɒ;;ZoZo&&ϘAϘAϱϱ7 7  ʧ ʧGG'v'vH[ШH[ = =>>5/5/MBMB-Q-Q[[*a*adcdcIdId'b'b+^+^cXcXfsMfsM<޻">&'&'. . 򶸪ض1T1T))RROOBjBj"E"EL߽L߽.z.zϵuu#s#s8 8 HJHJU.U.ru:ru:_B_B@ChG@ChG*,I*,I`?H`?HODODd?d?&,7&,7f-f-@"@"mdmdR R acac&&*].*].NNXFXF^^ISIS?&?&uu*x(*x(!2!2DJDJc&c&@@&Q&QDD…;…;\\\/\/hh⯜ᯜEmEmRRzezeyy̛U ̛U ^Z^Z$$W/W/~T9~T9@@EEsHsHHH{ME{MEbt?bt?66s*s*e0e0;h;hSS݀ɀc\c\ Sh Shӆӆ[[_T_T Q Q]^]^wǤwǤj*qj*qqqΖΖ#w|#w|J*J*1A1ARR) ^) ^>d>dn8gn8gii&h&hdd._._VVJHJHR3R3!!22N۾Nۃ**ڣڣcc;;==̹̹ӍӍ0Hd0Hd  NвNвYYʭ`ʭ`熌 z# z# l< l< P P=\=\ c c[R+g[R+g_Ph_Ph2WCg2WCg2c2c.^.^ V VkȢHkȢH66e$e$BPBPs$s$Ԁ88cc(æ(æii#sx#sx??-zh-zhM=M=eeǯٯُ  NA NA --,f97,f97Ђ=Ђ=6@6@1HA1HAJO?JO?N;N;44:,:,Փ#Փ#22ըըUU" " \ )\ )Bp8Bp8303044ww 0 0UU@d@d$*$*{ޖ{ޖNN<<**-+-+CCKDKDuuڵ׵׈ ׈ Z3Z3اnܧn◤뗤KK\\EvEvM M ,.,.(E9(E9c(Bc(BII} M} M*N*NMMIIOBOB=58=58 C) C)\\**p p K(K(G_G_77NN:E:EiiGG}}ww== ċ ċ9=9=F2F2HH8fX8fXaaAFfAFfii$Lj$Lj—h—hrOdrOd ] ]SSCCě,ě,JJDҌDCkCkZZr@r@ڍڍLL~~ 䘭@@""lmlmӑMM**AA>R>R]]L}cL}cIJfIJfh]fh]fњdњdS`S`z/TZz/TZ+P+PAA+-+-LL**]J]J--皁皁gђgђS S M˥M˥LL^ͧ^ͧMﵭMﵭӶӶ,š,¹hѹhȵ6ȵ6kkdd,, *+*+A}2A}266%8%8)7)755*90*90))AA"AA"JoJo3y3y  V*V*zɭzɭG0G0^I^Igg__M2M2B B kk!!__WWy:y:UU>S>S%,%,//NNs[s[թթ{{+:+:FFӜӜ᱘᱘]]E E KKZ[Z[RRi i \F}\F}UzUzixix v vss]q]q6o6olljjޖhޖhJfJfydydءbءbӇ`Ӈ`r^r^\\C[C[YY`lW`lWUUSS3DR3DRAPAP O O|M|MKKoJoJHHGGZFZF±D±D?WC?WCjAjA@@nf?nf?p&>p&><<ϴ;ϴ;::[9[9T78T78h7h76644x3x322t1t19090//....J-J-.2,.2,Q+Q+tu*tu*))5(5(''/'/'h&h&m%m%$$*$*$r#r#""""a!a!o o - - 8n8n11nn66PP==bb5588MDMD.Z.ZByBy" " --X8X8ll) ) hhJJ797977ggsEsEȫȫ9a9a'' S S E E   . . ? ? n n l l N N   A A   n n 9 9   1p 1p :@ :@ 7 7 $$S^S^33  CC88kkEE  NN22rrQQ11ffLL ~ ~6b6bFF , ,~~ggnQnQ};};%%==""vv e eSSBBN2N2""$$==@@''  22XXQQvvjj]]QQEEf:f://##pp99kkˮˮ>>ܝܝ}}bvbvnngg``YYRRKK\E\E>>88^2^2H,H,R&R&{ { ##? ? bbJJPP((..XXKKIIHHߗߗ۔۔**bb]]~~F|F|yyewewuurrlplp0n0nlliiggeeccaa__]][[+Z+ZaXaXVVTT8S8SQQOO\N\NLLHKHKIISHSHFF{E{EDDBBlAlA!@!@>>==b<b</;/;::88776655z4z4o3o3i2i2i1i1o0o0x/x/..--,,++****A)A)o(o(''&&&&Q%Q%$$##$#$#p"p"!!!!o o ))VV//~~((IIss  AA""kkggrr##AA l l ' ' c c $ $ o o 4 4 W W # # Z Z + + vvKK!!ZZ55ddCC$$rrVV;;  tt^^GG11cc\\33@@))  //  jjT T d d  OO= =   ))nn<<77T*T*EEcc>>bbppddXXMMWW}}2e2e..t t m5m5ff%%ԃԃ__nSnSCC ) )rrllPP??@@IICCrrVVfJfJ]]~a~a``ff  ssss~.~.4.4.vv{!{!jja'a'T.T.//bbII-w-w00XXցZ8ցZ8ݖ&Kݖ&KjWjW]]bbi Gci Gc+åb+åb)*_)*_^Y^Y٪Q٪Qy Dy D3030ZZii66_ݭ_ݭmmE6E6ΕΕ**zzωωʶʶLL!!ŘŘM'M'77'C'CKK_lP_lP`Q`QOOLL5 E5 ELa4y>4&m6&m6X6X6P?3P?3!.!.&&M M p`p` ĥ ĥɑ;;[o[o&&ИAИAϱϱ8 8  ʧ ʧII'v'vH[ЪH[==>>5/5/MBMB-Q-Q[[*a*adcdcIdId'b'b,^,^cXcXgsMgsM<> f foOƦoOƦ##ltlt:g:gͼͼD:D:,#-,#-J;J; F FkN\LkN\L!S^O!S^OӄOӄOMM2 H2 H+x@+x@p6p6ġ'+ġ'+zz++y(y(H~LH~LMMEeEeٗڗv\(v\(88{{􅑳b..b..[®[®CCQQVVll|A|A<5<5""5X5XmmˋcˋcJWJWRRCCp%p%8.8.@6@6.<.<夡?夡?ѣ@ѣ@M?M?$/;$/;O^$4O^$4))eu}eu}  KKFFxxҪ **22U^NU^N~~#d#d{{00__X X EEa#a#Lv3!Lv3!^98^98KKxsYxsYx`x`9#e9#egg~f~f`d`d\_\_9W?X9W?XsKsK99s1 s1 HaHa!2!2#C#CfLήfLήаϜаϜbbWWW[W[퍚ӍӍ啑啑kAkA¯W W ii66-:L-:LZZTcTc;Śg;ŚgiiTiTi"f"fΠaΠaO$ZO$ZGOGO޻">޻">&'&'. . 򶸪ض1T1T))RROOBjBj"E"EL߽L߽.z.zϵuu#s#s7 7 HJHJU.U.ru:ru:_B_B@ChG@ChG*,I*,I`?H`?HODODd?d?&,7&,7f-f-@"@"mdmdR R acac&&*].*].NNXFXF^^ISIS?&?&uu*x(*x(!2!2CJCJc&c&@@&Q&QDD…;…;\\\/\/hh⯜ᯜEmEmRRzezeyy̛U ̛U ^Z^Z$$W/W/~T9~T9@@EEsHsHHH{ME{MEbt?bt?66s*s*e0e0;h;hSS݀ɀc\c\ Sh Shӆӆ[[_T_T Q Q]^]^wǤwǤj*qj*qqqΖΖ#w|#w|J*J*1A1ARR) ^) ^>d>dn8gn8gii&h&hdd._._VVJHJHR3R3!!22N۽Nۃ**ڣڣcc::==̹̹ӍӍ0Hd0Hd  NвNвYYʭ`ʭ`熌 z# z# l< l< P P=\=\ c c[R+g[R+g_Ph_Ph2WCg2WCg2c2c.^.^ V VkȢHkȢH66e$e$BPBPs$s$Ԁ88cc(æ(æii#sx#sx??-zh-zhM=M=eeǯٯُ  NA NA --,f97,f97Ђ=Ђ=6@6@1HA1HAJO?JO?N;N;44:,:,Փ#Փ#22ըըUU" " \ )\ )Bp8Bp8303044ww 0 0UU@d@d$*$*{ޖ{ޖNN<<**-+-+CCKDKDuuڵ׵׈ ׈ Z3Z3اnܧn◤뗤KK\\EvEvM M ,.,.(E9(E9c(Bc(BII} M} M*N*NMMIIOBOB=58=58 C) C)\\**p p K(K(G_G_77NN:E:EiiGG}}ww== ċ ċ9=9=F2F2HH8fX8fXaaAFfAFfii$Lj$Lj—h—hrOdrOd ] ]SSCCě,ě,JJDҌDCkCkZZr@r@ڍڍLL~~ 䘭@@""lmlmӑMM**AA>R>R]]L}cL}cIJfIJfh]fh]fњdњdS`S`z/TZz/TZ+P+PAA+-+-LL**]J]J--皁皁gђgђS S M˥M˥LL^ͧ^ͧMﵭMﵭӶӶ,š,¹hѹhȵ6ȵ6kkdd,, *+*+A}2A}266%8%8)7)755*90*90))AA"AA"JoJo3y3y  V*V*zɭzɭG0G0^I^Igg__M2M2B B kk!!__WWy:y:UU=S=S',',//NNr[r[թթ{{-:-:EEӜӜౘౘ]]D D KKZ[Z[RRi i \F}\F}UzUzixix v vss]q]q6o6olljjݖhݖhJfJfydydءbءbӇ`Ӈ`r^r^\\D[D[YYalWalWUUSS2DR2DRBPBP O O|M|MKKoJoJHHGGYFYF±D±D>WC>WCjAjA@@nf?nf?p&>p&><<ϴ;ϴ;::[9[9T78T78h7h76644x3x322t1t19090//....J-J-.2,.2,Q+Q+tu*tu*))5(5(''/'/'h&h&m%m%$$*$*$r#r#""""a!a!o o - - 8n8n11nn66PP==bb5588MDMD-Z-ZByBy" " --X8X8ll) ) hhJJ898977ggsEsEȫȫ9a9a'' T T E E   . . ? ? n n k k N N   A A   n n 9 9   1p 1p :@ :@ 8 8 $$S^S^33  CC88kkEE  NN22rrQQ11ffLL ~ ~6b6bFF , ,~~ggnQnQ};};%%==""vv e eSSBBO2O2""$$==@@&&  22XXQQvvjj]]QQEEf:f://##pp88kk̮̮>>ܝܝ}}bvbvnngg``YYRRKK\E\E>>88^2^2H,H,R&R&{ { ##? ? bbJJPP((..XXKKHHHHޗޗ۔۔**bb]]~~F|F|yyewewuurrlplp0n0nlliiggeeccaa__]][[+Z+ZaXaXVVTT8S8SQQOO]N]NLLHKHKIISHSHFF{E{EDDBBlAlA!@!@>>==b<b</;/;::88776655z4z4o3o3i2i2i1i1o0o0x/x/..--,,++****@)@)o(o(''&&&&R%R%$$######q"q"!!!!n n ((VV//~~((IIss  AA""kkggrr##AA l l ' ' c c $ $ o o 4 4 W W # # [ [ + + vvKK!!ZZ55ccDD$$rrVV;;  tt^^HH11nn]]LL;;++  }}qqddXXLL@@55**  zzssllee]]VVOOHHCC;;55//))##  ||~~ssfenrir-1.5.1/config/sound/default-wav/soundicons.conf000066400000000000000000000031131317357605400226630ustar00rootroot00000000000000# Screen Reader Turned On or Off ScreenReaderOn='ScreenReaderOn.wav' ScreenReaderOff='ScreenReaderOff.wav' # Cancel the current command Cancel='Cancel.wav' # Accept command Accept='Accept.wav' # Bell a sound if the TTY is changed (ctrl + alt +FX) ChangeTTY='ChangeTTY.wav' # Is the first Position on the line StartOfLine='StartOfLine.wav' # Is the last position of the Line EndOfLine='EndOfLine.wav' # the Line is empty EmptyLine='EmptyLine.wav' # Is the first line on the screen. StartOfScreen='StartOfScreen.wav' # Is the last line on the screen EndOfScreen='EndOfScreen.wav' # The content has changed ContentChanged='ContentChanged.wav' # Speech has turned On or Off SpeechOn='SpeechOn.wav' SpeechOff='SpeechOff.wav' # Braille has turned On or Off BrailleOn='BrailleOn.wav' BrailleOff='BrailleOff.wav' # SoundIcons has turned On or Off SoundOn='SoundOn.wav' SoundOff='SoundOff.wav' # Set beginnig mark PlaceStartMark='PlaceStartMark.wav' # Set end mark PlaceEndMark='PlaceEndMark.wav' # Copied to clipboard CopyToClipboard='CopyToClipboard.wav' # Pasted on the screen PasteClipboardOnScreen='PasteClipboardOnScreen.wav' # An error accoured while speech or braille output or reading the screen ErrorSpeech='ErrorSpeech.wav' ErrorBraille='ErrorBraille.wav' ErrorScreen='ErrorScreen.wav' # If you cursor over an text that has attributs (like color) HasAttributes='HasAttributes.wav' # fenrir can promote strings if they appear on the screen. PromotedText='PromotedText.wav' # missspelled indicator mispell='mispell.wav' # the for capital letter capital='Caps.wav' # general announcement announce="Announce.wav" fenrir-1.5.1/config/sound/default/000077500000000000000000000000001317357605400170375ustar00rootroot00000000000000fenrir-1.5.1/config/sound/default/Accept.opus000066400000000000000000000030031317357605400211420ustar00rootroot00000000000000OggS`9S9OpusHead8OggS`9>OpusTags Lavf57.41.100encoder=Lavc57.48.101 libopusOggS&`9J jloolqsv{x3U:8QזEEEU̺aXN8ڰ6/L\vE̐?/QlIռ5A հBD9D9=5aE}} dD0sg^oAo%_;Hm/_i+2YsB}eorÄV:/Vq/n w60 1UNe7 .2b~mBFfyDUTpL.bBXȏ\R/J c6@+GPKͽz*d$.`oҝNG ~lmG0V 2$= ^)n,9⻛e `0_ъkb,'ði#TI" gwj`!zBevz-e;ʷf@ hZ?{lO:y8~CxEZ 2%EּkUڸGB!v2ϱ=F*6~C5>&5PLNLuZ )'tHBjP)Df*_-itԌXB$6uK |[l_Dfenrir-1.5.1/config/sound/default/Announce.opus000066400000000000000000000066551317357605400215310ustar00rootroot00000000000000OggSoJwOpusHeaddDOggSox!]OpusTagslibopus 1.1.3-98-gee44ff8%ENCODER=opusenc from opus-tools 0.1.9ENCODER_OPTIONS=--bitrate 30kComment=Processed by SoXOggSIo͎k۹yXD5is^`yxk`I9vօzIV|CJ<̓GG-1;t \D=#|aPGSuǚܻYIuzhx?8`A`| D߭mƈfI=Y_3oCxr!I}/((ȢuBE{sdBdavm*g2$6-Ds BNJULpanȼT^ȭww up!am\Z6 :cZ Ta_@ ؗښňI(Hb8"$SWݎ'^;tMnWa5y&| E8ۘ@-.Zsw4AbDLPA> fA-GISÊ/9=ϳP6AdpZx(yv%pјs7=vPŜ-&}R~? `,.aMU }ņxI|%U.`/3Aĥ֫>aLS5g ]x`ư^MT2A'H_R)1& l#  6ԟ.'vt,[73 'fޜ0d[YH[_N;W78Lm(Mۀ֔ (U3SbΓ<> O?>c?tg{Y7A[ݢ" h~y}F{Cٴ qL7Z %BYf|ԛ\{FL|/K2% /87 Eg_h:Sq/+t->kHЛ⸠D<ڗ^;w hj0=焗W #`6.鎗>[V8q=$BBQw0\ *[X.LXz~nM{Wy/i0`\Fn2o5ejq'5f;~An^z e2P6a9IŋaxvMPI-(㻓]f$X8Cx'Ġ!C3"k?| d #j|v<٠# G"FVnM5A,$3BζW &&*@:4EMQuƍH3x7vǒɟiZIIECFk*Tig-"{UˆigjKn X. nfTSuMvNKȊê/)Sk \L~+Dt.0 ͆t@UPk Ae0{{nH)Kؼ2pZ{a=~mT 9-n$8T2lT)f]sĘ#y7PQ) ZAi:IE_ bbqvZn"^q9>;FI&ydȭ\F5$W r,`Z0ChAzv:E> `ԕ ț !^,H^^iSd.kZvgZnrovY\Qv`A=iP S (Sfj|8Mw*\Z7?niͼdfٰz%qq ըR :VYo@&yBTf8mnyK 4p1sh]|=S|:ety6:^ ’up =+oI[;\__ ßf$i;cdF o{:aV=xz/D(BE-琹9_T??w{"VуQ[9<|/3w֞^ = |QZca.*fmਓVNIx,3 %m$m 阞a_9#]|iҸ^"Q5$G+9{v\lːŬ{]TnRMTuv)򕵮~XWfQ x1U@%|[=FZ:-ŘZ1 `SnQnNqk( e[CF`f;ȝ1&w-fenrir-1.5.1/config/sound/default/BrailleOff.opus000066400000000000000000000104121317357605400217520ustar00rootroot00000000000000OggS'E:uOpusHead8OggS'Egp1u>OpusTags Lavf57.41.100encoder=Lavc57.48.101 libopusOggS^'E{ν𴪪||vCj†D}.Lr/P+H(ug2b8a{ !4.$%B}8JmjNGdKѻK " Qթ:)]>RG65Wr] 8h>]nzRM|-đ)ti-SfŒD!aׂI3A]0 a  yfFL}xz%h"*"vOy~L_C@ vMI߆7j.pүӊXpq'ȁgtX`oLt gTF6ȥAϳORf 2Vsyo Nt2E)]}! v(Y":}ۿO lSpW|:n^,PU8x n:et5ڑ=G&ՓxJ!ŀOHd+9"i @%j+& ˉv~gvMpG'CV6ϨBœ 6]2(": 9qPٞ ,˦>:*p"TpBG>6&㇭{йH4x3Z%M&هG*?FrЍ!v+Gm`Z mmᥟcZ̙Ni&쾷zZĩе5ᆭpOC0V%M 7B{Tw-wFPNw뎿 (ό{r_QϏGxFѠޚJ7n/JBpnKgYfK#X‰z a`00kN݊`|F~b"&uDɟ&=r!\ނe#&4i̩k[+ Rw08.ˁK5>țY~sRQ0frx"@;ehfS a5w.Ц/ dWU>0m弦tk'w˼'`)3,!I`(UsCm}zQAk./]T7,9jUgT' Cg #ɱQC(LKb lBa%C?RjKLXf>2'CyyU%mty!L:Pm?uTK/^gVöEy3sn]6V! eU;n.I1A/~ (Vo!ZƂ !zP8j-XM|gx7g>rɔ5;8|, KDL{ -dm̗NA={DfUُaX{FLJ{lA.3=uIhOo7 _.lc[/5)Q;H7tgdy[ ZBv[kLU)wLOXt{` EvW3|óL, ;)1/M0=} vUF;+(^ xa!֡:]Ā`3&'kDv OI,4~JmڳPOipZ|ԕ(nE "H%p"L!240j|*?~Oy 쓀\A κv_] eM&ص|n@zwphp0R/p+ |mp)p6ӳ>$K3)-f醅+rl܃Qw5>>2 ȱ;;}`׾@Tki 0&]`v3B?`ϳց1Vk֬[|EwrgURz-E*0B|{D&\ohcN\2c؂QϤFˣfbT/=;8?bjP~ƀyxTil|v܂#O("tɋ#KdV$&k#^;S^'y̓Ϝ*>iKϞlI*~ᆫmM'F$g+A2 #2} >'Bq/WhF=ՠ},y<۶fL0vD7oVqRVw0nj*^MZ{iQ4tC߯npQsg˯0əw 5 6ԷY+$ruȡyi1:7XtuB2gjyn)Vf/yG`f)pl*?xQ?u sS]ڂG? W&DaI0KI.\r"GP=CyK\)-|Ϳ:fO6M)uI"!nZ%N !֌;I"j8҉4ToMʆR2pS(@gГ `7Mh V @tg!rF@!L᪈U~V[,f<TPL(OBUFnjraf巆fenrir-1.5.1/config/sound/default/BrailleOn.opus000066400000000000000000000102021317357605400216110ustar00rootroot00000000000000OggS0=-)OpusHead8OggS0=- >OpusTags Lavf57.41.100encoder=Lavc57.48.101 libopusOggS^0=-kvwae?3_ EHVtX<4L#1*\ r`C,1}QB&!PD.Oa߅ ցT?܋ ʔ@96 abLmu"IȒG7bWfQf=JxXpsQxg!1ju~ULr)a:3F)rNuN@#fo  >yR2(zs ߔ߱$O QIk<+&hF`{k~^ݬ_u%S<-q2y{:Nxs$"z$۷˃>@ڻ8VMn( pXv\e.\2[{L>)jc߃-OWl2_nz4OsCrf3ROo-A+/}V a>+[$~fXkEoN.7\[І[B6 e">z7rZ†"v8afw F{_Ld}F:jJ:$m $ۓa(iC:A"xOOPW ~\'2M&1\.^f t+)j8OCHA "J_ʴD;ɌҚͪfX`$w(,f%* oDvۘ[[ z n$| Z&l~+j!0$*A]LEY I0C?vMn,t(%L%@?B̖ccJ.-LԘchu.<+uZ7ĸf#RH 1a99PFmOL4f25;IظهpPQ|v0q`/Ј,&Ґpgu踭Eqz  = jS`]2Tm*P(_l0;_vP "1ݒn!Z)e[mo7^fvX3a0xzU3vE6@"猾vkR>U@S*ojZ2.۬-O@SӭwH#O$=wReq5' ](M$[ ]ұ#\7,s+.Ua@aŚ9zf_6],^rnW3Sr-\_Xu=Md-ˎ&3) lP?:0>z% ?6pe0,ao`i_WEo?reഅI4&bCN+qqWY|X`3pӜLdU5L"ti6V#(^>Ds#jIUʎD /_š\ܴVdpWRN_tTjFI>rX=nW[) }P9T 0ňΏ^QF٪߾Ĩ5d ^+RU5g?E;[Kj߻|\kzBMXnθ&eND0s у/:]TC7,D|ɥ GILooj lH\/Jx(v ~rij.8,b97MvIb$dl9c_S|{y(-ݓqů.DŽN]IqOV3;?>2X:pI>)Vp3`1UZRO;dF=ǀU7] G'$Ym+2I?I_SFebR!W`.B:&{KGql2椆w^ƒ 4AD4#k%sP*ΩN PpЬۃ}> _ O$EvF:)D\LGEMi/A'$<NwR EL9ױq̆wА. m]D8$U1 E{$\oWPZX{J-3s)MN[v-opmxqa8" ㏛S>>:=PtsLR ]1"N#YG4ڊn*mkhh?hY䍎N,䍍up3 틛K%Si9Q% tpxO*z]v."c"m;[=NF)3B͟PM D]Z+Q~.jZ~Fq^*?i+61`8nQk0rF[M% ,CkIcwiR%?OQd>'S9t-fЏa0_ I s{^QK,0½%|f0$$)398>:ؗMTEcG(6jBqN'=stCc83P޴. {wWt$w_^}ywOpusTags Lavf57.41.100encoder=Lavc57.48.101 libopusOggS&GPH& vrtrhpjJLlr).YjYOq#BƠ)R$*yc t"+.0H]$UP7|EW':ސujA"TK^vFJ,̍X]ptcݢLDO^F}]_Yof]n8+9G'|qkx#Lsm즥o4>SyfRҜ[Y5G_nV+P8MFi:ɧE u3ߦ+!6dԷF $JS>JȟZ79yELM}M A=u7A$8nrh0N|s"q ܜnqS N_"4J+%\xS`ʻ 1zD2ARu(#8îE 7nd k>^w)+2}< >䆆q|8fF^B.0IcuYkRNfZ4;Y;+X tU[mO)s6iBV.rY)Rq J¥B?& L\z#CLO yͅ| g}Jm'덆!tږ%j}5.aP\v1\Q<]Bsxpmgl' ~holM^dw$,hc]PԞ@5t9kD { hNI#-т=|7q9f-Vr:ٕLY'6ߞ!j7p,P&V$h.|q[Yr=sLljl%8G Y+w&Er[zyMܝ4# FWmlJ;ϓv62mHu(xUI/G qs.{l˞Pęl7)0LdDT0ZU b zdXZlmSsc QtT..Pi'zh(dԬQ li ;<][eg>~%W\\~4MnR>_q+P5D%sfp٦IN : rC6,pWWP&x #ҵUׯ;ijGDz[Y59mk!۝@?d UXa~zNޞ譟;q_9x[-90sMP̧GZVj +S})c>Ip[8[X<_m5oLWBZ@4ˏ_,7\Ӯ*k(]V̤S.>:'7kaW ?: m7oP1a^z 'wsCG#gw[F8jB);ʾC3Z3Z}xQ I^$q c:Ӳ=I>ҷQHu3؍9tu-2P ufenrir-1.5.1/config/sound/default/Caps.opus000066400000000000000000000004121317357605400206320ustar00rootroot00000000000000OggS(q OpusHead8OggS(qC>OpusTags Lavf57.41.100encoder=Lavc57.48.101 libopusOggS(q22x}&4Ϙ%mN#*f8!K ? /C?xe : R1Y8 Lh+ysc9v0bOpusTags Lavf57.41.100encoder=Lavc57.48.101 libopusOggSXjJf8eQ-k Yrզ>~w}{޳8l $~s'kكgkWf?&km;ϙQF rb8erڲIM|fh &HT^q<@ vŘl~ :yO8g6qlZCåfd0{8ʒi ) Tª̀`j5V WgE˔?2|jpDM4;!)þҊmc/kʂs/hÂDyy}}S*>siZGU8 њvwuIi*J'8 H 2L]oycen(8>=j/+TAM KFb=Q%4CQl|"̮VoIWxYZMbyQL 4k9s~?4#8 ׇWt3 p10fKeMi^.97e49K*e< JW'(RW7%P"*<;ҳ :_% +oeNWPCʡ ŠcbәNcT+,,t?@U X9ྀ%0䈔@uj5Gd¹_p5 V2.1؋;U Wk(Le/@h>;7_y֙_Ϥ{՛?#?,6 eAvj6AhV#5^>vU}4eĞziKFFcy !JoƑCXK|I]&?[*H֌ dji,iMֵke(!]|1Dg&95_ܫYnC+AK-`U>T*屗=Ʊ zl:~X0qޤZەvR݆L.y.~d+M&{rpiBmܢN@ЈlFڤ\Gx:W2nS>RnrHz>=yw DXJV8+(xeIyCt-;os;9]JJeJ´ϡ~dS+,IOƸN˧ǛNds,p JօOq'M79 ,^!fenrir-1.5.1/config/sound/default/ContentChanged.opus000066400000000000000000000012621317357605400226340ustar00rootroot00000000000000OggSɦCDQOpusHead8OggSɦCc\>OpusTags Lavf57.41.100encoder=Lavc57.48.101 libopusOggS ɦC-mL}L&IeebtOh2~aZ\[FuSM/#2WATdwH)߷q6\ vZ%)u%BјBՈ@q3 tS5S &0D*gu j3wl_QPthi+~{6 |rH?¨?}e)@>9JjgG!r#${ F;/.ƙc.{GRʍpu˃ƁOL%R߼?5S`qW#:p %id,s&x=3ɀi}bqKVgbB[)`-*!zƑw:8巘sDDu_0a3`ED^cO"$vxgw:̗E=5(Pp?*WO^x%1+#H 1D+~+qJYvRjskvVk[幋 2@ "fenrir-1.5.1/config/sound/default/CopyToClipboard.opus000066400000000000000000000051661317357605400230140ustar00rootroot00000000000000OggSaimЫPOpusHead8OggSaimJ[>OpusTags Lavf57.41.100encoder=Lavc57.48.101 libopusOggS^aima&jqrso[eoFCIHHJKKKLLHIFrY"E2V(xɠK YBGl$8e9bL%gҳґ[ tb{UO6Y^%mu zH&Z:Nn ?n.TT׌ryA ߤ1FTbÛ * 8R؂\$ nx BW-F1L5ň}awiP^S"E:KykGy.uf?K/ 'H9 PQy79@*ߪi%4ͬ[CpL1/Es8#%cF/Bq%5l RH"?'ڋCDc=B";qfuu}g5 7%R d3 0Z,YeQ:&*0$TXCAf< ~*45nA>ܢy69LgT1hi~k&<%tgT^s4QLh Ay}DЕnhHvf aw0n>C!l] 7B:UP8/^h nUA-X&®|Ls5AQ/"1a~Kt!KH 9"bO F)[̺/˾S/H>^"ZBxM9^d$_C:1OhƘ6s,gOMs'o 01L2p6+Hy.aٹ:B\%^pu,Ќ; /'<9w5k{pGZ5 6֤׳Aӯs.I^ُs!/@(Ush/K,&b6;W=-WPhmn5k!$]>"x}_č/)d pG9@>"&e-㓗 jBleKn~ 50YZTdF`xcZpz d ώ72g/,IQ%|iOJ_dvy$| ޷h^vX#guwZ7˰TVZ8h%j:K hL,~ix 5~,1x[ ݚu; 4Q^Xtc2 _f$?L 6Nk QVBA+?|冉͈_ *hNc)@As+Sd|" W)=y|JZj =NJ}2ՉF; +UI[%t&7O,+yyBaO݇i@Ke|Տ8CwWgX7:02)g:̈GwTvqfב߱~8u/@1<C@ot|q5hdr`oܹynhvvĴDހa4xݚXH!&EBY{⁰|rYe ly}5_~a>OGKRHc jI b>fO|D9rAXmSJ>>7طxґ݉'Jq2TatY\P_S^9G4AK|0ю^g6wCݣ) \z9li 'F!oƼbg28<ot|MγgS:P1bVqY}h%)WK;pDD%w&kp| _0X?@ %CՎeOpusTags Lavf57.41.100encoder=Lavc57.48.101 libopusOggS3p@T^|'.GxhK9GKv"5""ҫ%jr PV\?͕aYJkDj:UWgįt{ Y@nRDp#ZO=:EFYsLej`7ʡ5.o]|Vi"\):gX*^5gyHRF9`lKfg}!IQL />W0a$dG!  2Ԧ:]B ㎄+8)SyqwWKb 6%4fenrir-1.5.1/config/sound/default/EndOfLine.opus000066400000000000000000000010101317357605400215420ustar00rootroot00000000000000OggSC!-AOpusHead8OggSC!A܀>OpusTags Lavf57.41.100encoder=Lavc57.48.101 libopusOggSC!UE5!=J mZJ?OWJ5'qY{4i%tsPOHo&;HA0H ?܏PnՐ<"v饑fڙ%~gWpb$>.2 Gɶ|LDh_Vy/H60?i7X<4l%yEfo&pkW#m{A;?QR j!% [{k#yoe9JN3w۸(v` +9ˣ9QXO&&c4{!,F{O՟>$N:1[EU ?TTfenrir-1.5.1/config/sound/default/EndOfScreen.opus000066400000000000000000000010321317357605400220760ustar00rootroot00000000000000OggSsuzOpusHead8OggSs >OpusTags Lavf57.41.100encoder=Lavc57.48.101 libopusOggSs J 'F/V(ʰ8%/ ,`W1:)oX`d'SU Y\O%tw{y%?51 "u< Q_{3]TᎌI$Qܲ.[PE %ߪͲu |͵-JAݛg 7z$ GP!)OxW󉚸7 ]}fOjLD{J >hzP"jR/W u͐RsO;цS?-yCG y??,+L``ݙ4@~ *g~"Z$fenrir-1.5.1/config/sound/default/ErrorBraille.opus000066400000000000000000000045611317357605400223410ustar00rootroot00000000000000OggSi4WOpusHead8OggSi4&9>OpusTags Lavf57.41.100encoder=Lavc57.48.101 libopusOggS0i4/ $+`H b.J^P5tPdRs"N_ #_:>@ gE.r] թz>/vy:\xs-I(EE2|bū)N32x>}Y:ru8y|KD` /3,2( B-L,$%HCb1@^abdՒOHu=-[ z6=zpCn >> JEً VqIgSTE# K҄T]`\\)Pm2һ1w u]ƽ^){bOK*! qQ\D7CGeq?k?x.tyڛQki"vR+FlW-UDlrpӖqA$+>}2# B\?EDԆM-J uy9mм>LPgMoaTy5t& si#kZiLwT8PFlWS%TqƟxBz6 sIf%t!_4|+DgRHj8[ߥ[FB+@I2B 7WKT\ʱ{<4V|IZS@ #F" BZ3<@VRYj݄Fj؋ avX8aNb k\v2SPǍ[RήfGZ;'' =d+(WY邟%k&@J|Wzr.ͱ$$WoA^~t .-e4^"Ze!z7|n#v\ͧHn-Pl]a.:G҉y {:ʷ!*7K3 =Ag%ƒ}\cZIC"|nxXj}1[Mv  O{x/(/pI-!jT2۽k>urLHo'\b8 [+G 9N2'm; %a?M9SG}[5sՏ>kG;5qex{E+[$ Ħe9Y:t}5bҋ eR UE@3!1̗ `ݿ^-Z+FtR EF^8B㪶F+Qq2t@0Bi!+&&ksJHkD,G r.;~*ޏ~z| x;S gV))iPZzq(W(wUs~Zr3׶d°:tMyՑK av5g{(͘:CNphu I@pC*h_䐾4sX~S\F@4 U ؾ.܊ÉP,d&iw홅V+M[la) ?)8j[jf}#ሑĭjyX]B2.MBhղ(A =/YgNWA~ovVͅٹLuR'(te6k9Gz./6eɍy zG$fά tu*8,hIíϦqny&Hث׮Jun#؈qRst ioPؙ\m^=MU^8sLz:\\=%~ P}>ON5T ଶoȺ-:=;SSҮ2{s*5rևhAM5~@y[4{Ca<฿E?Cg̀@xtrn/xH/GEkWY16Jk_0,rJ+F/ɦkZ*k?J{;a3RThk0OpusHead8OggS>>OpusTags Lavf57.41.100encoder=Lavc57.48.101 libopusOggS0>0f $+`H b.J^P5tPdRs"N_ #_:>@ gE.r] թz>/vy:\xs-I(EE2|bū)N32x>}Y:ru8y|KD` /3,2( B-L,$%HCb1@^abdՒOHu=-[ z6=zpCn >> JEً VqIgSTE# K҄T]`\\)Pm2һ1w u]ƽ^){bOK*! qQ\D7CGeq?k?x.tyڛQki"vR+FlW-UDlrpӖqA$+>}2# B\?EDԆM-J uy9mм>LPgMoaTy5t& si#kZiLwT8PFlWS%TqƟxBz6 sIf%t!_4|+DgRHj8[ߥ[FB+@I2B 7WKT\ʱ{<4V|IZS@ #F" BZ3<@VRYj݄Fj؋ avX8aNb k\v2SPǍ[RήfGZ;'' =d+(WY邟%k&@J|Wzr.ͱ$$WoA^~t .-e4^"Ze!z7|n#v\ͧHn-Pl]a.:G҉y {:ʷ!*7K3 =Ag%ƒ}\cZIC"|nxXj}1[Mv  O{x/(/pI-!jT2۽k>urLHo'\b8 [+G 9N2'm; %a?M9SG}[5sՏ>kG;5qex{E+[$ Ħe9Y:t}5bҋ eR UE@3!1̗ `ݿ^-Z+FtR EF^8B㪶F+Qq2t@0Bi!+&&ksJHkD,G r.;~*ޏ~z| x;S gV))iPZzq(W(wUs~Zr3׶d°:tMyՑK av5g{(͘:CNphu I@pC*h_䐾4sX~S\F@4 U ؾ.܊ÉP,d&iw홅V+M[la) ?)8j[jf}#ሑĭjyX]B2.MBhղ(A =/YgNWA~ovVͅٹLuR'(te6k9Gz./6eɍy zG$fά tu*8,hIíϦqny&Hث׮Jun#؈qRst ioPؙ\m^=MU^8sLz:\\=%~ P}>ON5T ଶoȺ-:=;SSҮ2{s*5rևhAM5~@y[4{Ca<฿E?Cg̀@xtrn/xH/GEkWY16Jk_0,rJ+F/ɦkZ*k?J{;a3RThOpusTags Lavf57.41.100encoder=Lavc57.48.101 libopusOggS0~&q $+`H b.J^P5tPdRs"N_ #_:>@ gE.r] թz>/vy:\xs-I(EE2|bū)N32x>}Y:ru8y|KD` /3,2( B-L,$%HCb1@^abdՒOHu=-[ z6=zpCn >> JEً VqIgSTE# K҄T]`\\)Pm2һ1w u]ƽ^){bOK*! qQ\D7CGeq?k?x.tyڛQki"vR+FlW-UDlrpӖqA$+>}2# B\?EDԆM-J uy9mм>LPgMoaTy5t& si#kZiLwT8PFlWS%TqƟxBz6 sIf%t!_4|+DgRHj8[ߥ[FB+@I2B 7WKT\ʱ{<4V|IZS@ #F" BZ3<@VRYj݄Fj؋ avX8aNb k\v2SPǍ[RήfGZ;'' =d+(WY邟%k&@J|Wzr.ͱ$$WoA^~t .-e4^"Ze!z7|n#v\ͧHn-Pl]a.:G҉y {:ʷ!*7K3 =Ag%ƒ}\cZIC"|nxXj}1[Mv  O{x/(/pI-!jT2۽k>urLHo'\b8 [+G 9N2'm; %a?M9SG}[5sՏ>kG;5qex{E+[$ Ħe9Y:t}5bҋ eR UE@3!1̗ `ݿ^-Z+FtR EF^8B㪶F+Qq2t@0Bi!+&&ksJHkD,G r.;~*ޏ~z| x;S gV))iPZzq(W(wUs~Zr3׶d°:tMyՑK av5g{(͘:CNphu I@pC*h_䐾4sX~S\F@4 U ؾ.܊ÉP,d&iw홅V+M[la) ?)8j[jf}#ሑĭjyX]B2.MBhղ(A =/YgNWA~ovVͅٹLuR'(te6k9Gz./6eɍy zG$fά tu*8,hIíϦqny&Hث׮Jun#؈qRst ioPؙ\m^=MU^8sLz:\\=%~ P}>ON5T ଶoȺ-:=;SSҮ2{s*5rևhAM5~@y[4{Ca<฿E?Cg̀@xtrn/xH/GEkWY16Jk_0,rJ+F/ɦkZ*k?J{;a3RThOpusTags Lavf57.41.100encoder=Lavc57.48.101 libopusOggS ҹq}_5p87ށE T"5$5ܐ.%*0a(MYu`fqm{z8v RdFbIFbmnbmmziՌYKKo,-םf q Яi{]wq)5EVi~[66TύGv]s|mHٴZV7>߻_[MƗ*)6A9D7<-Cw4߽|W0@(} ^ Z]25SYP^$n.?)!x8w(EpM6ܔ4lyi-5ePtYn;Y>SE~AC=Ph49vϴKWBŊhu:W?FjxNp}iט@ix/y_AK2wzvA12i&/0kR T[ KD7-FaGE?7ΧN:fenrir-1.5.1/config/sound/default/PasteClipboardOnScreen.opus000066400000000000000000000021371317357605400243030ustar00rootroot00000000000000OggS(+FOpusHead8OggS(+R>OpusTags Lavf57.41.100encoder=Lavc57.48.101 libopusOggS(+ A=>E|?mPBI 0rdϠ$,7^K}heef}LO\WEOHrszb Tbg5'"zw#OYhxSGpHl|Ǿ/ۣWHipu&?h1jfenrir-1.5.1/config/sound/default/PlaceEndMark.opus000066400000000000000000000011471317357605400222400ustar00rootroot00000000000000OggSB;YaOpusHead8OggSB;Y4>OpusTags Lavf57.41.100encoder=Lavc57.48.101 libopusOggS B;YK>|W:ڄ̕^L w150 21ۏ4k/<<ʄ u!῵4eLZDIkey(Ől޳W,Bz}Lf qp@Ѡ#3׊^AURvGn6F5۴Bh_pUL]Cɗ^ ,Ѱ1‰hY55x6OpusTags Lavf57.41.100encoder=Lavc57.48.101 libopusOggS }k | ? VXRن&*nH ij&vYtqOg}At&6XcdL:Q)#=Vo!p7~n+D9g,ZLpN^u (PM0PU.+V>޲K CېB)@  6;BW[E) KDA0{ LC5Xp ZH"Slk;+z)eGymE^'i<wC?h=Mj 09|ՃoQ/+2`~^N BEZ5Oᒬ*&]h BuM&IaUTg~S&%x#c ))@h, i􎈜&LL-oj<fenrir-1.5.1/config/sound/default/PromotedText.opus000066400000000000000000000023151317357605400224060ustar00rootroot00000000000000OggSo]rOpusHead8OggSo]Of=;OpusTagslibopus 1.1.3-119-g5da0498%ENCODER=opusenc from opus-tools 0.1.9ENCODER_OPTIONS=--bitrate 20Comment=Processed by SoXOggSo]ojnJDOAFx*D~xMQf7w\ky aLxu O/e^Lf쵭++rO)Rx PVi4Qhmܰ &I| Ua}L}ߨn`P5g"VxjЍəuuq/3x?CZl,ށ:%vy!zK?hfϹMK(f֐X c!17?x]Gs晠pm[1=LumY ):jb ;UУ75[mvxKyw*$1/EsU&;rԱuIj=U+cf!2ʉ8fenrir-1.5.1/config/sound/default/ScreenReaderOff.opus000066400000000000000000000117701317357605400227520ustar00rootroot00000000000000OggSM4QV,͛OpusHead8OggSM4Q >OpusTags Lavf57.41.100encoder=Lavc57.48.101 libopusOggS؍M4Q,-&}{yxwxuuspmkjfhfd|B=ڤ*b6!FƈE4Uy(]xsb g1 5ebI)kO5↶FWgW8gEv d`yB򰩏9m;6k1d4 \-6ЕPߊp6,갍!!o% 2{Y-f v]-\:-̡9r劥 Z mgtW0VRϷ *w0Ad"96kP sG-!wq{ڈ>YyЬl{|:"v[ϡ5{l_{*&OuhƩgCk(YFT0T| rXι YNYXIR" >Y|гRG2ZSeX3[-b򸶕};7[*_QٜeEU[Ё?:t@}r(D{7ہdՖ*+eKDo`LdRPXObfq'^%%شk h|v/g; Di煹o8c]lE?OCC0E`=bơ}ԫ1^mق KJ@Wt\=ɀ6i((H~UH u"C<49=Okk>ȉ bM?BF]lO w)}:@|b -0%2V Gg.&( ? O=&H2:8% r>g\ywp验V%}(74Pc2 `݆lh3珕L2&,֙@")o8l$<-(wkN~[ 4":0+ ن@6y6<GsѓPoˆm9n,xVF7d_kAwwWw%3!^ڠlVS zamm")U3hzj$@Orߥߖ>0K5oO7KH.}}oJ9g{JltT54A_6Hl ~șTv?\oڲC􈀢^p C:l^890h. +)w|8{g&|c RΒ)x~Q/8Mf)g(bPlL%r}q/d֗;ȍǒ`\+ Xmrz\ob`_|4;r-ŷݶ\>su'3UzoC)$=y*ET;:L˦DV&h ǪN1t{x Jգ@٘%0D_ #ʝ `{`LJGM}X&W݅Q+k x3tWDZq^97Hg7KQ?SBL%q!z@Л  lS ~n:U!.0jE2FC*@zvc f-aAPe{fQ.yѓ >7nV{ `DyDu=Ü,ײvnhA-GƼ˧ `/ '8Q8^bDh''CHv ᷂?!k"AUes(s⊖>y;K`Zs2D 1iToS0M+$U.]N]c$QJRLN3]H%G )Uc8]h}Ek*7JcS,+Jx?w<}ITH|S֯&AQF*== Wޯ5d٨;p(Ű%Qw4,Qrwc,*4\2OsGƼzBpkbV%'>3l"0w."0<#,Z1$lTP)oWSH^=wZʨ]7r QyZ2%QOHJ* +GπqZr"Gķ:6>=1ަu5"c_#L oG!ٝ7U?~쭢5qV0R$@i !}9E\:zU`+!~8Etyei=Gƽ٢[5F/)1 omiWgSCzdJ I`F9)Kf{ؗ s0CBwL?L##T~ m,RiG\&3P v4U^G A$>wf>:pr4k8}EjGLsbIs^M<򧽏iz(pJ zU !m]AzA]Aj9PSyD;orGƽ2ucQ`z7pMTt('ݿ~Tr#XQzC/CXS(Bd{}} 5#TwWDRr  ;ꓖ#Q$G B'h}N+;IyJ a}Ւh?YwҠ_Y9ȟs ۪ i5:z~ ƣtJ*9mF VQ!dG<-<îzUܯp)BM}=Ul'x&=?3qAq6+yS|0{^ 69~gY`u>p@! Gƾ[XTw6)mVKW}Tcqwg)Wr?aL&_cZI6/;Ikd9ԩHiyB#t*ۣ :Fq\#d"譽&uE\Gʕ"I^eDU\di05w̓*dbfJFtGKa[/N .:߂bG//׽!!:|61t=_*GZ+8\G ݫ]'=)EQDn~37$|recFύhahy-u)MvQ,*Z.Y"lNo²ca8Gʪt @F}=<_d_}Xe.~*!9 dhPfBiou vy:L[uDDCS.5xJ5WgŠt+GҧoR6cQje`TV=©I+6InZ0o6{"UaGUC :b>͍(%RW᜘̺n @Leu)wDN[>£Bܸp#Ofvg}ZTJ;!O6vb֓[acCeY~* l^ǠG4.PC{PԵ<޲˒3PnPHZy~{A"00mT+uq@۱C&,K;Ƹr }#,Z'zk9Mͤ h!R)҇2L Gڋd0]Z3S|J.b4FV<@GO{_; Η` af oK^EKBǿ{kW=oLk \Xfn-!QS 囙F$FXn`!sB}fVC߲ &K  8&Ah!?Y4A*ݨ9,~Iyd?@q*$F깇.D@.Q[זOF=:#BGhQɸxMfa% )L]ǥp=7 +WU tGY+սJߗߴ_ OPylzo#Ӧ=y;ܔSqlE8_[☌l^q.5 <tO<:Y!W?w ` L7Fom2 AFHN{sd.K_wџ̙Q/פ0Ď[3D"1TKw _<a"J 8Dz>D*ٴrQ.pKURHp:Np/S~-G?P˩W|ʈ;cPfenrir-1.5.1/config/sound/default/ScreenReaderOn.opus000066400000000000000000000120731317357605400226110ustar00rootroot00000000000000OggSTOpusHead8OggSe>OpusTags Lavf57.41.100encoder=Lavc57.48.101 libopusOggS؍O&~z}{ytxqplkfjh|vK?m q'4EIٶ Wj Y>D{sDrYE4ion|T^3T =[1˦ VmxĝCB$&.)}ERRCIx#Gƚ“Bv-ȆE{+1C?*B :%kaF}nУLӔC%̌3#7))v"k7qLUmi b[V:I.uTe&-c47Ps( G#)F,4L9(͟oE۬*YQ?bJPٟ"*zES?hv%"XU3 JJyBFG2Suq'J~E\ A-$[ku-e2xU{F RJQsB-GC͟5ƱkWo \{'Mmp~iŸpPB# \Yf)yΨ#G|#&"FSWIM5H- # ȿ"M&rh?YwQ4Ҡ_|ϙu%#:Qʻ c\$y8eZ^ 7#X#r#WͳGZ#zoEVbc u8jSA*Ŗ5qj·!ģR3qjE_Fh1 d_03D1sӱY[u}@"ΜޢB5kg?ʄ$Y,[K15ڮ`^oY|Pأ! zn}$#\g4s {eCplk,=$7'S{y[UCw0AvrHuVnO˄lOIJgd" wp)C/{UdMih찍 K,_>!ܘmPchm :˝Z??LFke-b^Pܯiv܆ۏ&уV޻块U@-:qSN_D ㋲TwM5L?aQ[Dqh8B BIx#k 9Y AGГ4MTV}1NKza [;QQ ۖZTx]ɝb!\xL<0Y#rH;~"c bȟxB %Tky7Qsk!Θ:8f%Y7Oξ"HtZ GSOt(/ l!'\~E;]JvĆۗ'/)<&Y*ګZP+aTf fҝ&>Gs-Ap;ü(X]27GKV{[oXݨch+EVg]ĘI6AտƟ- $R1儆،E-`_Oz7~I0yO*H|o~-~``~S{'C2@?>h90L~qxۑ+G;N֫E2P&DCT~\P[.C%&t|ۖygzu6%FT/ӵ=Z{_D;o/!:uaX:h͊^=zl؆ p4/gbvaD1[ѓ!݇ٱع3i(B AWR33;Z'g2C~u+a"zFUw7h;X nb|R=~Nz) ¶YVbUő'UseLtۖM{AF7g],1Z6808i-TbsʛmC0e2?U׻Q9Agv} .N?f\Yx FZ8 DƯ΢qT ؏Fi9qiOj  ʽ˺#1xJq1b w9O\ ''iS2a$fd-Tqx vKo*ͱY?`o.'k76$i`4U!yp$Qaؘ< ӏwY#Er u-V=:iĶ_TWbx \YqUU1t$) Y~Q"՚5rf\-MmfJ_2FEm5Ǟ]/pWDPM))2 :.TPi;.O  a g᳼+S1l,n֫f|*4|*\.B*FĨ2Qɥc\ʤ^69C+VU<4W/*X׿']|]rapc"[x0 [oHE1? ĄsRnݲ= DȦI!*pzBy䌯Z7'4ܬMlI=%Gr· u5 ;NxV"Z%ZmZ1w15Q| E9.qlGbi! W,9 #{Y LNHOVł17}H8(\6T(.Q֫sb*,tbkl"nGY 321P;lX\M ;įyIs EWqCZn)WlUDfoL#>r3a}2B.n"mw'71i -aR}Aq!??wm题 ige0d{' ѩL=rz? et>t>]40,0;u77-=̀tIx\v-VfNے1qpm*lBUD>f죺i3P*91qqEv\3%w:ۆ|;d d qv+|ф ]Bu1#]EG9 wEʝr3<;'7+vaApvJw4[g\bI e+D%&x+Ug|=C V#OU?<c~R a.]42IG\yA?a HmO||6TT`ԃ ؍v'[z`{YJD9:s*vHUT|7=k|=5kصY(=@Ppo<e[DnUލgkUA $ :fXTmivA?gL$GdK'4(I`%%39ݶ8]"&r5)F<ۢBra/|w1 xU\쪐*DȘ$~kԆ\⟼?W0ʈU"_,OpusTags Lavf57.41.100encoder=Lavc57.48.101 libopusOggS& \ ۷rӲgl]bppIIO~[ۍuNj^)  o g%_E2Z"* ֫@Fܫ$72?*OSNY$n5IcsÞ13#L@v b)wkk#^ {Xwa|Wrm6^B$?$jRhϑaG֔K8>K/C%NMXSNdSR*mh.̨t :iVO)b,Ȣȵ։xy"!(sI~wH9巅8[fؑqRAjh X,YC-.?|ZvfV?h(H {܅}^NQ5!V 0j&mXCXC=@Sv%6 ٬d\E|/yۙ mDrPVlܢ}ϼ"S0a0myggSVU(AVye5_gl]'`.IAytki*t+`J[L}^~3.,/Ix}`*uWKXD}&)f%6 \l 4Sc; 9^8vJD5$(]JkB7Zxƚ))2SZ$+o҉PG|r]țR45YFco򿎀!Vz$ʲ0ख !ș< Ok$VT:cֳXoфB: v6A5 ]r'CU:U<iF4q: ~Oy ]Y};KêgcfU$$K\5iC*1h0MGX3>%n fTDɋSVApR3yyMNěAk~+>d%¸7H/YÕm>\ITNBkY^FlYt\SK R=蹒ȱhD52t:{&.Vo^La"MimK.]dnhNn_=otizwAמ+\Hg8QTXsW\bc(OpusTags Lavf57.41.100encoder=Lavc57.48.101 libopusOggS&4%/ }K( hJpP<ֺ$;o\:ܸ=*N_`%CLc˚Se v8ttCe=H ^޶nKwنeo(+Xq!Px H)uM]ze'e.`̗^I>vFoޢCg&WҾ: kjTA0٫ hb$BUPVy"4f{^ɏ? 0u+ɞN'XcGa[u:H@I P-Xx[:,ނ辫hn(A$MUnP !.8HuHÔ!}6a0=;ͯ&eGb'HA_ :WQȨ77=޽yp4 ( )P3{j`L:t#;wqHAk j4efAXtE?xA$eN}'\ w#<_|%a`A.t4Un=LX19vYq"ư8Ih CW;?iGwԞH8nâ:cS3k=ۗ}p<̉;{m&:0^ QI˖7{>ux}}p^skzIq"K4θR %p th8:i~Uؽ!LIMO_LƌHe}H_w& E2氽D 9NttLTT.-L s^xCmOpusTags Lavf57.41.100encoder=Lavc57.48.101 libopusOggS^$AņҵtxCj yS~r j8܋ޅ ʉAy%!Ҫ35MawA ;Ce]bSřf*?nxJ\+z!`wNE:>%!q#jz+В坯xzRM|-đ)tiad;HŹ^C"Bwַ`!ݱ*1eh޿_ܞFSX6AD >X`dj7hΨ0lsX$sٜϩ#_*R`mP"=v ʕknB^6ᡀt7I(}R;#p ;n"Vh4GU"8vmMɉqG4 MQ#XF->lPg< ޠ57NAe`iBL@ٛ:  6^ĠC<0qaz*Ѵ]$FE4O!uPۄ`:Q>pLv붘jI OY"*ŵRCuG,J;RDĤ9^NQi~DEu #:3= 16t _Os<oT22ؐ] YF=EWWdJedU #+xMW 4F/zv&Wg3BnRl5Dz mnsfNX%= xzAeYMbSaX"X}ܳiU!I.e'>z>I㏎j|77-lP& O9^$TM1Ϊ㍽ \'D50 Qx 0TM@&̘Xga|*|`Bj#Ϛ.Rr+M._ Y-wj8N~mB.*/t ]ѫ:u0r`@2/5aGcTochq%ݾ+@Tf(ݤmKqMih~5lO T*#t.˳_1BoqО9J$+Em*)b*cʏ N93FǴ0f0 6jĽ˹PF3MZ ^wbW=Lˈ4i3OÈs^SAUG,Θ23fEm*\:O-)iDI=6Rސ&[/[F:!esc1ڛgoc+j1n-1(`[X+^u5LFiefeMCBHoV9:8Bw/k,D K jM;ǔT8k>I_BYG;p#}nv6wq5?ՈJEq6[C-yĘ)uŢMKdb;X [MIME"4Fx qA7ͷ['c"F jmA"8uZk RZRDI)[NЧ@t1 T! 1m&Ğ6(<@ EP\ŮTRPZӹ= I>DsE߮ v y Q$ا4,f&B>&#s(t3Jqα_I &=]OT:zd&N`?W(F/E@^>Al3H5wL&U:=Y[.Ss1^>'F,hpjvN1\99ʍ]N..6x*-/#o1N{i+%D2 :N"]GBL)M֌N]N6 =V -0|c'u8k rŋ ڇwFO :UH˻:P^6ٷcMvL1 qnOVy=P`!Ma F&;QX@f 6tA3K鄨l_ixzѵ7ԗaTwZyW .׊|/eOojNZChME7Ehy77g_ffΖ+K>?o!CǙ &2Js>u5+вN<0G92{:t<8k;~'e[^p|Y Og FI{EJ6=bŲN֛){׋㐸Tcd @A0r[7;m~f'}SF: ErjL #B\+:j&J>X٣>?fw[? rLJ9l>KkUC>>_hB}2d" d:bJHw|Ɗ]c@- 8W)}p<4Ma5K |{5K#lZ5Ւ3(YJ@Dđđ3ZĿTュ~y2w4 -MᕠKk| [` W.FF^́S~&D&vG\;8nX P5KW mF 2Mc|E$9n6,YM{vv6ǻ}>L;p|YG( r'p:]u9(g-tJyt i*BMh4 A|~s-qJx5tnz)k Sc}NRzpY4eP rYgIU 3o[ 7W2b=KBUXIsYxw@!/⷗Ui{-xgkNga:M*ݫbrk`9+YvuGc3N}B.01H:SޜH2Q5" c0Wh=CIBWn )#Bz&F[ 7P+\mj=zuLbGsxG2eSm*7p7f38mFÂ7BBt=jAE&SV+Mxؔ򾺘Pឞ?e(ik"%gΞezNf',%l eV֖/U.T #S?fXO%-g6 H9Sa6G_.OВ+GYu7g@競Vvvrw8}@ҎoE3QaYa}$l\zWESMv.Pm519 ڰ;an ]֗ڼFYHw6w\U?O*m#ێ?D'$T\7ԗoI@;:lוgp3ʡ3¸k=LT@4pL[p lfenrir-1.5.1/config/sound/default/SpeechOn.opus000066400000000000000000000101401317357605400214470ustar00rootroot00000000000000OggS o.OpusHead8OggS o|z1>OpusTags Lavf57.41.100encoder=Lavc57.48.101 libopusOggS^ o_}[Hy $ U^yqūL-T“h%C1ҩѴ?$k6rUnչU"kfL[|g^T҈dHڕ@k+jɧ< &>7Rj9DK$[ާuqTo.Ƣ[e=F$5_e c0BK"<3֧d]U2(w l2t8H_^g,\A* QV@=o`·+ [&30YRg>Ap _ȷv^}lVDy,G9nx!s\f*F4=٧wH>Dӱ>5A bOb<꘱ ]ihzaݘ` ]Dk=TY3tVtn\!ddenD1YnS0﫭H[F G-nb/"kqY|:srdD<Ҳphx/q0O@S }?$W-zAV@#:&?(9^ద@ fz",g}ly[Zwp } ໅|IZ*Ee3RD4 ΖsPC18O9I(M|݀e=PHaut`vߗYsq9z|Bu2Z.u|h|{)q~F@(F_]LRhG3_)~dϢNQocdq},B*?#Ȫ s@=nL_IߩZUuVGGoUsY24*"5O!f$0OaV]/IyA7[8lEQ!-e )հSHf-(;d4.n2u-_Vؗ9ȬvD]D3,+o5:U6uEJ&aBex߽͞66 /1JgKY\?$a a?G֍Mׇ0~"pk=:08REU\lUӁI1:u'.r,l* @i(Tk/:Eн:nLɎSl,ϖao}:VMs ӎ;fyIU8>DO9Pp̿G)8< i/0"SH+,麀Xc I32Ӈ]o:i,Us "{P XHSEO'tt=XhNbThr6|_>A:Ͱ*K>X;5JzP["$EUz8>:Ypfh"h]簌"Fu{Wyz2:O9dR8@wPBt=ibfR 2^J~!E*T.Fz:Mb e+[aE"uFt`ǒbG^z? MfdM$E$ 'T~&ԗ0 2;8[~3$ك˫՚BI,W3NHD>vZ0 \U)MHw,dK\YWREOO PCT:,Q\A{u ))>B^+ylNX) (?]nt ]-+mW>HRZ/f$pdZJ♎a6HJd ݦjE_Kn Z1rwG?39x[M`ʀ:KyXPr8f8ㅉ+%EpO-ϛ:U k i[I )HmKWռVC0<[K XѝHDRl`ms%G>׸,~MI6#5L7wvulP;W<|o-(\X?<o(]|F!ߓK [1(msDb*p)/ލ3xɡ)O:d޻{)~ u_W]0<,]z[|ȯ<4H3$={ILzͺaD ?w4ex4Po/?dif_ɬ ]{uSϊ7A!RdNM LtCnd|6HXm^=:4'JN$T|U<"RnBרlqF|Vh ZȻ 9-UMS U`~?b8 S]YĒIg`~L %1f5aDV2UsNq۶ ^ %875.>֧ÙMp ]y 螼Lքa:<Ģ%m c: %\|o\N2}H r?.8ö]-t"`Of2oNJquF.`<4=IMA׆t eè*@f΂m2?߀Ljaԏ3 K4a};[Ä hZ F0{Q-(H)'ڻح5 Q=];Y^lsF>)r4`0'Fq*RnYqWabZm *I"9ŋt= <u#ʸW7ܒART^!.5$C? m)0\qHeb;#Xc*"!9]P|ˆ8ݜ!fzUㄭ6%2"}rdǧB+;ao=_S W@/·z,)We)Aˁ0ԭvuhsXzWkGEҙ$d7cc0aH.OxJd-bdKO" 2Ȏ %}zbbіlHƵE1>exf^Ώ| -VICr"Bన;-nn6,ٲu!r*[%r'ӓn9sxo 9\l>C;˂Dq'M"@v~X]&6#6A;|R<fenrir-1.5.1/config/sound/default/StartOfLine.opus000066400000000000000000000010101317357605400221310ustar00rootroot00000000000000OggSlN u;OpusHead8OggSlNSwf>OpusTags Lavf57.41.100encoder=Lavc57.48.101 libopusOggSlNxph>J mZJ?OWJ5'qY{4i%tsPOHo&;HA0H ?܏PnՐ<"v饑fڙ%~gWpb$>.2 Gɶ|LDh_Vy/H60?87X<4l%yEfo&pkW#m{A;?QR j!% [{k#yoe9JN3w۸(v` +9ˣ9QXO&&c4{!,F{O՟>$N:1[EU ?Tfenrir-1.5.1/config/sound/default/StartOfScreen.opus000066400000000000000000000010471317357605400224730ustar00rootroot00000000000000OggSΌǚOpusHead8OggSΌ>OpusTags Lavf57.41.100encoder=Lavc57.48.101 libopusOggSΌr |E,/}Sť@ N .?DBh$I@%I$_>dܺSlP6nOFQgf 3@!љ9b7TТ[%NV2e/1u<~n\jP׋LI <:oiȲ9Y/D*M1C\c;:#=쓇hL+㡧b@L[AL)sE١n3-Ty 7BIòZDx0R.\9/@({C(9)1OekXO V?o1 kD3e~B6?q2۽nT;>@f5/  fenrir-1.5.1/config/sound/default/mispell.opus000066400000000000000000000026401317357605400214160ustar00rootroot00000000000000OggSiN0OpusHead8OggSie$OpusTagslibopus 1.1.3-98-gee44ff8%ENCODER=opusenc from opus-tools 0.1.9ENCODER_OPTIONS=--bitrate 20kComment=Processed by SoXOggS&iFo 5127:71277 xM3?2t9[ 4@[ծ~-b*aڦ%sxlSa jLoPy^A|g0 /,Z~xSo0Ukm)R|dĪ8.@FE^~x.r܍-bA ;x6,0ӥ&׉!x什UחLJ^1C=Ee$ƗY~g{ x*f)Pȴ3)K \}FSpx /,x`/BdA7{]zov~}^6-́}P/,Z~xSo0UkW0)FL~- BwJ*~x.o$aBf:+1$ k- KD=}"0.M!x什Uח.͆K%Xj5%PqHk'y`x>@2XzzXDm.fhvA=fenrir-1.5.1/config/sound/default/soundicons.conf000066400000000000000000000032241317357605400220730ustar00rootroot00000000000000# Screen Reader Turned On or Off ScreenReaderOn='ScreenReaderOn.opus' ScreenReaderOff='ScreenReaderOff.opus' # Cancel the current command Cancel='Cancel.opus' # Accept command Accept='Accept.opus' # Bell a sound if the TTY is changed (ctrl + alt +FX) ChangeTTY='ChangeTTY.opus' # Is the first Position on the line StartOfLine='StartOfLine.opus' # Is the last position of the Line EndOfLine='EndOfLine.opus' # the Line is empty EmptyLine='EmptyLine.opus' # Is the first line on the screen. StartOfScreen='StartOfScreen.opus' # Is the last line on the screen EndOfScreen='EndOfScreen.opus' # The content has changed ContentChanged='ContentChanged.opus' # Speech has turned On or Off SpeechOn='SpeechOn.opus' SpeechOff='SpeechOff.opus' # Braille has turned On or Off BrailleOn='BrailleOn.opus' BrailleOff='BrailleOff.opus' # SoundIcons has turned On or Off SoundOn='SoundOn.opus' SoundOff='SoundOff.opus' # Set beginnig mark for copy to clipboard PlaceStartMark='PlaceStartMark.opus' # Set end mark for copy to clipboard PlaceEndMark='PlaceEndMark.opus' # Copied to clipboard CopyToClipboard='CopyToClipboard.opus' # Pasted on the screen PasteClipboardOnScreen='PasteClipboardOnScreen.opus' # An error accoured while speech or braille output or reading the screen ErrorSpeech='ErrorSpeech.opus' ErrorBraille='ErrorBraille.opus' ErrorScreen='ErrorScreen.opus' # If you cursor over an text that has attributs (like color) HasAttributes='HasAttributes.opus' # fenrir can promote strings if they appear on the screen. PromotedText='PromotedText.opus' # missspelled indicator mispell='mispell.opus' # the for capital letter capital='Caps.opus' # general announcement announce="Announce.opus" fenrir-1.5.1/config/sound/template/000077500000000000000000000000001317357605400172265ustar00rootroot00000000000000fenrir-1.5.1/config/sound/template/soundicons.conf000066400000000000000000000023401317357605400222600ustar00rootroot00000000000000# Screen Reader Turned On or Off ScreenReaderOn='' ScreenReaderOff='' # Cancel the current command Cancel='' # Accept command Accept='' # Bell a sound if the TTY is changed (ctrl + alt +FX) ChangeTTY='' # Is the first Position on the line StartOfLine='' # Is the last position of the Line EndOfLine='' # the Line is empty EmptyLine='' # Is the first line on the screen. StartOfScreen='' # Is the last line on the screen EndOfScreen='' # The content has changed ContentChanged='' # Speech has turned On or Off SpeechOn='' SpeechOff='' # Braille has turned On or Off BrailleOn='' BrailleOff='' # SoundIcons has turned On or Off SoundIconsOn='' SoundIconsOff='' # Set beginnig mark for copy to clipboard PlaceStartCopyMark='' # Set end mark for copy to clipboard PlaceEndCopyMark='' # Copied to clipboard CopyToClipboard='' # Pasted on the screen PasedClipboardOnScreen='' # An error accoured while speech or braille output or reading the screen ErrorSpeech='' ErrorBraille='' ErrorScreen='' # If you cursor over an text that has attributs (like color) HasAttributes='' # fenrir can promote strings if they appear on the screen. PromotedText='' # misspelled indicator mispell='' # the for capital letter: capital='' # general announcement announce="" fenrir-1.5.1/contrib/000077500000000000000000000000001317357605400144565ustar00rootroot00000000000000fenrir-1.5.1/contrib/Archlinux/000077500000000000000000000000001317357605400164135ustar00rootroot00000000000000fenrir-1.5.1/contrib/Archlinux/fenrir/000077500000000000000000000000001317357605400177005ustar00rootroot00000000000000fenrir-1.5.1/contrib/Archlinux/fenrir-git/000077500000000000000000000000001317357605400204615ustar00rootroot00000000000000fenrir-1.5.1/contrib/rpm/000077500000000000000000000000001317357605400152545ustar00rootroot00000000000000fenrir-1.5.1/contrib/rpm/howto.txt000066400000000000000000000001421317357605400171520ustar00rootroot00000000000000https://stackoverflow.com/questions/880227/what-is-the-minimum-i-have-to-do-to-create-an-rpm-file fenrir-1.5.1/docu/000077500000000000000000000000001317357605400137505ustar00rootroot00000000000000fenrir-1.5.1/docu/DokuWiki-to-Markdown-Converter/000077500000000000000000000000001317357605400216435ustar00rootroot00000000000000fenrir-1.5.1/docu/create_manpage.sh000077500000000000000000000003701317357605400172420ustar00rootroot00000000000000#!/bin/bash # needs pandoc and php installed # remove old files rm fenrir.1 rm user.md # convert to markdown php DokuWiki-to-Markdown-Converter/convert.php user.txt # convert markdown to manpage pandoc user.md -f markdown -t man -s -o fenrir.1 fenrir-1.5.1/docu/development.txt000066400000000000000000000000441317357605400170310ustar00rootroot000000000000001. Basic 2. Commands 3. Useful API fenrir-1.5.1/docu/fenrir.1000066400000000000000000002054371317357605400153320ustar00rootroot00000000000000.\"t .\" Automatically generated by Pandoc 1.19.2.1 .\" .TH "" "" "" "" "" .hy .SH Fenrir User Manual .PP Fenrir is a modern command line screen reader written in Python3. .PP It has a modular structure, a flexible based driver model, is highly configurable and easy to customize and extend (see Developer Manual (fenrir_development_manual)). .PP Please see the following pages for the current (fenrir_current_version) and Git (fenrir_git_version) version of Fenrir. .SH Support and Requirements .PP Fenrir requires several drivers to interact with the operating system. .SS Speech Drivers .PP A speech driver is for communication with the text to speech system like Speech\-Dispatcher (#SpeechDispatcher) or Espeak (http://espeak.sourceforge.net). \\ See section Speech (#Speech) in \[aq]\[aq]settings.conf\[aq]\[aq] for more information. .SS SpeechDispatcher .PP This driver is used by default. It uses Speech\-dispatcher as its backend. .PP Dependencies: .IP \[bu] 2 Speech\-dispatcher (installed and configured, Documentation (https///devel.freebsoft.org/speechd#sec2)) .IP \[bu] 2 Python\-speechd .SS Espeak .PP Uses Espeak via Python bindings. .PP Dependencies: .IP \[bu] 2 Espeak or Espeak\-ng .IP \[bu] 2 python\-espeak (https///launchpad.net/python-espeak) .SS Generic .PP This invokes speech via a sub\-process. This is almost the same as using the commandline. The performance depends on the overhead of the speech synthesis application but it is really flexible. .PP Dependencies: .IP \[bu] 2 Espeak or Espeak\-ng .PP The Requirements are flexible, they depend on the configuration in settings.conf. .SS Dummy .PP this is just for debugging, logs are output to the screen and logged as well. .SS Sound Drivers .PP To play sound icons and similar.\\ See section Sound (#Sound) in \[aq]\[aq]settings.conf\[aq]\[aq] for more information. .SS Generic .PP This driver is used by default. .PP Dependencies: .IP \[bu] 2 Sox (http://sox.sourceforge.net/) with opus support The Requirements are flexible, they depend on the configuration in settings.conf. .SS Gstreamer .PP if you prefer to use Gstreamer for sound output. .PP Dependencies: .IP \[bu] 2 Gstreamer >= 1.x .IP \[bu] 2 Glibc .SS Dummy .PP this is just for debugging, logs are output to the screen and logged as well. .SS Input Drivers .PP Input drivers are to capture keyboard shortcuts issued to the screen reader .PD 0 .P .PD See section Keyboard (#Keyboard) in \[aq]\[aq]settings.conf\[aq]\[aq] for more information. .SS Evdev .PP This driver is used by default. .PP Evdev is the low level input device framework for Linux. .PP Dependencies: .IP \[bu] 2 python\-evdev >=0.6.3 .IP \[bu] 2 pyudev .IP \[bu] 2 loaded uinput kernel module .IP \[bu] 2 exclusive access to the input devices Read permission to the following files and services: .IP \[bu] 2 /dev/input .IP \[bu] 2 /dev/uinput .SS Screen Drivers .PP The job of a screen driver is to get the information of current screen content.\\ See section Screen (#Screen) in \[aq]\[aq]settings.conf\[aq]\[aq] for more information. .SS VCSA .PP This driver is used by default. For Linux VCSA devices. These exist on any current standard installation of Linux. .PP Dependencie s: .IP \[bu] 2 python\-dbus Read permission to the following files and services (or run as root): .IP \[bu] 2 /sys/devices/virtual/tty/tty0/active .IP \[bu] 2 /dev/tty[1 \- 64] .IP \[bu] 2 /dev/vcsa[1 \- 64] (VCSA manpage (https///linux.die.net/man/4/vcsa)) .IP \[bu] 2 read Logind DBUS .SS Braille Drivers .PP This is for Braille support. Braille is currently a work in progress and is planned for the Fenrir 2.0 release.\\ See section Braille (#Braille) in \[aq]\[aq]settings.conf\[aq]\[aq] for more information. .SS BRLTTY .PP This driver is used by default. It uses BrlTTY (brltty) to communicate with with a Braille device. .PP Dependencies: .IP \[bu] 2 BrlTTY (configured and running, Documentation (http://mielke.cc/brltty/doc/Manual-BRLTTY/English/BRLTTY.html)) .IP \[bu] 2 python\-brlapi (configured, Documentation (http://mielke.cc/brltty/doc/Manual-BrlAPI/English/BrlAPI.html)) ## Currently supported platforms .PP Currently Fenrir completely supports the following Platforms: .IP \[bu] 2 Linux TTY Support for further Systems are planned. .SH Installation .PP Fenrir can run without installation. It just requires the dependencies are installed first. .PP We recommend to try it out before installation to be sure everything works and prevent yourself from experiencing a non\-talking environment. .SS Try Out .PP Fenrir does not require installation. You can try it and make sure everything works before you decide to install. In this way you can be sure that your system doesnt break or stop talking. for that you can just grab the code and run as root \[aq]\[aq]src/fenrir/fenrir\[aq]\[aq] (in foreground) or \[aq]\[aq]src/fenrir/fenrir\-daemon\[aq]\[aq] (in background, used by systemd for autostart) .SS Install it .SS Documented operating systems .SS Arch Linux .PP For Arch there are PKGBUILDs in the AUR: .IP \[bu] 2 fenrir (https///aur.archlinux.org/packages/fenrir/) .IP \[bu] 2 fenrir\-git (https///aur.archlinux.org/packages/fenrir-git/) .SS Manual .IP "1." 3 Download the latest stable version from the Fenrir\-Project (https///linux-a11y.org/index.php?page=fenrir-screenreader) site. .IP "2." 3 Unpack the archive .IP "3." 3 Check the needed Dependencys by running check\-dependencys.py (https///github.com/chrys87/fenrir/blob/master/check-dependencies.py) script .IP "4." 3 install the missing dependencies an standard installation requires the following: .RS 4 .IP \[bu] 2 python3 >= 3.3 (and all the following is needed for python3 ) .IP \[bu] 2 python3\-speechd (screen) .IP \[bu] 2 python3\-dbus (screen) .IP \[bu] 2 python3\-evdev >= 0.6.4(input) .IP \[bu] 2 python3\-daemonize (background service) .IP \[bu] 2 python3\-brlapi (braille) .IP \[bu] 2 python3\-pyenchant (spellchecker) .IP \[bu] 2 your language for aspell (aspell\-\f[C]\f[]) (spellchecker) .IP \[bu] 2 sox (sound) .IP \[bu] 2 For an individual installation see Support and Requirements (#Support%20and%20Requirements) or consult the Readme (https///github.com/chrys87/fenrir/blob/master/README.md)) .RE .IP "5." 3 run "install.sh" as root .PP this installs Fenrir as the following .IP .nf \f[C] *\ Application:\[aq]\[aq]/opt/fenrir\[aq]\[aq] *\ Settings:\[aq]\[aq]/etc/fenrir\[aq]\[aq] *\ Sound\ Icons:\[aq]\[aq]/usr/share/fenrir/\[aq]\[aq] \f[] .fi .PP to remove Fenrir just run uninstall.sh as root .SS Git .PP if you want to get the latest code you can use git to get a development snapshot: .IP .nf \f[C] git\ clone\ https://github.com/chrys87/fenrir.git \f[] .fi .SS Auto Start .PP To start Fenrir once: systemctl start fenrir .PP To enable auto start on system boot: systemctl enable fenrir .SH First Steps .PP If you are using Fenrir for the first time you may want to take a look at these resources: .IP \[bu] 2 Keybindings (#Keybindings) .IP \[bu] 2 Tutorial Mode (#Tutorial%20Mode) .SH Features .SS Commands .SS Keybindings .PP Normal commands can be invoked in two ways: 1. Using a Metakey (FenrirKey (#Fenrir%20Key)) 2. Shortcuts with a single key .PP See section Keyboard (#Keyboard) in \[aq]\[aq]settings.conf\[aq]\[aq] for more information. #### Fenrir Key .PP The Fenrir Key is for invoking screen reader commands. Fenrir can utilize more than one FenrirKey at the same time. By default the following keys are used: 1. Insert 2. KeyPad Insert 3. Meta (Super, Windows) .SS Script Key .PP To invoke "Scripts" the Script Key is mandatory. The shortcut is encoded in the filename of the script. See Scripting (#Scripting) #### Desktop Layout .PP .TS tab(@); l l. T{ Shortcut T}@T{ Command T} _ T{ FenrirKey + H T}@T{ toggle tutorial mode (#Tutorial%20Mode) T} T{ CTRL T}@T{ shut up (interrupts speech) (#shut%20up) T} T{ FenrirKey + KeyPad 9 T}@T{ reviews bottom (#review%20bottom) T} T{ FenrirKey + KeyPad 7 T}@T{ reviews top (#review%20top) T} T{ KeyPad 8 T}@T{ reviews current line (#review%20current%20line) T} T{ KeyPad 7 T}@T{ reviews previous line (#review%20previous%20line) T} T{ KeyPad 9 T}@T{ reviews next line (#review%20next%20line) T} T{ FenrirKey + KeyPad 4 T}@T{ reviews line beginning (#review%20line%20beginning) T} T{ FenrirKey + KeyPad 6 T}@T{ reviews line ending (#review%20line%20ending) T} T{ FenrirKey + KeyPad 1 T}@T{ reviews line first character (#review%20line%20first%20character) T} T{ FenrirKey + KeyPad 3 T}@T{ reviews line last character (#review%20line%20last%20character) T} T{ FenrirKey + Alt + 1 T}@T{ presents first line (#present%20first%20line) T} T{ FenrirKey + Alt + 2 T}@T{ presents last line (#present%20last%20line) T} T{ KeyPad 5 T}@T{ reviews current word (#review%20current%20word) T} T{ KeyPad 4 T}@T{ reviews previous word (#review%20previous%20word) T} T{ KeyPad 6 T}@T{ reviews next word (#review%20next%20word) T} T{ FenrirKey + Shift + KeyPad 5 T}@T{ reviews current word phonetic (#review%20current%20word%20phonetic) T} T{ FenrirKey + Shift + KeyPad 4 T}@T{ reviews previous word phonetic (#review%20previous%20word%20phonetic) T} T{ FenrirKey + Shift + KeyPad 6 T}@T{ reviews next word phonetic (#review%20next%20word%20phonetic) T} T{ KeyPad 2 T}@T{ reviews current char (#review%20current%20character) T} T{ KeyPad 1 T}@T{ reviews previous char (#review%20previous%20character) T} T{ KeyPad 3 T}@T{ reviews next char (#review%20next%20character) T} T{ FenrirKey + Shift + KeyPad 2 T}@T{ reviews current character phonetic (#review%20current%20character%20phonetic) T} T{ FenrirKey + Shift + KeyPad 1 T}@T{ reviews previous character phonetic (#review%20previous%20character%20phonetic) T} T{ FenrirKey + Shift + KeyPad 3 T}@T{ reviews next character phonetic (#review%20next%20character%20phonetic) T} T{ FenrirKey + CTRL + KeyPad 8 T}@T{ reviews up (#review%20up) T} T{ FenrirKey + CTRL + KeyPad 2 T}@T{ reviews down (#review%20down) T} T{ FenrirKey + KeyPad dot T}@T{ exit review (#exit%20review) T} T{ KeyPad dot T}@T{ cursor position (#cursor%20position) T} T{ FenrirKey + I T}@T{ indent curr line (#indent%20current%20line) T} T{ FenrirKey + KeyPad 5 T}@T{ current screen (#current%20screen) T} T{ FenrirKey + KeyPad 8 T}@T{ current screen before cursor (#current%20screen%20before%20cursor) T} T{ FenrirKey + KeyPad 2 T}@T{ current screen after cursor (#current%20screen%20after%20cursor) T} T{ \f[C]\f[] T}@T{ cursor read to end of line (#cursor%20read%20to%20end%20of%20line) T} T{ \f[C]\f[] T}@T{ cursor column (#cursor%20column) T} T{ \f[C]\f[] T}@T{ cursor line number (#cursor%20line%20number) T} T{ \f[C]\f[] T}@T{ Braille flush (#braille%20flush) T} T{ \f[C]\f[] T}@T{ Braille pan left (#braille%20pan%20left) T} T{ \f[C]\f[] T}@T{ Braille pan right (#braille%20pan%20right) T} T{ \f[C]\f[] T}@T{ Braille return to cursor (#braille%20return%20to%20cursor) T} T{ FenrirKey + CTRL + 1 T}@T{ clear bookmark 1 (#clear%20Bookmark%20X) T} T{ FenrirKey + Shift + 1 T}@T{ set bookmark 1 (#set%20Bookmark%20X) T} T{ FenrirKey + 1 T}@T{ bookmark 1 (#read%20Bookmark%20X) T} T{ FenrirKey + CTRL + 2 T}@T{ clear bookmark 2 (#clear%20Bookmark%20X) T} T{ FenrirKey + Shift + 2 T}@T{ set bookmark 2 (#set%20Bookmark%20X) T} T{ FenrirKey + 2 T}@T{ bookmark 2 (#read%20Bookmark%20X) T} T{ FenrirKey + CTRL + 3 T}@T{ clear bookmark 3 (#clear%20Bookmark%20X) T} T{ FenrirKey + Shift + 3 T}@T{ set bookmark 3 (#set%20Bookmark%20X) T} T{ FenrirKey + 3 T}@T{ bookmark 3 (#read%20Bookmark%20X) T} T{ FenrirKey + CTRL + 4 T}@T{ clear bookmark 4 (#clear%20Bookmark%20X) T} T{ FenrirKey + Shift + 4 T}@T{ set bookmark 4 (#set%20Bookmark%20X) T} T{ FenrirKey + 4 T}@T{ bookmark 4 (#read%20Bookmark%20X) T} T{ FenrirKey + CTRL + 5 T}@T{ clear bookmark 5 (#clear%20Bookmark%20X) T} T{ FenrirKey + Shift + 5 T}@T{ set bookmark 5 (#set%20Bookmark%20X) T} T{ FenrirKey + 5 T}@T{ bookmark 5 (#read%20Bookmark%20X) T} T{ FenrirKey + CTRL + 6 T}@T{ clear bookmark 6 (#clear%20Bookmark%20X) T} T{ FenrirKey + Shift + 6 T}@T{ set bookmark 6 (#set%20Bookmark%20X) T} T{ FenrirKey + 6 T}@T{ bookmark 6 (#read%20Bookmark%20X) T} T{ FenrirKey + CTRL + 7 T}@T{ clear bookmark 7 (#clear%20Bookmark%20X) T} T{ FenrirKey + Shift + 7 T}@T{ set bookmark 7 (#set%20Bookmark%20X) T} T{ FenrirKey + 7 T}@T{ bookmark 7 (#read%20Bookmark%20X) T} T{ FenrirKey + CTRL + 8 T}@T{ clear bookmark 8 (#clear%20Bookmark%20X) T} T{ FenrirKey + Shift + 8 T}@T{ set bookmark 8 (#set%20Bookmark%20X) T} T{ FenrirKey + 8 T}@T{ bookmark 8 (#read%20Bookmark%20X) T} T{ FenrirKey + CTRL + 9 T}@T{ clear bookmark 9 (#clear%20Bookmark%20X) T} T{ FenrirKey + Shift + 9 T}@T{ set bookmark 9 (#set%20Bookmark%20X) T} T{ FenrirKey + 9 T}@T{ bookmark 9 (#read%20Bookmark%20X) T} T{ FenrirKey + CTRL + 0 T}@T{ clear bookmark 10 (#clear%20Bookmark%20X) T} T{ FenrirKey + Shift + 0 T}@T{ set bookmark 10 (#set%20Bookmark%20X) T} T{ FenrirKey + 0 T}@T{ bookmark 10 (#read%20Bookmark%20X) T} T{ FenrirKey + KeyPad Slash T}@T{ set window application (#Create%20Window) T} T{ 2 * FenrirKey + KeyPad Slash T}@T{ clear window application (#Remove%20Window) T} T{ KeyPad Plus T}@T{ read last incoming (#last%20incoming) T} T{ FenrirKey + F2 T}@T{ toggles braille (#toggle%20braille) T} T{ FenrirKey + F3 T}@T{ toggles sound (#toggle%20sound) T} T{ FenrirKey + F4 T}@T{ toggles speech (#toggle%20speech) T} T{ KeyPad Enter T}@T{ temporarily disables speech (#disable%20speech%20temporarily) T} T{ FenrirKey + CTRL + P T}@T{ toggles punctuation level (#toggle%20punctuation%20level) T} T{ FenrirKey + RightBrace T}@T{ toggle auto spell check (#toggle%20auto%20spell%20check) T} T{ FenrirKey + Backslash T}@T{ toggles output (#toggle%20output) T} T{ FenrirKey + CTRL + E T}@T{ toggles emoticons (#toggle%20emoticons) T} T{ FenrirKey + KeyPad Enter T}@T{ toggles auto read (#toggle%20auto%20read) T} T{ FenrirKey + CTRL + T T}@T{ toggles auto time (#toggle%20auto%20time) T} T{ FenrirKey + KeyPad ASTERISK T}@T{ toggles highlight tracking (#toggle%20highlight%20tracking) T} T{ FenrirKey + Q T}@T{ quits fenrir (#quit%20Fenrir) T} T{ FenrirKey + T T}@T{ Announce time (#Time) T} T{ 2 * FenrirKey + T T}@T{ Announce date (#Date) T} T{ FenrirKey + S T}@T{ spell check (#spell%20check) T} T{ 2 * FenrirKey + S T}@T{ add word to spell check (#add%20word%20to%20spell%20check) T} T{ FenrirKey + Shift + S T}@T{ removes word from spell check (#removes%20word%20from%20spell%20check) T} T{ FenrirKey + Backspace T}@T{ forward keypress (#forward%20keypress) T} T{ FenrirKey + Up T}@T{ increase speech volume (#increase%20speech%20volume) T} T{ FenrirKey + Down T}@T{ decrease speech volume (#decrease%20speech%20volume) T} T{ FenrirKey + Right T}@T{ increase speech rate (#increase%20speech%20rate) T} T{ FenrirKey + Left T}@T{ decrease speech rate (#decrease%20speech%20rate) T} T{ FenrirKey + Alt + Right T}@T{ increase speech pitch (#increase%20speech%20pitch) T} T{ FenrirKey + Alt + Left T}@T{ decrease speech pitch (#decrease%20speech%20pitch) T} T{ FenrirKey + Alt + Up T}@T{ increase sound volume (#increase%20sound%20volume) T} T{ FenrirKey + Alt + Down T}@T{ decrease sound volume (#decrease%20sound%20volume) T} T{ FenrirKey + CTRL + Shift + C T}@T{ clears clipboard (#clear%20clipboard) T} T{ FenrirKey + Home T}@T{ first clipboard (#first%20clipboard) T} T{ FenrirKey + End T}@T{ last clipboard (#last%20clipboard) T} T{ FenrirKey + PageUp T}@T{ previous clipboard (#previous%20clipboard) T} T{ FenrirKey + PageDown T}@T{ next clipboard (#next%20clipboard) T} T{ FenrirKey + Shift + C T}@T{ current clipboard (#read%20current%20clipboard) T} T{ FenrirKey + C T}@T{ copy marked text to clipboard (#copy%20marked%20to%20clipboard) T} T{ FenrirKey + V T}@T{ paste clipboard contents (#paste%20clipboard) T} T{ FenrirKey + P T}@T{ import clipboard from file (#import%20clipboard%20from%20file) T} T{ FenrirKey + Alt + Shift +C T}@T{ export clipboard to file (#export%20clipboard%20to%20file) T} T{ FenrirKey + CTRL + Shift + X T}@T{ remove marks (#Remove%20Marks) T} T{ FenrirKey + X T}@T{ set mark (#Set%20mark) T} T{ FenrirKey + Shift + X T}@T{ announce marked text (#Get%20text%20between%20marks) T} T{ Linux specific T}@T{ T} T{ \f[C]\f[] T}@T{ export clipboard to X T} T{ FenrirKey + CTRL + Up T}@T{ include Alsa volume T} T{ FenrirKey + CTRL + Down T}@T{ decrease Alsa volume T} .TE .SS Laptop Layout .PP .TS tab(@); l l. T{ Shortcut T}@T{ Command T} _ T{ FenrirKey + H T}@T{ toggle tutorial mode (#Tutorial%20Mode) T} T{ CTRL T}@T{ shut up (interrupts speech) (#shut%20up) T} T{ FenrirKey + Shift + O T}@T{ reviews bottom (#review%20bottom) T} T{ FenrirKey + Shift + U T}@T{ reviews top (#review%20top) T} T{ FenrirKey + I T}@T{ reviews current line (#review%20current%20line) T} T{ FenrirKey + U T}@T{ reviews previous line (#review%20previous%20line) T} T{ FenrirKey + O T}@T{ reviews next line (#review%20next%20line) T} T{ FenrirKey + Shift + J T}@T{ reviews line beginning (#review%20line%20beginning) T} T{ FenrirKey + Shift + L T}@T{ reviews line ending (#review%20line%20ending) T} T{ FenrirKey + CTRL + J T}@T{ reviews line first character (#review%20line%20first%20character) T} T{ FenrirKey + CTRL + L T}@T{ reviews line last character (#review%20line%20last%20character) T} T{ FenrirKey + Alt + 1 T}@T{ presents first line (#present%20first%20line) T} T{ FenrirKey + Alt + 2 T}@T{ presents last line (#present%20last%20line) T} T{ FenrirKey + K T}@T{ reviews current word (#review%20current%20word) T} T{ FenrirKey + J T}@T{ reviews previous word (#review%20previous%20word) T} T{ FenrirKey + L T}@T{ reviews next word (#review%20next%20word) T} T{ FenrirKey + CTRL + ALT + K T}@T{ reviews current word phonetic (#review%20current%20word%20phonetic) T} T{ FenrirKey + CTRL + ALT + J T}@T{ reviews previous word phonetic (#review%20previous%20word%20phonetic) T} T{ FenrirKey + CTRL + ALT + L T}@T{ reviews next word phonetic (#review%20next%20word%20phonetic) T} T{ FenrirKey + comma T}@T{ reviews current character (#review%20current%20character) T} T{ FenrirKey + M T}@T{ reviews previous character (#review%20previous%20character) T} T{ FenrirKey + dot T}@T{ reviews next character (#review%20next%20character) T} T{ FenrirKey + CTRL + ALT + comma T}@T{ reviews current character phonetic (#review%20current%20character%20phonetic) T} T{ FenrirKey + CTRL + ALT + M T}@T{ reviews previous character phonetic (#review%20previous%20character%20phonetic) T} T{ FenrirKey + CTRL + ALT + dot T}@T{ reviews next character phonetic (#review%20next%20character%20phonetic) T} T{ FenrirKey + CTRL + I T}@T{ reviews up (#review%20up) T} T{ FenrirKey + CTRL + comma T}@T{ reviews down (#review%20down) T} T{ FenrirKey + Slash T}@T{ exit review (#exit%20review) T} T{ FenrirKey + Shift + dot T}@T{ cursor position (#cursor%20position) T} T{ 2 * FenrirKey + I T}@T{ indent curr line (#indent%20current%20line) T} T{ FenrirKey + Shift + K T}@T{ current screen (#current%20screen) T} T{ FenrirKey + Shift + I T}@T{ current screen before cursor (#current%20screen%20before%20cursor) T} T{ FenrirKey + Shift + comma T}@T{ current screen after cursor (#current%20screen%20after%20cursor) T} T{ \f[C]\f[] T}@T{ cursor read to end of line (#cursor%20read%20to%20end%20of%20line) T} T{ \f[C]\f[] T}@T{ cursor column (#cursor%20column) T} T{ \f[C]\f[] T}@T{ cursor line number (#cursor%20line%20number) T} T{ \f[C]\f[] T}@T{ Braille flush (#braille%20flush) T} T{ \f[C]\f[] T}@T{ Braille pan left (#braille%20pan%20left) T} T{ \f[C]\f[] T}@T{ Braille pan right (#braille%20pan%20right) T} T{ \f[C]\f[] T}@T{ Braille return to cursor (#braille%20return%20to%20cursor) T} T{ FenrirKey + CTRL + 1 T}@T{ clear bookmark 1 (#clear%20Bookmark%20X) T} T{ FenrirKey + Shift + 1 T}@T{ set bookmark 1 (#set%20Bookmark%20X) T} T{ FenrirKey + 1 T}@T{ bookmark 1 (#read%20Bookmark%20X) T} T{ FenrirKey + CTRL + 2 T}@T{ clear bookmark 2 (#clear%20Bookmark%20X) T} T{ FenrirKey + Shift + 2 T}@T{ set bookmark 2 (#set%20Bookmark%20X) T} T{ FenrirKey + 2 T}@T{ bookmark 2 (#read%20Bookmark%20X) T} T{ FenrirKey + CTRL + 3 T}@T{ clear bookmark 3 (#clear%20Bookmark%20X) T} T{ FenrirKey + Shift + 3 T}@T{ set bookmark 3 (#set%20Bookmark%20X) T} T{ FenrirKey + 3 T}@T{ bookmark 3 (#read%20Bookmark%20X) T} T{ FenrirKey + CTRL + 4 T}@T{ clear bookmark 4 (#clear%20Bookmark%20X) T} T{ FenrirKey + Shift + 4 T}@T{ set bookmark 4 (#set%20Bookmark%20X) T} T{ FenrirKey + 4 T}@T{ bookmark 4 (#read%20Bookmark%20X) T} T{ FenrirKey + CTRL + 5 T}@T{ clear bookmark 5 (#clear%20Bookmark%20X) T} T{ FenrirKey + Shift + 5 T}@T{ set bookmark 5 (#set%20Bookmark%20X) T} T{ FenrirKey + 5 T}@T{ bookmark 5 (#read%20Bookmark%20X) T} T{ FenrirKey + CTRL + 6 T}@T{ clear bookmark 6 (#clear%20Bookmark%20X) T} T{ FenrirKey + Shift + 6 T}@T{ set bookmark 6 (#set%20Bookmark%20X) T} T{ FenrirKey + 6 T}@T{ bookmark 6 (#read%20Bookmark%20X) T} T{ FenrirKey + CTRL + 7 T}@T{ clear bookmark 7 (#clear%20Bookmark%20X) T} T{ FenrirKey + Shift + 7 T}@T{ set bookmark 7 (#set%20Bookmark%20X) T} T{ FenrirKey + 7 T}@T{ bookmark 7 (#read%20Bookmark%20X) T} T{ FenrirKey + CTRL + 8 T}@T{ clear bookmark 8 (#clear%20Bookmark%20X) T} T{ FenrirKey + Shift + 8 T}@T{ set bookmark 8 (#set%20Bookmark%20X) T} T{ FenrirKey + 8 T}@T{ bookmark 8 (#read%20Bookmark%20X) T} T{ FenrirKey + CTRL + 9 T}@T{ clear bookmark 9 (#clear%20Bookmark%20X) T} T{ FenrirKey + Shift + 9 T}@T{ set bookmark 9 (#set%20Bookmark%20X) T} T{ FenrirKey + 9 T}@T{ bookmark 9 (#read%20Bookmark%20X) T} T{ FenrirKey + CTRL + 0 T}@T{ clear bookmark 10 (#clear%20Bookmark%20X) T} T{ FenrirKey + Shift + 0 T}@T{ set bookmark 10 (#set%20Bookmark%20X) T} T{ FenrirKey + 0 T}@T{ bookmark 10 (#read%20Bookmark%20X) T} T{ FenrirKey + CTRL + 8 T}@T{ set window application (#Create%20Window) T} T{ 2 * FenrirKey + CTRL + 8 T}@T{ clear window application (#Remove%20Window) T} T{ FenrirKey + Semicolon T}@T{ read last incoming (#last%20incoming) T} T{ FenrirKey + F2 T}@T{ toggles braille (#toggle%20braille) T} T{ FenrirKey + F3 T}@T{ toggles sound (#toggle%20sound) T} T{ FenrirKey + F4 T}@T{ toggles speech (#toggle%20speech) T} T{ FenrirKey + Enter T}@T{ temporarily disables speech (#disable%20speech%20temporarily) T} T{ FenrirKey + Shift + CTRL + P T}@T{ toggles punctuation level (#toggle%20punctuation%20level) T} T{ FenrirKey + RightBrace T}@T{ toggle auto spell check (#toggle%20auto%20spell%20check) T} T{ FenrirKey + Shift + Enter T}@T{ toggles output (#toggle%20output) T} T{ FenrirKey + Shift + E T}@T{ toggles emoticons (#toggle%20emoticons) T} T{ FenrirKey + Enter T}@T{ toggles auto read (#toggle%20auto%20read) T} T{ FenrirKey + CTRL + T T}@T{ toggles auto time (#toggle%20auto%20time) T} T{ FenrirKey + Y T}@T{ toggles highlight tracking (#toggle%20highlight%20tracking) T} T{ FenrirKey + Q T}@T{ quits fenrir (#quit%20Fenrir) T} T{ FenrirKey + T T}@T{ Announce time (#Time) T} T{ 2 * FenrirKey + T T}@T{ Announce date (#Date) T} T{ FenrirKey + S T}@T{ spell check (#spell%20check) T} T{ 2 * FenrirKey + S T}@T{ add word to spell check (#add%20word%20to%20spell%20check) T} T{ FenrirKey + Shift + S T}@T{ removes word from spell check (#removes%20word%20from%20spell%20check) T} T{ FenrirKey + Backspace T}@T{ forward keypress (#forward%20keypress) T} T{ FenrirKey + Up T}@T{ increase speech volume (#increase%20speech%20volume) T} T{ FenrirKey + Down T}@T{ decrease speech volume (#decrease%20speech%20volume) T} T{ FenrirKey + Right T}@T{ increase speech rate (#increase%20speech%20rate) T} T{ FenrirKey + Left T}@T{ decrease speech rate (#decrease%20speech%20rate) T} T{ FenrirKey + Alt + Right T}@T{ increase speech pitch (#increase%20speech%20pitch) T} T{ FenrirKey + Alt + Left T}@T{ decrease speech pitch (#decrease%20speech%20pitch) T} T{ FenrirKey + Alt + Up T}@T{ increase sound volume (#increase%20sound%20volume) T} T{ FenrirKey + Alt + Down T}@T{ decrease sound volume (#decrease%20sound%20volume) T} T{ FenrirKey + CTRL + Shift + C T}@T{ clears clipboard (#clear%20clipboard) T} T{ FenrirKey + Home T}@T{ first clipboard (#first%20clipboard) T} T{ FenrirKey + End T}@T{ last clipboard (#last%20clipboard) T} T{ FenrirKey + PageUp T}@T{ previous clipboard (#previous%20clipboard) T} T{ FenrirKey + PageDown T}@T{ next clipboard (#next%20clipboard) T} T{ FenrirKey + Shift + C T}@T{ current clipboard (#read%20current%20clipboard) T} T{ FenrirKey + C T}@T{ copy marked text to clipboard (#copy%20marked%20to%20clipboard) T} T{ FenrirKey + V T}@T{ paste clipboard contents (#paste%20clipboard) T} T{ FenrirKey + F5 T}@T{ import clipboard from file (#import%20clipboard%20from%20file) T} T{ FenrirKey + Alt + Shift +C T}@T{ export clipboard to file (#export%20clipboard%20to%20file) T} T{ FenrirKey + CTRL + Shift + X T}@T{ remove marks (#Remove%20Marks) T} T{ FenrirKey + X T}@T{ set mark (#Set%20mark) T} T{ FenrirKey + Shift + X T}@T{ announce marked text (#Get%20text%20between%20marks) T} T{ Linux specific T}@T{ T} T{ \f[C]\f[] T}@T{ export clipboard to X T} T{ FenrirKey + CTRL + Up T}@T{ increases Alsa volume T} T{ FenrirKey + CTRL + Down T}@T{ decreases Alsa volume T} .TE .SS General .SS quit Fenrir .PP Just stops fenrir. #### shut up .PP Interrupt the current spoken. ### Review Modes .PP Fenrir provides a virtual cursor, with it you can navigate all over the screen without changing the text cursor. .PP Using the review feature will open the review mode automatically. .PP The review cursor always starts from the text cursor. Attention: after using the review mode, the review cursor will stay open until you use the \[aq]\[aq]exit review\[aq]\[aq] shortcut. .PP Think when using clipboard operations and similar. The review cursor is always prefered over the text cursor. .PP Fenrir sounds a bell sound if the used review command jumps to another line or end of screen. #### exit review .PP You can leave the review mode by pressing the \[aq]\[aq]exit review\[aq]\[aq] shortcut. #### review bottom .PP Set the review cursor to first column in the last line. #### review top .PP Set the review cursor to the first column in the first line #### review current line .PP Set the review cursor to the beginn of the the current line and review it. #### review previous line .PP Set the review cursor to the previous line and review it. #### review next line .PP Set the review cursor to the next line and review it. #### review line beginning .PP Set the review cursor to the begin of the current line #### review line ending .PP Set the review cursor to the end of the current line #### review line first character .PP Set the review cursor the first char (that is not space) in the current line and review it. #### review line last character .PP Set the review cursor the last char (that is not space) in the current line and review it. #### review current word .PP Sets the review cursor to the beginning of the current word and review it. #### review previous word .PP Sets the review cursor to the beginning of the previous word and review it. #### review next word .PP Sets the review cursor to the beginning of the next word and review it. #### review current word phonetic .PP Sets the review cursor to the beginning of the current word and spell it phonetic. #### review previous word phonetic .PP Sets the review cursor to the beginning of the previous word and spell it phonetic. #### review next word phonetic .PP Sets the review cursor to the beginning of the next word and spell it phonetic. #### review current character .PP Does not change the review cursor. Just announce the current char. #### review previous character .PP Sets review cursor to the previous column and review it #### review next character .PP Sets review cursor to the next column and review it #### review current character phonetic .PP Does not change the review cursor. Just announce the current char phonetic. #### review previous character phonetic .PP Sets review cursor to the previous column and announce the char phonetic. #### review next character phonetic .PP Sets review cursor to the next column and announce the char phonetic. #### review up .PP Set the review cursor in the same column one line above the current one and review it. #### review down .PP Set the review cursor in the same column one line below the current one and review it. ### Handling marking .PP A mark defines a point of origin or end to prepare to copy or paste a block of text. \\ Examples where you need marks are: .IP \[bu] 2 copy to clipboard .IP \[bu] 2 set window application .IP \[bu] 2 set bookmark 1 \- X #### Set mark .PP How to set a mark: 1. navigate with review or textcursor to the position you want to set the mark. Attention: if a review cursor is set, that is the prefered. If you want to use text cursor, be sure that you are not in review mode. 2. press shortcut for \[aq]\[aq]set mark\[aq]\[aq] you can set two marks (begin and end). Some commands allow some simpler usecases just using the whole line if only one mark is set. you may want to try this out. #### Get text between marks .PP To get the text that is currently between your marks press shortcut for \[aq]\[aq]marked text\[aq]\[aq].\\ #### Remove Marks .PP You can remove all current marks by pressing the shortcut for \[aq]\[aq]remove marks\[aq]\[aq]. Changing the screen also removes the marks. ### Screen Interaction .PP Fenrir provides several methods to interact with the current screen. #### forward keypress .PP This just forwards the next shortcut to the screen Fenrir shortcut or not. This is useful if the currently pressed shortcut is also in use by Fenrir. #### Clipboard .PP Fenrir provides a clipboard with multible items represented by a list. You navigate throught the list and paste the selected clipboard. ##### copy marked to clipboard .PP To copy something to the clipboard you need to set one or two marks. if you set one mark, the text between the mark and your current cursor is copied to clipboard. Setting two marks just copies the text between the marks into the clipboard. If you copy something it is always placed as the first item on your clipboard. ##### clear clipboard .PP You can remove all items from the current clipboard by \[aq]\[aq]clear clipboard\[aq]\[aq] functionality. ##### first clipboard .PP This moves quick to the first item of the clipboard. ##### last clipboard .PP This moves quick to the last item of the clipboard. ##### previous clipboard .PP Go to previous item in the clipboard. ##### next clipboard .PP Go to next item on the clipboard. ##### read current clipboard .PP Read the content of the current item of the clipboard. ##### paste clipboard .PP Pass whatever item is currently selected by first, last, prev or next clipboard commands. if no special clipboard is selected the (last copied) is used. ##### export clipboard to file .PP This allows you to export the current clipboard to a configurable filepath. This is useful to share the clipboard with a graphical desktop. ##### import clipboard from file .PP Import a clipboard from a configurable file. This is useful to share the clipboard with a graphical desktop. ### Quick Settings .PP Fenrir provides shortcuts to change settings temporarily and on the fly without the need to permanently change the \[aq]\[aq]settings.conf\[aq]\[aq] file. #### toggle braille .PP Enables and disables Braille. This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] but during run time. #### toggle sound .PP Enables and disables sound. This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] but during run time. #### toggle speech .PP Enables and disables speech. This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] but during run time. #### disable speech temporarily .PP Disables the speech until next key press. it might be useful if you want to listen to music or similar. As soon as a key is pressed it is going to be enabled again. #### toggle punctuation level .PP Cycle between all available punctuation levels. This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] but during run time. #### toggle auto spell check .PP Enables and disables automatic spellchecker (when typing). This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] but during run time. #### toggle emoticons .PP Enables and disables emoticons. This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] but during runtime. #### toggle output .PP Enables and disables all output at once (sound, Braille, speech). This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] but during run time. #### toggle auto read .PP Enables and disables what is automatically spoken. This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] but during run time. #### toggle auto time .PP Enables and disables auto time functionality. This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] but during run time. #### toggle highlight tracking .PP Enables and disables highlight tracking. This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] but during run time. #### increase speech volume .PP Increase the volume of the speech. This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] but during runtime. #### decrease speech volume .PP Decrease the volume of the speech. This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] but during runtime. #### increase speech rate .PP Increase the rate of the speech. This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] but during runtime. #### decrease speech rate .PP Decrease the rate of the speech. This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] but during runtime. #### increase speech pitch .PP Increase the pitch of the speech. This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] but during runtime. #### decrease speech pitch .PP Decrease the pitch of the speech. This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] but during runtime. #### increase sound volume .PP Increase the volume of the sound. This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] but during runtime. #### decrease sound volume .PP Decrease the volume of the sound. This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] but during runtime. ### Window Mode .PP Fenrir supports window mode, a window is a partial area of the screen. #### Create Window .PP To create a window you need to do the following: 1. set a beginning mark (as the start of the window) 2. set an end mark (where the window should end) 3. press \[aq]\[aq]set window application\[aq]\[aq] shortcut. Now Fenrir ignores anything outside of the window.\\ #### Remove Window .PP You can remove the window by pressing \[aq]\[aq]the clear window application\[aq]\[aq] shortcut. Now Fenrir will read everything on the screen again. ### Tracking Modes .PP Different types of tracking are currently supported See section Focus (#Focus) in \[aq]\[aq]settings.conf\[aq]\[aq] for more information. #### Cursor Tracking .PP This follows the text cursor. This is the typical way an application works. This is used by: .IP \[bu] 2 almost any shell such as (Bash, Zsh, sh) .IP \[bu] 2 vim .IP \[bu] 2 nano .IP \[bu] 2 emacs .IP \[bu] 2 mutt .IP \[bu] 2 tintin++ #### Highlight Tracking .PP In some applications there are no text cursors. In those applications cursor changes are represented by different colors or attributes (underlined or bold). This mode tracks and announces these changes for you. This is used by: .IP .nf \f[C] *\ wifi\-menu *\ dialog *\ alpine \f[] .fi .SS Tutorial Mode .PP Fenrir provides a Tutorial mode. When you enter tutorial mode, screen reader commands are intercepted and explained instead of executing them. \[aq]\[aq]Arrow up\[aq]\[aq] and \[aq]\[aq]Arrow Down\[aq]\[aq] let you navigate through a list of all available commands with shortcuts and description. Pressing escape leaves the tutorial mode. .SS Information .SS Time .PP Announces the current Time. #### Date .PP Announces the current Date. #### Bookmarks .PP Bookmarks provide quick access to part of the screen without the need to navigate to the area. By default Fenrir provides 10 bookmarks. Those can be set and accessed via shortcut. This is useful for status lines or other information where the position does not change. ##### set Bookmark X .PP You need to set the bookmark first. For that you have to set one or two lines for use. 1. Set marks (one or two) 2. press shortcut for \[aq]\[aq]set bookmark X\[aq]\[aq]. X represents the number 1 \- 10. ##### read Bookmark X .PP If a bookmark is set you can access the area just by pressing the \[aq]\[aq]bookmark X\[aq]\[aq] shortcut. X represents the number 1 \- 10. Bookmarks are dynamic. That means the content changes with the screen. ##### clear Bookmark X .PP to remove a bookmark just press the \[aq]\[aq]clear bookmark X\[aq]\[aq] shortcut. X represents the number 1 \- 10. Afterward the bookmark is no longer available. #### cursor position .PP You can get information about the current cursor and its position by using the "cursor position" functionality. #### indent current line .PP Announce the current indent level of the current line. It represents the number of trailing spaces of the line. #### current screen .PP Reads all the current screen from the beginning to the end. #### current screen before cursor .PP Reads current screen from the beginning of the screen to the current cursor position. #### current screen after cursor .PP Read anything after current cursor position to the end. #### cursor read to end of line .PP Read from the current cursor position to the end of the current line. #### cursor column .PP Read the current X position of a cursor (column of the current line). #### cursor line number .PP Read the current Y position of a cursor (line number). #### present first line .PP Reads just the first line. this is maybe useful for status information. #### present last line .PP Presets the last line. This is maybe useful for status information. #### last incoming .PP Repeat the last automatically incoming text. ## Input .SS Echo .PP Fenrir provides different methods of echoing content: .IP \[bu] 2 Word: Will speak each word after you push space .IP \[bu] 2 Character: speak any letter you type on the screen .IP \[bu] 2 Delete Character: speaks the character prior to the cursor when you push backspace ### Silence on Key press .SS Spellchecker .PP Fenrir has a built\-in spellchecker, it can invoke automatically while typing or be called by a shortcut. Commands to add or remove the current word to the dictionary are included. As using the spellchecker is enhanced usage. You will need dictionary aspell\-\f[C]\f[]. See section General (#General) in \[aq]\[aq]settings.conf\[aq]\[aq] for more information. #### spell check .PP Invokes the spellcheck on the word that contains the Review or text cursor. #### add word to spell check .PP Adds the word under the Review or Text cursor to the dictionary. #### removes word from spell check .PP Removes the word under the Review or Text cursor from the dictionary. ## Announcements .SS Emoticons .PP If you want to replace ":)" emoticons with "smile" in speech you can use this feature. It can be toggled on or off. You can define emoticons in a dictionary, please see Emoticon Dictionary. See section General (#General) in \[aq]\[aq]settings.conf\[aq]\[aq] to see how to enable or disable this feature. .SS Time .PP Announce the time at periodical increments, To track the time easily. You can define 2 different ways of time announcements. 1. periodic 2. on fix minutes .PP Example periodic, every 20 minutes "delaySec=20": .IP .nf \f[C] [time] enabled=True presentTime=True presentDate=True delaySec=20 onMinutes= announce=True interrupt=False\ \ \ \ \f[] .fi .PP Example on fix minutes in an hour. example every quarter "delaySec=0" and "onMinutes=00,15,30,45": .IP .nf \f[C] [time] enabled=True presentTime=True presentDate=True #delaySec\ is\ repected\ bevore\ onMinutes\ so\ it\ need\ to\ be\ set\ to\ 0 delaySec=0\ onMinutes=00,15,30,45 announce=True interrupt=False\ \ \ \ \ \ \f[] .fi .SS Promoted List .PP Promoted Lists are a nice feature if you are away from your computer or performing more longer tasks. you can define a list of words which you want to hear a sound icon for after a period of inactivity. Example if the word "Chrys" appears after 120 Seconds of inactivity: [promote] enabled=True .PD 0 .P .PD inactiveTimeoutSec=120 list=Chrys See section Promote (#Promote) in \[aq]\[aq]settings.conf\[aq]\[aq] for more information. ### Punctuation .PP Fenrir handles punctuation levels and names for you with several provided dictionaries. .PP See levelDict See punctuationDict ## Braille .PP Fenrir provides Braille support in Version >= 2.0. See section Braille (#Braille) in \[aq]\[aq]settings.conf\[aq]\[aq] for more information. ### braille flush .PP If a message appears on the Braille device you can flush it to get back to the review\- or system cursor ### Braille pan left .PP If a line is longer than your Braille devices you can move the view (called panning) to the left. So you can read stuff without the need to move the review\- or system cursor. ### Braille pan right .PP If a line is longer than your Braille devices you can move the view (called panning) to the right. So you can read stuff without the need to move the review\- or system cursor. ### braille return to cursor .PP When you have finished reading the line on the Braille device using panning, the focus can be returned to the current used cursor by using "return to cursor" command. ## Dictionary .PP You can make use of different kinds of built\-in dictionary\[aq]s. A dictionary has a name and list of keys and values separated by :===: Example: [customDict] Chrys:===:Chrys is cool lollipop:===:lolli that means that every instance "chrys" is displayed, speech will say Chrys is cool. "lollipop" is spoken as "lolli". Before making changes to a dictionary we recommend making a backup of your current dictionary in case future updates overwrite your local changes. ### Punctuation .SS Level .PP The punctuation level dict contains lists with "what punctuation is spoken in what level". the default one looks like this: [levelDict] none:===: some:===:.\-$~+*\-/\\\@ most:===:.,:\-$~+*\-/\@!#%^&\f[I]()[]}{\f[C]<>\f[]; all:===:!"#$%& \[aq]()\f[]+,\-./:;\f[C]<=>\f[]?\@[\\]^_`{|}~ the level "none" has no values. so it should not speak any punctuation (sadly this is not respected by every TTS system) if "some" is the current level the following are spoken: dot dash dollar tilde plus star slash backslash at. same for most and all, you can add new levels. if you cycle punctuation levels they are recognized. the default punctuation level is set in settings.conf. The default is "some". #### Punctuation .PP The punctuation dictionary "[punctDict]" contains how the punctuation is spoken. Example: [punctDict] \f[I]:===:line .PD 0 .P .PD speaks an \f[] as "line". .PD 0 .P .PD [punctDict] \f[I]:===:underscore speaks an \f[] as underscore. for question mark an ? is appended to the word that the TTS system can announce the question correctly. .PD 0 .P .PD ### Custom .PP The dict "[customDict]" is just for your own use, it just replace the key with the value without any special functionality. This might be used to fix incorrectly spoken words, make words more common, shorter or just for fun. :) ### Emoticons .PP The Emoticons dictionary "[emoticonDict]" by default contains some emoticons. it can replace ":)" with "smile" or "XD" with "loool" Making chat more colorful. A nice feature with this dictionary is that you can toggle the substitution on or off during run time or in settings.conf. This is useful because while doing programming or other serious work you want to hear colons and perryns not smiles. # Configuration .PP You can configure Fenrir in the following places (ordered by priority): 1. Commandline Parameters \[aq]\[aq]\-o\[aq]\[aq] see Set settings coption (#Set%20settings%20coption) 2. /etc/fenrir/settings/settings.conf see Settigns (#Settings) 3. \f[C]\f[]/config/settings/settings.conf see Settigns (#Settings) 4. hard coded defaults ## Commandline Arguments .SS Set settings option .PP You can specify options that overwrite the setting.conf. This is done with \[aq]\[aq]\-o \f[C]\f[] parameter. The list of options have the following syntax fenrir \-o "section#setting=value;section#setting=value" .PP For example changing the sound driver to gstreamer and disabling Braille .PD 0 .P .PD fenrir \-o "sound#driver=gstreamerDriver;braille#enabled=False=False" or change the debug level to verbose fenrir \-o "general#debugLevel=3" You can find the available sections and variables here <#Settings> See Syntax #settings.conf syntax (#settings.conf%20syntax) ### settings.conf syntax .PP the syntax of the settings.conf (#Settings) is quite simple and similar to a "*.ini" file, there are 4 different elements. 1. Sections 2. Settings 3. Values 4. Comments .PP A comment starts with a # and is ignored by Fenrir. # this is a comment To group settings we have sections. A section can look like this: [Section] A setting looks like this: settingName=Value .PP Example: sound (#sound) # Turn sound on or off: enabled=True # Select the driver used to play sounds, choices are genericDriver and gstreamerDriver. # Sox is default. driver=genericDriver .SS Settings .SS Sound .PP The sound is configured in section \[aq]\[aq]sound (#sound)\[aq]\[aq]. .PP Turn sound on or off: enabled=True Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] .PP Select the driver used to play sounds. The genericDriver using Sox is the default. .IP .nf \f[C] driver=genericDriver \f[] .fi .PP Available Drivers: .IP \[bu] 2 \[aq]\[aq]genericDriver\[aq]\[aq] using the generic driver, for Fenrir <1.5 just use \[aq]\[aq]generic\[aq]\[aq] .IP \[bu] 2 \[aq]\[aq]gstreamerDriver\[aq]\[aq] using the gstreamer, for Fenrir <1.5 just use \[aq]\[aq]gstreamer\[aq]\[aq] .PP These are the pack of sounds used for sound icons. theme=default By default we ship two sound packs. 1. \[aq]\[aq]default\[aq]\[aq] opus encoded, for newer Sox versions 2. \[aq]\[aq]default\-wav\[aq]\[aq] wav encoded, just for compatibility Sound packs are located at /usr/share/sounds/fenrir/ .PP Sound volume controls how loud the sounds for your selected sound pack are. volume=1.0 Values: \[aq]\[aq]0.0\[aq]\[aq] is quietest, \[aq]\[aq]1.0\[aq]\[aq] is loudest. .SS Generic Driver .PP The generic sound driver uses shell commands for play sound and frequencies. .PP \[aq]\[aq]genericPlayFileCommand\[aq]\[aq] defines the command that is used to play a sound file. genericPlayFileCommand=\f[C]\f[] \[aq]\[aq]genericFrequencyCommand\[aq]\[aq] defines the command that is used playing frequencies. genericFrequencyCommand=\f[C]\f[] .PP The following variables are substituted in \[aq]\[aq]genericPlayFileCommand\[aq]\[aq] and \[aq]\[aq]genericFrequencyCommand\[aq]\[aq]: .IP \[bu] 2 \[aq]\[aq]fenrirVolume\[aq]\[aq] = the current volume setting .IP \[bu] 2 \[aq]\[aq]fenrirSoundFile\[aq]\[aq] = the sound file for an sound icon .IP \[bu] 2 \[aq]\[aq]fenrirFrequence\[aq]\[aq] = the frequency to play .IP \[bu] 2 \[aq]\[aq]fenrirDuration\[aq]\[aq] = the duration of the frequency .PP Example genericPlayFileCommand (default) genericPlayFileCommand=play \-q \-v fenrirVolume fenrirSoundFile Example genericFrequencyCommand (default) genericFrequencyCommand=play \-q \-v fenrirVolume \-n \-c1 synth fenrirDuration sine fenrirFrequence ### Speech .PP Speech is configured in section \[aq]\[aq][speech]\[aq]\[aq]. Turn speech on or off: enabled=True Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] .SH Select speech driver, options are speechdDriver (default), genericDriver or espeakDriver: .PP driver=speechdDriver #driver=espeakDriver .SH driver=genericDriver .PP Select the driver used to generate speech output. .IP .nf \f[C] driver=speechdDriver \f[] .fi .PP Available Drivers: .IP \[bu] 2 \[aq]\[aq]genericDriver\[aq]\[aq] using the generic driver, for Fenrir <1.5 this is not available .IP \[bu] 2 \[aq]\[aq]speechdDriver\[aq]\[aq] using speech\-dispatcher, for Fenrir <1.5 just use \[aq]\[aq]speechd\[aq]\[aq] .IP \[bu] 2 \[aq]\[aq]espeakDriver\[aq]\[aq] using the espeak directly, for Fenrir <1.5 just use \[aq]\[aq]espeak\[aq]\[aq] .PP The rate selects how fast Fenrir will speak. rate=0.65 Values: Range Minimum:\[aq]\[aq]0.0\[aq]\[aq] is slowest, Maximum:\[aq]\[aq]1.0\[aq]\[aq] is fastest. .PP Pitch controls the pitch of the voice. pitch=0.5 Values: Range Minimum:\[aq]\[aq]0.0\[aq]\[aq] is lowest, Maximum:\[aq]\[aq]1.0\[aq]\[aq] is highest. .PP A Pitch for capital letters can be set. capitalPitch=0.9 Values: Range Minimum:\[aq]\[aq]0.0\[aq]\[aq] is lowest, Maximum:\[aq]\[aq]1.0\[aq]\[aq] is highest. .PP The Volume controls the loudness of the voice. volume=1.0 Values: Range Minimum:\[aq]\[aq]0.0\[aq]\[aq] is quietest, Maximum:\[aq]\[aq]1.0\[aq]\[aq] is loudest. .PP Some speech drivers like speechdDriver can support various modules. these can be set here. module=espeak Values: Text, Consult speech\-dispatcher\[aq]s configuration to see what modules are available. .PP Voice selects the varient you want to use, for example, f5 will use the female voice #5 in Espeak, or if using the Espeak module in Speech\-dispatcher. To find out which voices are available, consult the documentation provided with your selected synthesizer. voice= Values: Text, see your TTS synths documentation what is available. .PP Select the language you want Fenrir to use. language=english\-us Values: Text, see your TTS synths documentation what is available. .PP Read new text as it occurs autoReadIncoming=True Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] .SS Generic Driver .PP The generic speech driver uses shell commands for speech synthisus. .PP \[aq]\[aq]genericSpeechCommand\[aq]\[aq] defines the command that is executed for creating speech The following variables are substituted in \[aq]\[aq]genericSpeechCommand\[aq]\[aq]: .IP \[bu] 2 \[aq]\[aq]FenrirText\[aq]\[aq] = is the text that should be spoken .IP \[bu] 2 \[aq]\[aq]fenrirModule\[aq]\[aq] = may be the speech module like used in speech\-dispatcher, not every TTY needs this .IP \[bu] 2 \[aq]\[aq]fenrirLanguage\[aq]\[aq] = the language to speak in .IP \[bu] 2 \[aq]\[aq]fenrirVoice\[aq]\[aq] = is the current voice that should be used .IP \[bu] 2 \[aq]\[aq]fenrirVolume\[aq]\[aq] = is replaced with the current volume .IP \[bu] 2 \[aq]\[aq]fenrirPitch\[aq]\[aq] = is replaced with the current pitch .IP \[bu] 2 \[aq]\[aq]fenrirRate\[aq]\[aq] = is replaced with the current speed (speech rate) .PP Example genericSpeechCommand (default): genericSpeechCommand=espeak \-a fenrirVolume \-s fenrirRate \-p fenrirPitch \-v fenrirVoice "fenrirText" .PP These are the minimum and maximum values of the TTS system used in genericSpeechCommand. They are needed to calculate the abstract range in volume, rate and pitch 0.0 \- 1.0. .IP .nf \f[C] FenrirMinVolume=0 fenrirMaxVolume=200 fenrirMinPitch=0 fenrirMaxPitch=99 fenrirMinRate=80 fenrirMaxRate=450 \f[] .fi .PP The current volume, pitch and rate is calculated like this value = min + [volume,pitch,rate] * (min \- max ) ### Braille .PP Braille is a WIP and not ready yet. Braille support can be configured in section \[aq]\[aq][braille]\[aq]\[aq]. .PP Turn braille on or off: enabled=False Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] .PP Select the driver used for communication with a braille device. driver=brlapiDriver Values: Text, available Driver Available Drivers: .IP \[bu] 2 \[aq]\[aq]brlttyDriver\[aq]\[aq] using brltty for braille communication, for Fenrir <1.5 just use \[aq]\[aq]brltty\[aq]\[aq] .PP The Braille layout can be configured here layout=en Values: Text, see braille driver for layouts. .PP What should the flush timeout relate to flushMode=word Values: Text, an flushMode Existing flushModes: .IP \[bu] 2 \[aq]\[aq]word\[aq]\[aq] = flush after (number of words to display) * seconds .IP \[bu] 2 \[aq]\[aq]char\[aq]\[aq] = flush after (number of chars to display) * seconds .IP \[bu] 2 \[aq]\[aq]fix\[aq]\[aq] = flush after X seconds .IP \[bu] 2 \[aq]\[aq]none\[aq]\[aq] = no automatic flush (manual via shortcut) .PP Seconds to flush (see flushMode) flushTimeout=3 Values: Integer, in Seconds or \[aq]\[aq]\-1\[aq]\[aq] = no automatic flush (manual via shortcut) The total flush time calculates in relation to flushMode. .PP How should the Braille cursor focus be tracked? cursorFocusMode=page Values: Text, an existing cursor focus mode Available cursor focus modes: .IP \[bu] 2 \[aq]\[aq]page\[aq]\[aq] = if the cursor crosses the border move to next page and start at begin .IP \[bu] 2 \[aq]\[aq]fixCell\[aq]\[aq] = ajust the cursor on a special cell where it is always placed. the display scroll here more smooth. .PP Define the cell on the Braille device where Fenrir should scroll and keep the cursor fixCursorOnCell=\-1 Values: Integer .IP \[bu] 2 \[aq]\[aq]0\[aq]\[aq] = first cell on device, .IP \[bu] 2 \[aq]\[aq]\-1\[aq]\[aq] = last cell on device .IP \[bu] 2 \[aq]\[aq]>0\[aq]\[aq] = fix cell number .PP What cursor should Fenrir show on the Braille device cursorFollowMode=review Values: Text, an exsiting cursor following mode. Existing cursor following mode: .IP \[bu] 2 \[aq]\[aq]none\[aq]\[aq] = no automatic toggle command used .IP \[bu] 2 \[aq]\[aq]review\[aq]\[aq] = priority to review .IP \[bu] 2 \[aq]\[aq]last\[aq]\[aq] = follow last used cursor .PP number of cells in panning (horizontal). How many cell should be panned on press the routing key? panSizeHorizontal=0 Values: Integer, .IP \[bu] 2 \[aq]\[aq]0\[aq]\[aq] = display size .IP \[bu] 2 \[aq]\[aq]>0\[aq]\[aq] number of cells ### Screen .PP The settings for screens, (TTY, PTY) are configured in the \[aq]\[aq][screen]\[aq]\[aq] section. .PP The driver to get the information from the screen: driver=vcsaDriver Available Drivers: .IP \[bu] 2 \[aq]\[aq]vcsaDriver\[aq]\[aq] using the VCSA driver (for TTYs), for Fenrir <1.5 just use \[aq]\[aq]vcsa\[aq]\[aq] The encoding of the screen encoding=cp850 Values:\[aq]\[aq]cp850\[aq]\[aq] is used for Western languages like USA or Europe. .PP The driver updates Fenrir with changes on the screen. screenUpdateDelay=0.05 Values: in Seconds .PP If you want Fenrir to not be active on any screen for various reasons. Maybe an X server or Wayland is running on that screen. You can make Fenrir ignore it or multiple screens seperated by \[aq]\[aq],\[aq]\[aq] with: suspendingScreen= Values: Depends on driver: .IP \[bu] 2 VCSA: the number of the TTY. TTY6 is \[aq]\[aq]6\[aq]\[aq]. Example ignore TTY1 and TTY2: suspendingScreen=1,2 .PP There is also the ability to let Fenrir auto detect screens that are running an X server. So Screens running an GUI can be ignored. autodetectSuspendingScreen=True Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] .SS Keyboard .PP The settings for keyboard and input related configuration is located in the section \[aq]\[aq]keyboard (#keyboard)\[aq]\[aq] of the \[aq]\[aq]settings.conf\[aq]\[aq] file. .PP Select the driver used for grabbing keybord input and for recieving shortcuts. driver=evdevDriver Values: Text, available Driver Available Drivers: .IP \[bu] 2 \[aq]\[aq]evdevDriver\[aq]\[aq] uses the evdev input system of linux, for Fenrir <1.5 just use \[aq]\[aq]evdev\[aq]\[aq] .PP You can let Fenrir know about what input devices are to be used. device=ALL Values: .IP \[bu] 2 \[aq]\[aq]ALL\[aq]\[aq] use all devices with key capabilities. .IP \[bu] 2 \[aq]\[aq]NOMICE\[aq]\[aq] Exclude mices from handling. .IP \[bu] 2 \f[C]\f[] just use the device with the given name. .PP Gives Fenrir exclusive access to the keyboard and lets it control keystrokes. This is needed to intercept Fenrir related shortcuts. grabDevices=True Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] .PP The following makes sense if you are using a second screenreader and want to have some hooked events. Fenrir ignores all shortcuts then. ignoreShortcuts=False Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] .PP The current keyboard layout used for shortcuts. keyboardLayout=desktop Values: An absolute Path to a Keyboard definition file or a Filename without extension located in \[aq]\[aq]/etc/fenrir/keyboard\[aq]\[aq] .PP Announce characters while typing. charEcho=False Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] .PP Announce deleted characters charDeleteEcho=True Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] .PP Announce word after pressing space wordEcho=False Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] .PP Interrupt speech on any keypress interruptOnKeyPress=False Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] .PP You can filter the keys that speech should interrupt interruptOnKeyPressFilter= Values: (List) empty = all keys, otherwise interrupt with specified keys .PP The timeout that is used for double tap shortcuts doubleTapTimeout=0.2 Values: Seconds ### General .PP Overall settings can be configured from the section \[aq]\[aq]general (#general)\[aq]\[aq]. .PP Set the current debug level: debugLevel=1 Values: off=0, error=1, warning=2, info=3 .PP the current punctuation and dict file in use: punctuationProfile=default Values: Text, see available profiles in \[aq]\[aq]/etc/fenrir/punctuation\[aq]\[aq] or in \[aq]\[aq]sourceTree/config/punctuation\[aq]\[aq] .PP The current punctuation level in use: punctuationLevel=some Values: Text, See available levels in the used punctuation file. .PP Respect pause for punctuations: respectPunctuationPause=True Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] .PP Add a pause on Line break: newLinePause=True Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] .PP Specify the path where the clipboard should be exported to. See export clipboard to file (#export%20clipboard%20to%20file). The variable \[aq]\[aq]$user\[aq]\[aq] is replaced by the current logged username. clipboardExportPath=/tmp/fenrirClipboard Values: Text, Systemfilepath .PP The number of available clipboards: numberOfClipboards=10 Values: Integer, 1 \- 999 .PP Replace emoticons like :) or ;) with text insertions: emoticons=True Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] .PP Define the current Fenrir keys: fenrirKeys=KEY_KP0,KEY_META,KEY_INSERT Values, Text list, separated by comma. .PP Define the current script keys: scriptKey=KEY_COMPOSE Values, Text list, separated by comma. .PP The time format to be used for (time command) output: timeFormat=%H:%M:%P Values: see python specification for datetime.strftime (https///docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior) .PP The date format to be used for (date command) output: dateFormat=%A, %B %d, %Y Values: see python specification for datetime.strftime (https///docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior) .PP Enable or Disable spellcheck whilst typing: autoSpellCheck=True Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] .PP The use of the dictionary with spellcheck: spellCheckLanguage=en_US Values: Text, see aspell dictionary\[aq]s. .PP Folder Path for your scripts "scriptKey" functionality: scriptPath=/usr/share/fenrir/scripts Values: Text, Existing path on file system. .PP Override commands or create new ones without changing the Fenrir defaults: commandPath=/usr/share/fenrir/commands Values: Text, Existing path on file system. Subfolders in commandPath are: .IP \[bu] 2 \[aq]\[aq]commands\[aq]\[aq] = to create shortcut commands .IP \[bu] 2 \[aq]\[aq]onInput\[aq]\[aq] = executed while typing .IP \[bu] 2 \[aq]\[aq]onScreenChange\[aq]\[aq] = executed on change the screen (change from TTY4 to TTY6) .IP \[bu] 2 \[aq]\[aq]onScreenUpdate\[aq]\[aq] = executed when the screen is captured .SS Focus .PP The configuration for basic focus is in the section \[aq]\[aq]focus (#focus)\[aq]\[aq]. Follow the text cursor: cursor=True Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] .PP Follow highlighted text changes (Highlight Tracking): highlight=False Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] ### Review .PP Configurations for the review mode are in the section \[aq]\[aq][review]\[aq]\[aq]. .PP If "next word/ char" or "prev word/char" create a linebreak, announce it: lineBreak=True Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] .PP If "next word/ char" or "prev word/char" cannot be performed because you reached the end of the screen, announce it: endOfScreen=True Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] .PP Leave the review mode when pressing a key: leaveReviewOnKeypress=False Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] .PP Leave the review mode when changing the screen (From TTY3 to TTY4): leaveReviewOnScreenChange=True Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] ### Promote .PP "Promoted Lists" are configured in the section \[aq]\[aq][promote]\[aq]\[aq]. Turn Promoted Lists" on or off: enabled=True Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] .PP The minimum time interval of inactivity to activate promoting. By default it promotes after 120 Seconds inactivity: inactiveTimeoutSec=120 Values: in Seconds .PP Define a list of promoted words comma seperated: list= Values: text (comma seperated) Example to promote the word "nickname" or a bash prompt: list=nickname,$:,#: .SS Time .PP The automated time announcement is configured in the section \[aq]\[aq]time (#time-2)\[aq]\[aq]. Time announcement is disabled by default. Turn time announcement on or off: enabled=True Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] .PP Should the time be announced: presentTime=True Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] .PP Should the date be announced (just on date change): presentDate=True Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] .PP Announce after a given period of seconds: delaySec=0 Value: in Seconds, 0 = Deactivated .PP Announce after fixed minutes in an hour. if delaySec is >0 onMinutes is ignored: onMinutes=00,30 Example every 15 minutes: onMinutes=00,15,30,45 .PP Just play a soundicon, (not interrupting): announce=True Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] .PP Interrupt current speech for time announcement: interrupt=False Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] # Customization .SS Scripting .PP Scripts can be in any language, bash, python, sh or others. Place your scripts in the directory /usr/share/fenrir/scripts/ (the path is configurable in settings.conf). The script key is the applications key. Usually this key can be found on the keyboard located just left of the right most control key. When you name a script, the key name appears in the script seperated by the sequence \f[B]\-\f[]. So, for example, if you have a python weather script you want assigned to the script key plus the letter w you would name the script /usr/share/fenrir/scripts/weather__\-__key_w.py Then, to access the script, simply press the script key and the letter w. Scripts must be executable. So, make sure to chmod 755 your script when you place it in the scripts directory. The script gets some parameters from fenrir when it is executed. So that information is available in your script then. .SS Parameterlist .PP .TS tab(@); l l. T{ Parameter T}@T{ Content T} _ T{ $1 T}@T{ Username of the current logged in user T} .TE .SS Examples .PP Script that just speaks the current username when pressing ScriptKey + H.\\ File: \[aq]\[aq]/usr/share/fenrir/scripts/helloWorld__\-__key_h.sh\[aq]\[aq]: #!/bin/bash echo $1 .SS Commands .PP You can place your own commands in "/usr/share/fenrir/commands" (path is configurable in settings.conf). Commands are python files with a special scheme. You can assign them to a shortcut using the filename without an extension or place them in a hook trigger like OnInput or OnScreenChange. For further information see developer guide. Good Examples: "date.py" (https///github.com/chrys87/fenrir/blob/master/src/fenrir/commands/commands/date.py) (announce the Date), "shut_up.py" (https///github.com/chrys87/fenrir/blob/master/src/fenrir/commands/commands/shut_up.py) (interrupt output) the basic scheme for a command is as follows: .IP .nf \f[C] from\ core\ import\ debug class\ command(): \ \ def\ __init__(self): \ \ \ \ \ \ pass \ \ def\ initialize(self,\ environment): \ \ \ \ \ \ self.env\ =\ environment \ \ def\ shutdown(self): \ \ \ \ \ \ pass \ \ def\ getDescription(self): \ \ \ \ \ \ return\ _(\[aq]No\ description\ found\[aq]) \ \ def\ run(self): \ \ \ \ \ \ pass \ \ def\ setCallback(self,\ callback): \ \ \ \ \ \ pass \f[] .fi .IP \[bu] 2 Template lives here (https///github.com/chrys87/fenrir/blob/master/src/fenrir/commands/command_template.py) .IP \[bu] 2 The class needs to have the name "command". .IP \[bu] 2 "initialize" is running once whilst loading the command. .IP \[bu] 2 "shutdown" is running on unload like the command (quit fenrir) .IP \[bu] 2 "getDescriptsion" just returns an string. That String is used in Tutorial Mode. .IP \[bu] 2 "run" is executed when the command is invoked. (shortcut is pressed, or trigger isn\[aq]t running) .IP \[bu] 2 setCAllback is currently not used. and has no functionality yet. .SH Troubleshooting .SS Fenrir does not start .IP " 1." 4 Have you installed all the dependencies Support and Requirements (#Support%20and%20Requirements) .IP " 2." 4 Try using master, a lot of changes take place there to make Fenrir compatible with more systems ## Fenrir does not utilize the shortcuts .IP " 3." 4 Make sure you have python3\-evdev installed .IP " 4." 4 Use the latest Fenrir version .IP " 5." 4 Make sure that Fenrir has permission to /dev/input/* and /dev/uinput (or run it as root) ## No sound at all .IP " 6." 4 Run the script to configure Pulseaudio once as root and once as your user. This will setup Pulseaudio but require a restart of Pulseaudio. The script is located in \[aq]\[aq]tools/configure_pulse.sh\[aq]\[aq] .IP " 7." 4 Use ALSA .IP " 8." 4 Configure Pulse system wide (https///www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/SystemWide/) (Not recommended) .IP " 9." 4 Use gstreamerDriver: change \[aq]\[aq]settings.conf\[aq]\[aq] in the section \[aq]\[aq]sound\[aq]\[aq] the line \[aq]\[aq]driver=genericDriver\[aq]\[aq] to \[aq]\[aq]driver=gstreamerDriver\[aq]\[aq] .IP "10." 4 Use wave sound\-icons: change \[aq]\[aq]settings.conf\[aq]\[aq] in the section \[aq]\[aq]sound\[aq]\[aq] the line \[aq]\[aq]theme=default\[aq]\[aq] to \[aq]\[aq]theme=default\-wav\[aq]\[aq] .IP "11." 4 Use most current version of sox (http://sox.sourceforge.net/) with opus support .IP "12." 4 Try apulse (https///github.com/i-rinat/apulse) (not tested by myself but might work). Please give me feedback if you try it out. ## You get sound\-icons but no speech .IP "13." 4 If you are using speech\-dispatcher run "spd\-conf" once as user and as root. .IP "14." 4 You can test if speech\-dispatcher works by invoking it as root\\ \[aq]\[aq]sudo spd\-say "hello world"\[aq]\[aq] ## Bugreports and feature requests .PP Please report Bugs and feature requests to: https://github.com/chrys87/fenrir/issues (https///github.com/chrys87/fenrir/issues) .PP for bugs please provide a debug (#Howto%20create%20a%20debug%20file) file that shows the issue. ### How\-to create a debug file .IP "1." 3 Delete old debug stuff\\ \[aq]\[aq]sudo rm /var/log/fenrir.log\[aq]\[aq] .IP "2." 3 Start fenrir in debug mode\\ \[aq]\[aq]sudo fenrir \-d\[aq]\[aq] .IP "3." 3 Do your stuff to reproduce the problem .IP "4." 3 Stop fenrir (\[aq]\[aq]fenrirKey + q\[aq]\[aq]) the debug file is located in \[aq]\[aq]/var/log/fenrir.log\[aq]\[aq] .PP Please be as precise as possible to make it easy to solve the problem. fenrir-1.5.1/docu/user.md000066400000000000000000002164111317357605400152550ustar00rootroot00000000000000# Fenrir User Manual Fenrir is a modern command line screen reader written in Python3. It has a modular structure, a flexible based driver model, is highly configurable and easy to customize and extend ([see Developer Manual](fenrir_development_manual)). Please see the following pages for the [current](fenrir_current_version) and [Git](fenrir_git_version) version of Fenrir. # Support and Requirements Fenrir requires several drivers to interact with the operating system. ## Speech Drivers A speech driver is for communication with the text to speech system like [Speech-Dispatcher](#SpeechDispatcher) or [Espeak](http://espeak.sourceforge.net). \\ See section [Speech](#Speech) in ''settings.conf'' for more information. ### SpeechDispatcher This driver is used by default. It uses Speech-dispatcher as its backend. Dependencies: * Speech-dispatcher (installed and configured, [Documentation](https///devel.freebsoft.org/speechd#sec2)) * Python-speechd ### Espeak Uses Espeak via Python bindings. Dependencies: * Espeak or Espeak-ng * [python-espeak](https///launchpad.net/python-espeak) ### Generic This invokes speech via a sub-process. This is almost the same as using the commandline. The performance depends on the overhead of the speech synthesis application but it is really flexible. Dependencies: * Espeak or Espeak-ng The Requirements are flexible, they depend on the configuration in settings.conf. ### Dummy this is just for debugging, logs are output to the screen and logged as well. ## Sound Drivers To play sound icons and similar.\\ See section [Sound](#Sound) in ''settings.conf'' for more information. ### Generic This driver is used by default. Dependencies: * [Sox](http://sox.sourceforge.net/) with opus support The Requirements are flexible, they depend on the configuration in settings.conf. ### Gstreamer if you prefer to use Gstreamer for sound output. Dependencies: * Gstreamer >= 1.x * Glibc ### Dummy this is just for debugging, logs are output to the screen and logged as well. ## Input Drivers Input drivers are to capture keyboard shortcuts issued to the screen reader \ See section [Keyboard](#Keyboard) in ''settings.conf'' for more information. ### Evdev This driver is used by default. Evdev is the low level input device framework for Linux. Dependencies: * python-evdev >=0.6.3 * pyudev * loaded uinput kernel module * exclusive access to the input devices Read permission to the following files and services: * /dev/input * /dev/uinput ## Screen Drivers The job of a screen driver is to get the information of current screen content.\\ See section [Screen](#Screen) in ''settings.conf'' for more information. ### VCSA This driver is used by default. For Linux VCSA devices. These exist on any current standard installation of Linux. Dependencie s: * python-dbus Read permission to the following files and services (or run as root): * /sys/devices/virtual/tty/tty0/active * /dev/tty[1 - 64] * /dev/vcsa[1 - 64] ([VCSA manpage](https///linux.die.net/man/4/vcsa)) * read Logind DBUS ## Braille Drivers This is for Braille support. Braille is currently a work in progress and is planned for the Fenrir 2.0 release.\\ See section [Braille](#Braille) in ''settings.conf'' for more information. ### BRLTTY This driver is used by default. It uses [BrlTTY](brltty) to communicate with with a Braille device. Dependencies: * BrlTTY (configured and running, [Documentation](http://mielke.cc/brltty/doc/Manual-BRLTTY/English/BRLTTY.html)) * python-brlapi (configured, [Documentation](http://mielke.cc/brltty/doc/Manual-BrlAPI/English/BrlAPI.html)) ## Currently supported platforms Currently Fenrir completely supports the following Platforms: * Linux TTY Support for further Systems are planned. # Installation Fenrir can run without installation. It just requires the dependencies are installed first. We recommend to try it out before installation to be sure everything works and prevent yourself from experiencing a non-talking environment. ## Try Out Fenrir does not require installation. You can try it and make sure everything works before you decide to install. In this way you can be sure that your system doesnt break or stop talking. for that you can just grab the code and run as root ''src/fenrir/fenrir'' (in foreground) or ''src/fenrir/fenrir-daemon'' (in background, used by systemd for autostart) ## Install it ### Documented operating systems ### Arch Linux For Arch there are PKGBUILDs in the AUR: * [fenrir](https///aur.archlinux.org/packages/fenrir/) * [fenrir-git](https///aur.archlinux.org/packages/fenrir-git/) ### Manual 1. Download the latest stable version from the [Fenrir-Project](https///linux-a11y.org/index.php?page=fenrir-screenreader) site. 2. Unpack the archive 3. Check the needed Dependencys by running [check-dependencys.py](https///github.com/chrys87/fenrir/blob/master/check-dependencies.py) script 4. install the missing dependencies an standard installation requires the following: * python3 >= 3.3 (and all the following is needed for python3 ) * python3-speechd (screen) * python3-dbus (screen) * python3-evdev >= 0.6.4(input) * python3-daemonize (background service) * python3-brlapi (braille) * python3-pyenchant (spellchecker) * your language for aspell (aspell-``) (spellchecker) * sox (sound) * For an individual installation see [Support and Requirements](#Support and Requirements) or consult the [Readme](https///github.com/chrys87/fenrir/blob/master/README.md)) 5. run "install.sh" as root this installs Fenrir as the following * Application:''/opt/fenrir'' * Settings:''/etc/fenrir'' * Sound Icons:''/usr/share/fenrir/'' to remove Fenrir just run uninstall.sh as root ### Git if you want to get the latest code you can use git to get a development snapshot: git clone https://github.com/chrys87/fenrir.git ## Auto Start To start Fenrir once: systemctl start fenrir To enable auto start on system boot: systemctl enable fenrir # First Steps If you are using Fenrir for the first time you may want to take a look at these resources: * [Keybindings](#Keybindings) * [Tutorial Mode](#Tutorial Mode) # Features ## Commands ### Keybindings Normal commands can be invoked in two ways: 1. Using a Metakey ([FenrirKey](#Fenrir Key)) 2. Shortcuts with a single key See section [Keyboard](#Keyboard) in ''settings.conf'' for more information. #### Fenrir Key The Fenrir Key is for invoking screen reader commands. Fenrir can utilize more than one FenrirKey at the same time. By default the following keys are used: 1. Insert 2. KeyPad Insert 3. Meta (Super, Windows) #### Script Key To invoke "Scripts" the Script Key is mandatory. The shortcut is encoded in the filename of the script. See [Scripting](#Scripting) #### Desktop Layout | Shortcut | Command | | -------- | ------- | | FenrirKey + H | [toggle tutorial mode](#Tutorial Mode) | | CTRL | [shut up (interrupts speech)](#shut up) | | FenrirKey + KeyPad 9 | [reviews bottom](#review bottom) | | FenrirKey + KeyPad 7 | [reviews top](#review top) | | KeyPad 8 | [reviews current line](#review current line) | | KeyPad 7 | [reviews previous line](#review previous line) | | KeyPad 9 | [reviews next line](#review next line) | | FenrirKey + KeyPad 4 | [reviews line beginning](#review line beginning) | | FenrirKey + KeyPad 6 | [reviews line ending](#review line ending) | | FenrirKey + KeyPad 1 | [reviews line first character](#review line first character) | | FenrirKey + KeyPad 3 | [reviews line last character](#review line last character) | | FenrirKey + Alt + 1 | [presents first line](#present first line) | | FenrirKey + Alt + 2 | [presents last line](#present last line) | | KeyPad 5 | [reviews current word](#review current word) | | KeyPad 4 | [reviews previous word](#review previous word) | | KeyPad 6 | [reviews next word](#review next word) | | FenrirKey + Shift + KeyPad 5 | [reviews current word phonetic](#review current word phonetic) | | FenrirKey + Shift + KeyPad 4 | [reviews previous word phonetic](#review previous word phonetic) | | FenrirKey + Shift + KeyPad 6 | [reviews next word phonetic](#review next word phonetic) | | KeyPad 2 | [reviews current char](#review current character) | | KeyPad 1 | [reviews previous char](#review previous character) | | KeyPad 3 | [reviews next char](#review next character) | | FenrirKey + Shift + KeyPad 2 | [reviews current character phonetic](#review current character phonetic) | | FenrirKey + Shift + KeyPad 1 | [reviews previous character phonetic](#review previous character phonetic) | | FenrirKey + Shift + KeyPad 3 | [reviews next character phonetic](#review next character phonetic) | | FenrirKey + CTRL + KeyPad 8 | [reviews up](#review up) | | FenrirKey + CTRL + KeyPad 2 | [reviews down](#review down) | | FenrirKey + KeyPad dot | [exit review](#exit review) | | KeyPad dot | [cursor position](#cursor position) | | FenrirKey + I | [indent curr line](#indent current line) | | FenrirKey + KeyPad 5 | [current screen](#current screen) | | FenrirKey + KeyPad 8 | [current screen before cursor](#current screen before cursor) | | FenrirKey + KeyPad 2 | [current screen after cursor](#current screen after cursor) | | `` | [cursor read to end of line](#cursor read to end of line) | | `` | [cursor column](#cursor column) | | `` | [cursor line number](#cursor line number) | | `` | [Braille flush](#braille flush) | | `` | [Braille pan left](#braille pan left) | | `` | [Braille pan right](#braille pan right) | | `` | [Braille return to cursor](#braille return to cursor) | | FenrirKey + CTRL + 1 | [clear bookmark 1](#clear Bookmark X) | | FenrirKey + Shift + 1 | [set bookmark 1](#set Bookmark X) | | FenrirKey + 1 | [bookmark 1](#read Bookmark X) | | FenrirKey + CTRL + 2 | [clear bookmark 2](#clear Bookmark X) | | FenrirKey + Shift + 2 | [set bookmark 2](#set Bookmark X) | | FenrirKey + 2 | [bookmark 2](#read Bookmark X) | | FenrirKey + CTRL + 3 | [clear bookmark 3](#clear Bookmark X) | | FenrirKey + Shift + 3 | [set bookmark 3](#set Bookmark X) | | FenrirKey + 3 | [bookmark 3](#read Bookmark X) | | FenrirKey + CTRL + 4 | [clear bookmark 4](#clear Bookmark X) | | FenrirKey + Shift + 4 | [set bookmark 4](#set Bookmark X) | | FenrirKey + 4 | [bookmark 4](#read Bookmark X) | | FenrirKey + CTRL + 5 | [clear bookmark 5](#clear Bookmark X) | | FenrirKey + Shift + 5 | [set bookmark 5](#set Bookmark X) | | FenrirKey + 5 | [bookmark 5](#read Bookmark X) | | FenrirKey + CTRL + 6 | [clear bookmark 6](#clear Bookmark X) | | FenrirKey + Shift + 6 | [set bookmark 6](#set Bookmark X) | | FenrirKey + 6 | [bookmark 6](#read Bookmark X) | | FenrirKey + CTRL + 7 | [clear bookmark 7](#clear Bookmark X) | | FenrirKey + Shift + 7 | [set bookmark 7](#set Bookmark X) | | FenrirKey + 7 | [bookmark 7](#read Bookmark X) | | FenrirKey + CTRL + 8 | [clear bookmark 8](#clear Bookmark X) | | FenrirKey + Shift + 8 | [set bookmark 8](#set Bookmark X) | | FenrirKey + 8 | [bookmark 8](#read Bookmark X) | | FenrirKey + CTRL + 9 | [clear bookmark 9](#clear Bookmark X) | | FenrirKey + Shift + 9 | [set bookmark 9](#set Bookmark X) | | FenrirKey + 9 | [bookmark 9](#read Bookmark X) | | FenrirKey + CTRL + 0 | [clear bookmark 10](#clear Bookmark X) | | FenrirKey + Shift + 0 | [set bookmark 10](#set Bookmark X) | | FenrirKey + 0 | [bookmark 10](#read Bookmark X) | | FenrirKey + KeyPad Slash | [set window application](#Create Window) | | 2 * FenrirKey + KeyPad Slash | [clear window application](#Remove Window) | | KeyPad Plus | [read last incoming](#last incoming) | | FenrirKey + F2 | [toggles braille](#toggle braille) | | FenrirKey + F3 | [toggles sound](#toggle sound) | | FenrirKey + F4 | [toggles speech](#toggle speech) | | KeyPad Enter | [temporarily disables speech](#disable speech temporarily) | | FenrirKey + CTRL + P | [toggles punctuation level](#toggle punctuation level) | | FenrirKey + RightBrace | [toggle auto spell check](#toggle auto spell check) | | FenrirKey + Backslash | [toggles output](#toggle output) | | FenrirKey + CTRL + E | [toggles emoticons](#toggle emoticons) | | FenrirKey + KeyPad Enter | [toggles auto read](#toggle auto read) | | FenrirKey + CTRL + T | [toggles auto time](#toggle auto time) | | FenrirKey + KeyPad ASTERISK | [toggles highlight tracking](#toggle highlight tracking) | | FenrirKey + Q | [quits fenrir](#quit Fenrir) | | FenrirKey + T | [Announce time](#Time) | | 2 * FenrirKey + T | [Announce date](#Date) | | FenrirKey + S | [spell check](#spell check) | | 2 * FenrirKey + S | [add word to spell check](#add word to spell check) | | FenrirKey + Shift + S | [removes word from spell check](#removes word from spell check) | | FenrirKey + Backspace | [forward keypress](#forward keypress) | | FenrirKey + Up | [increase speech volume](#increase speech volume) | | FenrirKey + Down | [decrease speech volume](#decrease speech volume) | | FenrirKey + Right | [increase speech rate](#increase speech rate) | | FenrirKey + Left | [decrease speech rate](#decrease speech rate) | | FenrirKey + Alt + Right | [increase speech pitch](#increase speech pitch) | | FenrirKey + Alt + Left | [decrease speech pitch](#decrease speech pitch) | | FenrirKey + Alt + Up | [increase sound volume](#increase sound volume) | | FenrirKey + Alt + Down | [decrease sound volume](#decrease sound volume) | | FenrirKey + CTRL + Shift + C | [clears clipboard](#clear clipboard) | | FenrirKey + Home | [first clipboard](#first clipboard) | | FenrirKey + End | [last clipboard](#last clipboard) | | FenrirKey + PageUp | [previous clipboard](#previous clipboard) | | FenrirKey + PageDown | [next clipboard](#next clipboard) | | FenrirKey + Shift + C | [current clipboard](#read current clipboard) | | FenrirKey + C | [copy marked text to clipboard](#copy marked to clipboard) | | FenrirKey + V | [paste clipboard contents](#paste clipboard) | | FenrirKey + P | [import clipboard from file](#import clipboard from file) | | FenrirKey + Alt + Shift +C | [export clipboard to file](#export clipboard to file) | | FenrirKey + CTRL + Shift + X | [remove marks](#Remove Marks) | | FenrirKey + X | [set mark](#Set mark) | | FenrirKey + Shift + X | [announce marked text](#Get text between marks) | | Linux specific | | `` | export clipboard to X | | FenrirKey + CTRL + Up | include Alsa volume | | FenrirKey + CTRL + Down | decrease Alsa volume | #### Laptop Layout | Shortcut | Command | | -------- | ------- | | FenrirKey + H | [toggle tutorial mode](#Tutorial Mode) | | CTRL | [shut up (interrupts speech)](#shut up) | | FenrirKey + Shift + O | [reviews bottom](#review bottom) | | FenrirKey + Shift + U | [reviews top](#review top) | | FenrirKey + I | [reviews current line](#review current line) | | FenrirKey + U | [reviews previous line](#review previous line) | | FenrirKey + O | [reviews next line](#review next line) | | FenrirKey + Shift + J | [reviews line beginning](#review line beginning) | | FenrirKey + Shift + L | [reviews line ending](#review line ending) | | FenrirKey + CTRL + J | [reviews line first character](#review line first character) | | FenrirKey + CTRL + L | [reviews line last character](#review line last character) | | FenrirKey + Alt + 1 | [presents first line](#present first line) | | FenrirKey + Alt + 2 | [presents last line](#present last line) | | FenrirKey + K | [reviews current word](#review current word) | | FenrirKey + J | [reviews previous word](#review previous word) | | FenrirKey + L | [reviews next word](#review next word) | | FenrirKey + CTRL + ALT + K | [reviews current word phonetic](#review current word phonetic) | | FenrirKey + CTRL + ALT + J | [reviews previous word phonetic](#review previous word phonetic) | | FenrirKey + CTRL + ALT + L | [reviews next word phonetic](#review next word phonetic) | | FenrirKey + comma | [reviews current character](#review current character) | | FenrirKey + M | [reviews previous character](#review previous character) | | FenrirKey + dot | [reviews next character](#review next character) | | FenrirKey + CTRL + ALT + comma | [reviews current character phonetic](#review current character phonetic) | | FenrirKey + CTRL + ALT + M | [reviews previous character phonetic](#review previous character phonetic) | | FenrirKey + CTRL + ALT + dot | [reviews next character phonetic](#review next character phonetic) | | FenrirKey + CTRL + I | [reviews up](#review up) | | FenrirKey + CTRL + comma | [reviews down](#review down) | | FenrirKey + Slash | [exit review](#exit review) | | FenrirKey + Shift + dot | [cursor position](#cursor position) | | 2 * FenrirKey + I | [indent curr line](#indent current line) | | FenrirKey + Shift + K | [current screen](#current screen) | | FenrirKey + Shift + I | [current screen before cursor](#current screen before cursor) | | FenrirKey + Shift + comma | [current screen after cursor](#current screen after cursor) | | `` | [cursor read to end of line](#cursor read to end of line) | | `` | [cursor column](#cursor column) | | `` | [cursor line number](#cursor line number) | | `` | [Braille flush](#braille flush) | | `` | [Braille pan left](#braille pan left) | | `` | [Braille pan right](#braille pan right) | | `` | [Braille return to cursor](#braille return to cursor) | | FenrirKey + CTRL + 1 | [clear bookmark 1](#clear Bookmark X) | | FenrirKey + Shift + 1 | [set bookmark 1](#set Bookmark X) | | FenrirKey + 1 | [bookmark 1](#read Bookmark X) | | FenrirKey + CTRL + 2 | [clear bookmark 2](#clear Bookmark X) | | FenrirKey + Shift + 2 | [set bookmark 2](#set Bookmark X) | | FenrirKey + 2 | [bookmark 2](#read Bookmark X) | | FenrirKey + CTRL + 3 | [clear bookmark 3](#clear Bookmark X) | | FenrirKey + Shift + 3 | [set bookmark 3](#set Bookmark X) | | FenrirKey + 3 | [bookmark 3](#read Bookmark X) | | FenrirKey + CTRL + 4 | [clear bookmark 4](#clear Bookmark X) | | FenrirKey + Shift + 4 | [set bookmark 4](#set Bookmark X) | | FenrirKey + 4 | [bookmark 4](#read Bookmark X) | | FenrirKey + CTRL + 5 | [clear bookmark 5](#clear Bookmark X) | | FenrirKey + Shift + 5 | [set bookmark 5](#set Bookmark X) | | FenrirKey + 5 | [bookmark 5](#read Bookmark X) | | FenrirKey + CTRL + 6 | [clear bookmark 6](#clear Bookmark X) | | FenrirKey + Shift + 6 | [set bookmark 6](#set Bookmark X) | | FenrirKey + 6 | [bookmark 6](#read Bookmark X) | | FenrirKey + CTRL + 7 | [clear bookmark 7](#clear Bookmark X) | | FenrirKey + Shift + 7 | [set bookmark 7](#set Bookmark X) | | FenrirKey + 7 | [bookmark 7](#read Bookmark X) | | FenrirKey + CTRL + 8 | [clear bookmark 8](#clear Bookmark X) | | FenrirKey + Shift + 8 | [set bookmark 8](#set Bookmark X) | | FenrirKey + 8 | [bookmark 8](#read Bookmark X) | | FenrirKey + CTRL + 9 | [clear bookmark 9](#clear Bookmark X) | | FenrirKey + Shift + 9 | [set bookmark 9](#set Bookmark X) | | FenrirKey + 9 | [bookmark 9](#read Bookmark X) | | FenrirKey + CTRL + 0 | [clear bookmark 10](#clear Bookmark X) | | FenrirKey + Shift + 0 | [set bookmark 10](#set Bookmark X) | | FenrirKey + 0 | [bookmark 10](#read Bookmark X) | | FenrirKey + CTRL + 8 | [set window application](#Create Window) | | 2 * FenrirKey + CTRL + 8 | [clear window application](#Remove Window) | | FenrirKey + Semicolon | [read last incoming](#last incoming) | | FenrirKey + F2 | [toggles braille](#toggle braille) | | FenrirKey + F3 | [toggles sound](#toggle sound) | | FenrirKey + F4 | [toggles speech](#toggle speech) | | FenrirKey + Enter | [temporarily disables speech](#disable speech temporarily) | | FenrirKey + Shift + CTRL + P | [toggles punctuation level](#toggle punctuation level) | | FenrirKey + RightBrace | [toggle auto spell check](#toggle auto spell check) | | FenrirKey + Shift + Enter | [toggles output](#toggle output) | | FenrirKey + Shift + E | [toggles emoticons](#toggle emoticons) | | FenrirKey + Enter | [toggles auto read](#toggle auto read) | | FenrirKey + CTRL + T | [toggles auto time](#toggle auto time) | | FenrirKey + Y | [toggles highlight tracking](#toggle highlight tracking) | | FenrirKey + Q | [quits fenrir](#quit Fenrir) | | FenrirKey + T | [Announce time](#Time) | | 2 * FenrirKey + T | [Announce date](#Date) | | FenrirKey + S | [spell check](#spell check) | | 2 * FenrirKey + S | [add word to spell check](#add word to spell check) | | FenrirKey + Shift + S | [removes word from spell check](#removes word from spell check) | | FenrirKey + Backspace | [forward keypress](#forward keypress) | | FenrirKey + Up | [increase speech volume](#increase speech volume) | | FenrirKey + Down | [decrease speech volume](#decrease speech volume) | | FenrirKey + Right | [increase speech rate](#increase speech rate) | | FenrirKey + Left | [decrease speech rate](#decrease speech rate) | | FenrirKey + Alt + Right | [increase speech pitch](#increase speech pitch) | | FenrirKey + Alt + Left | [decrease speech pitch](#decrease speech pitch) | | FenrirKey + Alt + Up | [increase sound volume](#increase sound volume) | | FenrirKey + Alt + Down | [decrease sound volume](#decrease sound volume) | | FenrirKey + CTRL + Shift + C | [clears clipboard](#clear clipboard) | | FenrirKey + Home | [first clipboard](#first clipboard) | | FenrirKey + End | [last clipboard](#last clipboard) | | FenrirKey + PageUp | [previous clipboard](#previous clipboard) | | FenrirKey + PageDown | [next clipboard](#next clipboard) | | FenrirKey + Shift + C | [current clipboard](#read current clipboard) | | FenrirKey + C | [copy marked text to clipboard](#copy marked to clipboard) | | FenrirKey + V | [paste clipboard contents](#paste clipboard) | | FenrirKey + F5 | [import clipboard from file](#import clipboard from file) | | FenrirKey + Alt + Shift +C | [export clipboard to file](#export clipboard to file) | | FenrirKey + CTRL + Shift + X | [remove marks](#Remove Marks) | | FenrirKey + X | [set mark](#Set mark) | | FenrirKey + Shift + X | [announce marked text](#Get text between marks) | | Linux specific | | `` | export clipboard to X | | FenrirKey + CTRL + Up | increases Alsa volume | | FenrirKey + CTRL + Down | decreases Alsa volume | ### General #### quit Fenrir Just stops fenrir. #### shut up Interrupt the current spoken. ### Review Modes Fenrir provides a virtual cursor, with it you can navigate all over the screen without changing the text cursor. Using the review feature will open the review mode automatically. The review cursor always starts from the text cursor. Attention: after using the review mode, the review cursor will stay open until you use the ''exit review'' shortcut. Think when using clipboard operations and similar. The review cursor is always prefered over the text cursor. Fenrir sounds a bell sound if the used review command jumps to another line or end of screen. #### exit review You can leave the review mode by pressing the ''exit review'' shortcut. #### review bottom Set the review cursor to first column in the last line. #### review top Set the review cursor to the first column in the first line #### review current line Set the review cursor to the beginn of the the current line and review it. #### review previous line Set the review cursor to the previous line and review it. #### review next line Set the review cursor to the next line and review it. #### review line beginning Set the review cursor to the begin of the current line #### review line ending Set the review cursor to the end of the current line #### review line first character Set the review cursor the first char (that is not space) in the current line and review it. #### review line last character Set the review cursor the last char (that is not space) in the current line and review it. #### review current word Sets the review cursor to the beginning of the current word and review it. #### review previous word Sets the review cursor to the beginning of the previous word and review it. #### review next word Sets the review cursor to the beginning of the next word and review it. #### review current word phonetic Sets the review cursor to the beginning of the current word and spell it phonetic. #### review previous word phonetic Sets the review cursor to the beginning of the previous word and spell it phonetic. #### review next word phonetic Sets the review cursor to the beginning of the next word and spell it phonetic. #### review current character Does not change the review cursor. Just announce the current char. #### review previous character Sets review cursor to the previous column and review it #### review next character Sets review cursor to the next column and review it #### review current character phonetic Does not change the review cursor. Just announce the current char phonetic. #### review previous character phonetic Sets review cursor to the previous column and announce the char phonetic. #### review next character phonetic Sets review cursor to the next column and announce the char phonetic. #### review up Set the review cursor in the same column one line above the current one and review it. #### review down Set the review cursor in the same column one line below the current one and review it. ### Handling marking A mark defines a point of origin or end to prepare to copy or paste a block of text. \\ Examples where you need marks are: * copy to clipboard * set window application * set bookmark 1 - X #### Set mark How to set a mark: 1. navigate with review or textcursor to the position you want to set the mark. Attention: if a review cursor is set, that is the prefered. If you want to use text cursor, be sure that you are not in review mode. 2. press shortcut for ''set mark'' you can set two marks (begin and end). Some commands allow some simpler usecases just using the whole line if only one mark is set. you may want to try this out. #### Get text between marks To get the text that is currently between your marks press shortcut for ''marked text''.\\ #### Remove Marks You can remove all current marks by pressing the shortcut for ''remove marks''. Changing the screen also removes the marks. ### Screen Interaction Fenrir provides several methods to interact with the current screen. #### forward keypress This just forwards the next shortcut to the screen Fenrir shortcut or not. This is useful if the currently pressed shortcut is also in use by Fenrir. #### Clipboard Fenrir provides a clipboard with multible items represented by a list. You navigate throught the list and paste the selected clipboard. ##### copy marked to clipboard To copy something to the clipboard you need to set one or two marks. if you set one mark, the text between the mark and your current cursor is copied to clipboard. Setting two marks just copies the text between the marks into the clipboard. If you copy something it is always placed as the first item on your clipboard. ##### clear clipboard You can remove all items from the current clipboard by ''clear clipboard'' functionality. ##### first clipboard This moves quick to the first item of the clipboard. ##### last clipboard This moves quick to the last item of the clipboard. ##### previous clipboard Go to previous item in the clipboard. ##### next clipboard Go to next item on the clipboard. ##### read current clipboard Read the content of the current item of the clipboard. ##### paste clipboard Pass whatever item is currently selected by first, last, prev or next clipboard commands. if no special clipboard is selected the (last copied) is used. ##### export clipboard to file This allows you to export the current clipboard to a configurable filepath. This is useful to share the clipboard with a graphical desktop. ##### import clipboard from file Import a clipboard from a configurable file. This is useful to share the clipboard with a graphical desktop. ### Quick Settings Fenrir provides shortcuts to change settings temporarily and on the fly without the need to permanently change the ''settings.conf'' file. #### toggle braille Enables and disables Braille. This is not persistent stored in your ''settings.conf'' but during run time. #### toggle sound Enables and disables sound. This is not persistent stored in your ''settings.conf'' but during run time. #### toggle speech Enables and disables speech. This is not persistent stored in your ''settings.conf'' but during run time. #### disable speech temporarily Disables the speech until next key press. it might be useful if you want to listen to music or similar. As soon as a key is pressed it is going to be enabled again. #### toggle punctuation level Cycle between all available punctuation levels. This is not persistent stored in your ''settings.conf'' but during run time. #### toggle auto spell check Enables and disables automatic spellchecker (when typing). This is not persistent stored in your ''settings.conf'' but during run time. #### toggle emoticons Enables and disables emoticons. This is not persistent stored in your ''settings.conf'' but during runtime. #### toggle output Enables and disables all output at once (sound, Braille, speech). This is not persistent stored in your ''settings.conf'' but during run time. #### toggle auto read Enables and disables what is automatically spoken. This is not persistent stored in your ''settings.conf'' but during run time. #### toggle auto time Enables and disables auto time functionality. This is not persistent stored in your ''settings.conf'' but during run time. #### toggle highlight tracking Enables and disables highlight tracking. This is not persistent stored in your ''settings.conf'' but during run time. #### increase speech volume Increase the volume of the speech. This is not persistent stored in your ''settings.conf'' but during runtime. #### decrease speech volume Decrease the volume of the speech. This is not persistent stored in your ''settings.conf'' but during runtime. #### increase speech rate Increase the rate of the speech. This is not persistent stored in your ''settings.conf'' but during runtime. #### decrease speech rate Decrease the rate of the speech. This is not persistent stored in your ''settings.conf'' but during runtime. #### increase speech pitch Increase the pitch of the speech. This is not persistent stored in your ''settings.conf'' but during runtime. #### decrease speech pitch Decrease the pitch of the speech. This is not persistent stored in your ''settings.conf'' but during runtime. #### increase sound volume Increase the volume of the sound. This is not persistent stored in your ''settings.conf'' but during runtime. #### decrease sound volume Decrease the volume of the sound. This is not persistent stored in your ''settings.conf'' but during runtime. ### Window Mode Fenrir supports window mode, a window is a partial area of the screen. #### Create Window To create a window you need to do the following: 1. set a beginning mark (as the start of the window) 2. set an end mark (where the window should end) 3. press ''set window application'' shortcut. Now Fenrir ignores anything outside of the window.\\ #### Remove Window You can remove the window by pressing ''the clear window application'' shortcut. Now Fenrir will read everything on the screen again. ### Tracking Modes Different types of tracking are currently supported See section [Focus](#Focus) in ''settings.conf'' for more information. #### Cursor Tracking This follows the text cursor. This is the typical way an application works. This is used by: * almost any shell such as (Bash, Zsh, sh) * vim * nano * emacs * mutt * tintin++ #### Highlight Tracking In some applications there are no text cursors. In those applications cursor changes are represented by different colors or attributes (underlined or bold). This mode tracks and announces these changes for you. This is used by: * wifi-menu * dialog * alpine ### Tutorial Mode Fenrir provides a Tutorial mode. When you enter tutorial mode, screen reader commands are intercepted and explained instead of executing them. ''Arrow up'' and ''Arrow Down'' let you navigate through a list of all available commands with shortcuts and description. Pressing escape leaves the tutorial mode. ### Information #### Time Announces the current Time. #### Date Announces the current Date. #### Bookmarks Bookmarks provide quick access to part of the screen without the need to navigate to the area. By default Fenrir provides 10 bookmarks. Those can be set and accessed via shortcut. This is useful for status lines or other information where the position does not change. ##### set Bookmark X You need to set the bookmark first. For that you have to set one or two lines for use. 1. Set marks (one or two) 2. press shortcut for ''set bookmark X''. X represents the number 1 - 10. ##### read Bookmark X If a bookmark is set you can access the area just by pressing the ''bookmark X'' shortcut. X represents the number 1 - 10. Bookmarks are dynamic. That means the content changes with the screen. ##### clear Bookmark X to remove a bookmark just press the ''clear bookmark X'' shortcut. X represents the number 1 - 10. Afterward the bookmark is no longer available. #### cursor position You can get information about the current cursor and its position by using the "cursor position" functionality. #### indent current line Announce the current indent level of the current line. It represents the number of trailing spaces of the line. #### current screen Reads all the current screen from the beginning to the end. #### current screen before cursor Reads current screen from the beginning of the screen to the current cursor position. #### current screen after cursor Read anything after current cursor position to the end. #### cursor read to end of line Read from the current cursor position to the end of the current line. #### cursor column Read the current X position of a cursor (column of the current line). #### cursor line number Read the current Y position of a cursor (line number). #### present first line Reads just the first line. this is maybe useful for status information. #### present last line Presets the last line. This is maybe useful for status information. #### last incoming Repeat the last automatically incoming text. ## Input ### Echo Fenrir provides different methods of echoing content: * Word: Will speak each word after you push space * Character: speak any letter you type on the screen * Delete Character: speaks the character prior to the cursor when you push backspace ### Silence on Key press ### Spellchecker Fenrir has a built-in spellchecker, it can invoke automatically while typing or be called by a shortcut. Commands to add or remove the current word to the dictionary are included. As using the spellchecker is enhanced usage. You will need dictionary aspell-``. See section [General](#General) in ''settings.conf'' for more information. #### spell check Invokes the spellcheck on the word that contains the Review or text cursor. #### add word to spell check Adds the word under the Review or Text cursor to the dictionary. #### removes word from spell check Removes the word under the Review or Text cursor from the dictionary. ## Announcements ### Emoticons If you want to replace ":)" emoticons with "smile" in speech you can use this feature. It can be toggled on or off. You can define emoticons in a dictionary, please see Emoticon Dictionary. See section [General](#General) in ''settings.conf'' to see how to enable or disable this feature. ### Time Announce the time at periodical increments, To track the time easily. You can define 2 different ways of time announcements. 1. periodic 2. on fix minutes Example periodic, every 20 minutes "delaySec=20": [time] enabled=True presentTime=True presentDate=True delaySec=20 onMinutes= announce=True interrupt=False Example on fix minutes in an hour. example every quarter "delaySec=0" and "onMinutes=00,15,30,45": [time] enabled=True presentTime=True presentDate=True #delaySec is repected bevore onMinutes so it need to be set to 0 delaySec=0 onMinutes=00,15,30,45 announce=True interrupt=False ### Promoted List Promoted Lists are a nice feature if you are away from your computer or performing more longer tasks. you can define a list of words which you want to hear a sound icon for after a period of inactivity. Example if the word "Chrys" appears after 120 Seconds of inactivity: [promote] enabled=True inactiveTimeoutSec=120 list=Chrys See section [Promote](#Promote) in ''settings.conf'' for more information. ### Punctuation Fenrir handles punctuation levels and names for you with several provided dictionaries. See levelDict See punctuationDict ## Braille Fenrir provides Braille support in Version >= 2.0. See section [Braille](#Braille) in ''settings.conf'' for more information. ### braille flush If a message appears on the Braille device you can flush it to get back to the review- or system cursor ### Braille pan left If a line is longer than your Braille devices you can move the view (called panning) to the left. So you can read stuff without the need to move the review- or system cursor. ### Braille pan right If a line is longer than your Braille devices you can move the view (called panning) to the right. So you can read stuff without the need to move the review- or system cursor. ### braille return to cursor When you have finished reading the line on the Braille device using panning, the focus can be returned to the current used cursor by using "return to cursor" command. ## Dictionary You can make use of different kinds of built-in dictionary's. A dictionary has a name and list of keys and values separated by :===: Example: [customDict] Chrys:===:Chrys is cool lollipop:===:lolli that means that every instance "chrys" is displayed, speech will say Chrys is cool. "lollipop" is spoken as "lolli". Before making changes to a dictionary we recommend making a backup of your current dictionary in case future updates overwrite your local changes. ### Punctuation #### Level The punctuation level dict contains lists with "what punctuation is spoken in what level". the default one looks like this: [levelDict] none:===: some:===:.-$~+*-/\@ most:===:.,:-$~+*-/\@!#%^&*()[]}{`<>`; all:===:!"#$%& \'()*+,-./:;`<=>`?@[\\]^_`{|}~ the level "none" has no values. so it should not speak any punctuation (sadly this is not respected by every TTS system) if "some" is the current level the following are spoken: dot dash dollar tilde plus star slash backslash at. same for most and all, you can add new levels. if you cycle punctuation levels they are recognized. the default punctuation level is set in settings.conf. The default is "some". #### Punctuation The punctuation dictionary "[punctDict]" contains how the punctuation is spoken. Example: [punctDict] _:===:line speaks an _ as "line". [punctDict] _:===:underscore speaks an _ as underscore. for question mark an ? is appended to the word that the TTS system can announce the question correctly. ### Custom The dict "[customDict]" is just for your own use, it just replace the key with the value without any special functionality. This might be used to fix incorrectly spoken words, make words more common, shorter or just for fun. :) ### Emoticons The Emoticons dictionary "[emoticonDict]" by default contains some emoticons. it can replace ":)" with "smile" or "XD" with "loool" Making chat more colorful. A nice feature with this dictionary is that you can toggle the substitution on or off during run time or in settings.conf. This is useful because while doing programming or other serious work you want to hear colons and perryns not smiles. # Configuration You can configure Fenrir in the following places (ordered by priority): 1. Commandline Parameters ''-o'' see [Set settings coption](#Set settings coption) 2. /etc/fenrir/settings/settings.conf see [Settigns](#Settings) 3. ``/config/settings/settings.conf see [Settigns](#Settings) 4. hard coded defaults ## Commandline Arguments ### Set settings option You can specify options that overwrite the setting.conf. This is done with ''-o `` parameter. The list of options have the following syntax fenrir -o "section#setting=value;section#setting=value" For example changing the sound driver to gstreamer and disabling Braille fenrir -o "sound#driver=gstreamerDriver;braille#enabled=False=False" or change the debug level to verbose fenrir -o "general#debugLevel=3" You can find the available sections and variables here [#Settings](#Settings) See Syntax [#settings.conf syntax](#settings.conf syntax) ### settings.conf syntax the syntax of the [settings.conf](#Settings) is quite simple and similar to a "*.ini" file, there are 4 different elements. 1. Sections 2. Settings 3. Values 4. Comments A comment starts with a # and is ignored by Fenrir. # this is a comment To group settings we have sections. A section can look like this: [Section] A setting looks like this: settingName=Value Example: [sound] # Turn sound on or off: enabled=True # Select the driver used to play sounds, choices are genericDriver and gstreamerDriver. # Sox is default. driver=genericDriver ## Settings ### Sound The sound is configured in section ''[sound]''. Turn sound on or off: enabled=True Values: on=''True'', off=''False'' Select the driver used to play sounds. The genericDriver using Sox is the default. driver=genericDriver Available Drivers: * ''genericDriver'' using the generic driver, for Fenrir <1.5 just use ''generic'' * ''gstreamerDriver'' using the gstreamer, for Fenrir <1.5 just use ''gstreamer'' These are the pack of sounds used for sound icons. theme=default By default we ship two sound packs. 1. ''default'' opus encoded, for newer Sox versions 2. ''default-wav'' wav encoded, just for compatibility Sound packs are located at /usr/share/sounds/fenrir/ Sound volume controls how loud the sounds for your selected sound pack are. volume=1.0 Values: ''0.0'' is quietest, ''1.0'' is loudest. #### Generic Driver The generic sound driver uses shell commands for play sound and frequencies. ''genericPlayFileCommand'' defines the command that is used to play a sound file. genericPlayFileCommand=`` ''genericFrequencyCommand'' defines the command that is used playing frequencies. genericFrequencyCommand=`` The following variables are substituted in ''genericPlayFileCommand'' and ''genericFrequencyCommand'': * ''fenrirVolume'' = the current volume setting * ''fenrirSoundFile'' = the sound file for an sound icon * ''fenrirFrequence'' = the frequency to play * ''fenrirDuration'' = the duration of the frequency Example genericPlayFileCommand (default) genericPlayFileCommand=play -q -v fenrirVolume fenrirSoundFile Example genericFrequencyCommand (default) genericFrequencyCommand=play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence ### Speech Speech is configured in section ''[speech]''. Turn speech on or off: enabled=True Values: on=''True'', off=''False'' # Select speech driver, options are speechdDriver (default), genericDriver or espeakDriver: driver=speechdDriver #driver=espeakDriver #driver=genericDriver Select the driver used to generate speech output. driver=speechdDriver Available Drivers: * ''genericDriver'' using the generic driver, for Fenrir <1.5 this is not available * ''speechdDriver'' using speech-dispatcher, for Fenrir <1.5 just use ''speechd'' * ''espeakDriver'' using the espeak directly, for Fenrir <1.5 just use ''espeak'' The rate selects how fast Fenrir will speak. rate=0.65 Values: Range Minimum:''0.0'' is slowest, Maximum:''1.0'' is fastest. Pitch controls the pitch of the voice. pitch=0.5 Values: Range Minimum:''0.0'' is lowest, Maximum:''1.0'' is highest. A Pitch for capital letters can be set. capitalPitch=0.9 Values: Range Minimum:''0.0'' is lowest, Maximum:''1.0'' is highest. The Volume controls the loudness of the voice. volume=1.0 Values: Range Minimum:''0.0'' is quietest, Maximum:''1.0'' is loudest. Some speech drivers like speechdDriver can support various modules. these can be set here. module=espeak Values: Text, Consult speech-dispatcher's configuration to see what modules are available. Voice selects the varient you want to use, for example, f5 will use the female voice #5 in Espeak, or if using the Espeak module in Speech-dispatcher. To find out which voices are available, consult the documentation provided with your selected synthesizer. voice= Values: Text, see your TTS synths documentation what is available. Select the language you want Fenrir to use. language=english-us Values: Text, see your TTS synths documentation what is available. Read new text as it occurs autoReadIncoming=True Values: on=''True'', off=''False'' #### Generic Driver The generic speech driver uses shell commands for speech synthisus. ''genericSpeechCommand'' defines the command that is executed for creating speech The following variables are substituted in ''genericSpeechCommand'': * ''FenrirText'' = is the text that should be spoken * ''fenrirModule'' = may be the speech module like used in speech-dispatcher, not every TTY needs this * ''fenrirLanguage'' = the language to speak in * ''fenrirVoice'' = is the current voice that should be used * ''fenrirVolume'' = is replaced with the current volume * ''fenrirPitch'' = is replaced with the current pitch * ''fenrirRate'' = is replaced with the current speed (speech rate) Example genericSpeechCommand (default): genericSpeechCommand=espeak -a fenrirVolume -s fenrirRate -p fenrirPitch -v fenrirVoice "fenrirText" These are the minimum and maximum values of the TTS system used in genericSpeechCommand. They are needed to calculate the abstract range in volume, rate and pitch 0.0 - 1.0. FenrirMinVolume=0 fenrirMaxVolume=200 fenrirMinPitch=0 fenrirMaxPitch=99 fenrirMinRate=80 fenrirMaxRate=450 The current volume, pitch and rate is calculated like this value = min + [volume,pitch,rate] * (min - max ) ### Braille Braille is a WIP and not ready yet. Braille support can be configured in section ''[braille]''. Turn braille on or off: enabled=False Values: on=''True'', off=''False'' Select the driver used for communication with a braille device. driver=brlapiDriver Values: Text, available Driver Available Drivers: * ''brlttyDriver'' using brltty for braille communication, for Fenrir <1.5 just use ''brltty'' The Braille layout can be configured here layout=en Values: Text, see braille driver for layouts. What should the flush timeout relate to flushMode=word Values: Text, an flushMode Existing flushModes: * ''word'' = flush after (number of words to display) * seconds * ''char'' = flush after (number of chars to display) * seconds * ''fix'' = flush after X seconds * ''none'' = no automatic flush (manual via shortcut) Seconds to flush (see flushMode) flushTimeout=3 Values: Integer, in Seconds or ''-1'' = no automatic flush (manual via shortcut) The total flush time calculates in relation to flushMode. How should the Braille cursor focus be tracked? cursorFocusMode=page Values: Text, an existing cursor focus mode Available cursor focus modes: * ''page'' = if the cursor crosses the border move to next page and start at begin * ''fixCell'' = ajust the cursor on a special cell where it is always placed. the display scroll here more smooth. Define the cell on the Braille device where Fenrir should scroll and keep the cursor fixCursorOnCell=-1 Values: Integer * ''0'' = first cell on device, * ''-1'' = last cell on device * ''>0'' = fix cell number What cursor should Fenrir show on the Braille device cursorFollowMode=review Values: Text, an exsiting cursor following mode. Existing cursor following mode: * ''none'' = no automatic toggle command used * ''review'' = priority to review * ''last'' = follow last used cursor number of cells in panning (horizontal). How many cell should be panned on press the routing key? panSizeHorizontal=0 Values: Integer, * ''0'' = display size * ''>0'' number of cells ### Screen The settings for screens, (TTY, PTY) are configured in the ''[screen]'' section. The driver to get the information from the screen: driver=vcsaDriver Available Drivers: * ''vcsaDriver'' using the VCSA driver (for TTYs), for Fenrir <1.5 just use ''vcsa'' The encoding of the screen encoding=cp850 Values:''cp850'' is used for Western languages like USA or Europe. The driver updates Fenrir with changes on the screen. screenUpdateDelay=0.05 Values: in Seconds If you want Fenrir to not be active on any screen for various reasons. Maybe an X server or Wayland is running on that screen. You can make Fenrir ignore it or multiple screens seperated by '','' with: suspendingScreen= Values: Depends on driver: * VCSA: the number of the TTY. TTY6 is ''6''. Example ignore TTY1 and TTY2: suspendingScreen=1,2 There is also the ability to let Fenrir auto detect screens that are running an X server. So Screens running an GUI can be ignored. autodetectSuspendingScreen=True Values: on=''True'', off=''False'' ### Keyboard The settings for keyboard and input related configuration is located in the section ''[keyboard]'' of the ''settings.conf'' file. Select the driver used for grabbing keybord input and for recieving shortcuts. driver=evdevDriver Values: Text, available Driver Available Drivers: * ''evdevDriver'' uses the evdev input system of linux, for Fenrir <1.5 just use ''evdev'' You can let Fenrir know about what input devices are to be used. device=ALL Values: * ''ALL'' use all devices with key capabilities. * ''NOMICE'' Exclude mices from handling. * `` just use the device with the given name. Gives Fenrir exclusive access to the keyboard and lets it control keystrokes. This is needed to intercept Fenrir related shortcuts. grabDevices=True Values: on=''True'', off=''False'' The following makes sense if you are using a second screenreader and want to have some hooked events. Fenrir ignores all shortcuts then. ignoreShortcuts=False Values: on=''True'', off=''False'' The current keyboard layout used for shortcuts. keyboardLayout=desktop Values: An absolute Path to a Keyboard definition file or a Filename without extension located in ''/etc/fenrir/keyboard'' Announce characters while typing. charEcho=False Values: on=''True'', off=''False'' Announce deleted characters charDeleteEcho=True Values: on=''True'', off=''False'' Announce word after pressing space wordEcho=False Values: on=''True'', off=''False'' Interrupt speech on any keypress interruptOnKeyPress=False Values: on=''True'', off=''False'' You can filter the keys that speech should interrupt interruptOnKeyPressFilter= Values: (List) empty = all keys, otherwise interrupt with specified keys The timeout that is used for double tap shortcuts doubleTapTimeout=0.2 Values: Seconds ### General Overall settings can be configured from the section ''[general]''. Set the current debug level: debugLevel=1 Values: off=0, error=1, warning=2, info=3 the current punctuation and dict file in use: punctuationProfile=default Values: Text, see available profiles in ''/etc/fenrir/punctuation'' or in ''sourceTree/config/punctuation'' The current punctuation level in use: punctuationLevel=some Values: Text, See available levels in the used punctuation file. Respect pause for punctuations: respectPunctuationPause=True Values: on=''True'', off=''False'' Add a pause on Line break: newLinePause=True Values: on=''True'', off=''False'' Specify the path where the clipboard should be exported to. See [export clipboard to file](#export clipboard to file). The variable ''$user'' is replaced by the current logged username. clipboardExportPath=/tmp/fenrirClipboard Values: Text, Systemfilepath The number of available clipboards: numberOfClipboards=10 Values: Integer, 1 - 999 Replace emoticons like :) or ;) with text insertions: emoticons=True Values: on=''True'', off=''False'' Define the current Fenrir keys: fenrirKeys=KEY_KP0,KEY_META,KEY_INSERT Values, Text list, separated by comma. Define the current script keys: scriptKey=KEY_COMPOSE Values, Text list, separated by comma. The time format to be used for (time command) output: timeFormat=%H:%M:%P Values: see python specification for [datetime.strftime](https///docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior) The date format to be used for (date command) output: dateFormat=%A, %B %d, %Y Values: see python specification for [datetime.strftime](https///docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior) Enable or Disable spellcheck whilst typing: autoSpellCheck=True Values: on=''True'', off=''False'' The use of the dictionary with spellcheck: spellCheckLanguage=en_US Values: Text, see aspell dictionary's. Folder Path for your scripts "scriptKey" functionality: scriptPath=/usr/share/fenrir/scripts Values: Text, Existing path on file system. Override commands or create new ones without changing the Fenrir defaults: commandPath=/usr/share/fenrir/commands Values: Text, Existing path on file system. Subfolders in commandPath are: * ''commands'' = to create shortcut commands * ''onInput'' = executed while typing * ''onScreenChange'' = executed on change the screen (change from TTY4 to TTY6) * ''onScreenUpdate'' = executed when the screen is captured ### Focus The configuration for basic focus is in the section ''[focus]''. Follow the text cursor: cursor=True Values: on=''True'', off=''False'' Follow highlighted text changes (Highlight Tracking): highlight=False Values: on=''True'', off=''False'' ### Review Configurations for the review mode are in the section ''[review]''. If "next word/ char" or "prev word/char" create a linebreak, announce it: lineBreak=True Values: on=''True'', off=''False'' If "next word/ char" or "prev word/char" cannot be performed because you reached the end of the screen, announce it: endOfScreen=True Values: on=''True'', off=''False'' Leave the review mode when pressing a key: leaveReviewOnKeypress=False Values: on=''True'', off=''False'' Leave the review mode when changing the screen (From TTY3 to TTY4): leaveReviewOnScreenChange=True Values: on=''True'', off=''False'' ### Promote "Promoted Lists" are configured in the section ''[promote]''. Turn Promoted Lists" on or off: enabled=True Values: on=''True'', off=''False'' The minimum time interval of inactivity to activate promoting. By default it promotes after 120 Seconds inactivity: inactiveTimeoutSec=120 Values: in Seconds Define a list of promoted words comma seperated: list= Values: text (comma seperated) Example to promote the word "nickname" or a bash prompt: list=nickname,$:,#: ### Time The automated time announcement is configured in the section ''[time]''. Time announcement is disabled by default. Turn time announcement on or off: enabled=True Values: on=''True'', off=''False'' Should the time be announced: presentTime=True Values: on=''True'', off=''False'' Should the date be announced (just on date change): presentDate=True Values: on=''True'', off=''False'' Announce after a given period of seconds: delaySec=0 Value: in Seconds, 0 = Deactivated Announce after fixed minutes in an hour. if delaySec is >0 onMinutes is ignored: onMinutes=00,30 Example every 15 minutes: onMinutes=00,15,30,45 Just play a soundicon, (not interrupting): announce=True Values: on=''True'', off=''False'' Interrupt current speech for time announcement: interrupt=False Values: on=''True'', off=''False'' # Customization ## Scripting Scripts can be in any language, bash, python, sh or others. Place your scripts in the directory /usr/share/fenrir/scripts/ (the path is configurable in settings.conf). The script key is the applications key. Usually this key can be found on the keyboard located just left of the right most control key. When you name a script, the key name appears in the script seperated by the sequence __-__. So, for example, if you have a python weather script you want assigned to the script key plus the letter w you would name the script /usr/share/fenrir/scripts/weather__-__key_w.py Then, to access the script, simply press the script key and the letter w. Scripts must be executable. So, make sure to chmod 755 your script when you place it in the scripts directory. The script gets some parameters from fenrir when it is executed. So that information is available in your script then. ### Parameterlist | Parameter | Content | | --------- | ------- | | $1 | Username of the current logged in user | ### Examples Script that just speaks the current username when pressing ScriptKey + H.\\ File: ''/usr/share/fenrir/scripts/helloWorld__-__key_h.sh'': #!/bin/bash echo $1 ## Commands You can place your own commands in "/usr/share/fenrir/commands" (path is configurable in settings.conf). Commands are python files with a special scheme. You can assign them to a shortcut using the filename without an extension or place them in a hook trigger like OnInput or OnScreenChange. For further information see developer guide. Good Examples: ["date.py"](https///github.com/chrys87/fenrir/blob/master/src/fenrir/commands/commands/date.py) (announce the Date), ["shut_up.py"](https///github.com/chrys87/fenrir/blob/master/src/fenrir/commands/commands/shut_up.py) (interrupt output) the basic scheme for a command is as follows: from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('No description found') def run(self): pass def setCallback(self, callback): pass * [Template lives here](https///github.com/chrys87/fenrir/blob/master/src/fenrir/commands/command_template.py) * The class needs to have the name "command". * "initialize" is running once whilst loading the command. * "shutdown" is running on unload like the command (quit fenrir) * "getDescriptsion" just returns an string. That String is used in Tutorial Mode. * "run" is executed when the command is invoked. (shortcut is pressed, or trigger isn't running) * setCAllback is currently not used. and has no functionality yet. # Troubleshooting ## Fenrir does not start 1. Have you installed all the dependencies [Support and Requirements](#Support and Requirements) 2. Try using master, a lot of changes take place there to make Fenrir compatible with more systems ## Fenrir does not utilize the shortcuts 1. Make sure you have python3-evdev installed 2. Use the latest Fenrir version 3. Make sure that Fenrir has permission to /dev/input/* and /dev/uinput (or run it as root) ## No sound at all 1. Run the script to configure Pulseaudio once as root and once as your user. This will setup Pulseaudio but require a restart of Pulseaudio. The script is located in ''tools/configure_pulse.sh'' 2. Use ALSA 3. [Configure Pulse system wide](https///www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/SystemWide/) (Not recommended) 4. Use gstreamerDriver: change ''settings.conf'' in the section ''sound'' the line ''driver=genericDriver'' to ''driver=gstreamerDriver'' 5. Use wave sound-icons: change ''settings.conf'' in the section ''sound'' the line ''theme=default'' to ''theme=default-wav'' 6. Use most current version of [sox](http://sox.sourceforge.net/) with opus support 7. Try [apulse](https///github.com/i-rinat/apulse) (not tested by myself but might work). Please give me feedback if you try it out. ## You get sound-icons but no speech 1. If you are using speech-dispatcher run "spd-conf" once as user and as root. 2. You can test if speech-dispatcher works by invoking it as root\\ ''sudo spd-say "hello world"'' ## Bugreports and feature requests Please report Bugs and feature requests to: [https://github.com/chrys87/fenrir/issues](https///github.com/chrys87/fenrir/issues) for bugs please provide a [debug](#Howto create a debug file) file that shows the issue. ### How-to create a debug file 1. Delete old debug stuff\\ ''sudo rm /var/log/fenrir.log'' 2. Start fenrir in debug mode\\ ''sudo fenrir -d'' 3. Do your stuff to reproduce the problem 4. Stop fenrir (''fenrirKey + q'') the debug file is located in ''/var/log/fenrir.log'' Please be as precise as possible to make it easy to solve the problem. fenrir-1.5.1/docu/user.txt000066400000000000000000001672511317357605400155030ustar00rootroot00000000000000====== Fenrir User Manual ====== Fenrir is a modern command line screen reader written in Python3. It has a modular structure, a flexible based driver model, is highly configurable and easy to customize and extend ([[fenrir_development_manual|see Developer Manual]]). Please see the following pages for the [[fenrir_current_version|current]] and [[fenrir_git_version|Git]] version of Fenrir. ====== Support and Requirements ====== Fenrir requires several drivers to interact with the operating system. ===== Speech Drivers ===== A speech driver is for communication with the text to speech system like [[#SpeechDispatcher|Speech-Dispatcher]] or [[http://espeak.sourceforge.net|Espeak]]. \\ See section [[#Speech|Speech]] in ''settings.conf'' for more information. ==== SpeechDispatcher ==== This driver is used by default. It uses Speech-dispatcher as its backend. Dependencies: * Speech-dispatcher (installed and configured, [[https://devel.freebsoft.org/speechd#sec2|Documentation]]) * Python-speechd ==== Espeak ==== Uses Espeak via Python bindings. Dependencies: * Espeak or Espeak-ng * [[https://launchpad.net/python-espeak|python-espeak]] ==== Generic ==== This invokes speech via a sub-process. This is almost the same as using the commandline. The performance depends on the overhead of the speech synthesis application but it is really flexible. Dependencies: * Espeak or Espeak-ng The Requirements are flexible, they depend on the configuration in settings.conf. ==== Dummy ==== this is just for debugging, logs are output to the screen and logged as well. ===== Sound Drivers ===== To play sound icons and similar.\\ See section [[#Sound|Sound]] in ''settings.conf'' for more information. ==== Generic ==== This driver is used by default. Dependencies: * [[http://sox.sourceforge.net/|Sox]] with opus support The Requirements are flexible, they depend on the configuration in settings.conf. ==== Gstreamer ==== if you prefer to use Gstreamer for sound output. Dependencies: * Gstreamer >= 1.x * Glibc ==== Dummy ==== this is just for debugging, logs are output to the screen and logged as well. ===== Input Drivers ===== Input drivers are to capture keyboard shortcuts issued to the screen reader \ See section [[#Keyboard|Keyboard]] in ''settings.conf'' for more information. ==== Evdev ==== This driver is used by default. Evdev is the low level input device framework for Linux. Dependencies: * python-evdev >=0.6.3 * pyudev * loaded uinput kernel module * exclusive access to the input devices Read permission to the following files and services: * /dev/input * /dev/uinput ===== Screen Drivers ===== The job of a screen driver is to get the information of current screen content.\\ See section [[#Screen|Screen]] in ''settings.conf'' for more information. ==== VCSA ==== This driver is used by default. For Linux VCSA devices. These exist on any current standard installation of Linux. Dependencie s: * python-dbus Read permission to the following files and services (or run as root): * /sys/devices/virtual/tty/tty0/active * /dev/tty[1 - 64] * /dev/vcsa[1 - 64] ([[https://linux.die.net/man/4/vcsa|VCSA manpage]]) * read Logind DBUS ===== Braille Drivers ===== This is for Braille support. Braille is currently a work in progress and is planned for the Fenrir 2.0 release.\\ See section [[#Braille|Braille]] in ''settings.conf'' for more information. ==== BRLTTY ==== This driver is used by default. It uses [[brltty|BrlTTY]] to communicate with with a Braille device. Dependencies: * BrlTTY (configured and running, [[http://mielke.cc/brltty/doc/Manual-BRLTTY/English/BRLTTY.html|Documentation]]) * python-brlapi (configured, [[http://mielke.cc/brltty/doc/Manual-BrlAPI/English/BrlAPI.html|Documentation]]) ===== Currently supported platforms ===== Currently Fenrir completely supports the following Platforms: * Linux TTY Support for further Systems are planned. ====== Installation ====== Fenrir can run without installation. It just requires the dependencies are installed first. We recommend to try it out before installation to be sure everything works and prevent yourself from experiencing a non-talking environment. ===== Try Out ===== Fenrir does not require installation. You can try it and make sure everything works before you decide to install. In this way you can be sure that your system doesnt break or stop talking. for that you can just grab the code and run as root ''src/fenrir/fenrir'' (in foreground) or ''src/fenrir/fenrir-daemon'' (in background, used by systemd for autostart) ===== Install it ===== ==== Documented operating systems ==== ==== Arch Linux ==== For Arch there are PKGBUILDs in the AUR: * [[https://aur.archlinux.org/packages/fenrir/|fenrir]] * [[https://aur.archlinux.org/packages/fenrir-git/|fenrir-git]] ==== Manual ==== - Download the latest stable version from the [[https://linux-a11y.org/index.php?page=fenrir-screenreader|Fenrir-Project]] site. - Unpack the archive - Check the needed Dependencys by running [[https://github.com/chrys87/fenrir/blob/master/check-dependencies.py|check-dependencys.py]] script - install the missing dependencies an standard installation requires the following: * python3 >= 3.3 (and all the following is needed for python3 ) * python3-speechd (screen) * python3-dbus (screen) * python3-evdev >= 0.6.4(input) * python3-daemonize (background service) * python3-brlapi (braille) * python3-pyenchant (spellchecker) * your language for aspell (aspell-) (spellchecker) * sox (sound) * For an individual installation see [[#Support and Requirements|Support and Requirements]] or consult the [[https://github.com/chrys87/fenrir/blob/master/README.md|Readme]]) - run "install.sh" as root this installs Fenrir as the following * Application:''/opt/fenrir'' * Settings:''/etc/fenrir'' * Sound Icons:''/usr/share/fenrir/'' to remove Fenrir just run uninstall.sh as root ==== Git ==== if you want to get the latest code you can use git to get a development snapshot: git clone https://github.com/chrys87/fenrir.git ===== Auto Start ===== To start Fenrir once: systemctl start fenrir To enable auto start on system boot: systemctl enable fenrir ====== First Steps ====== If you are using Fenrir for the first time you may want to take a look at these resources: * [[#Keybindings|Keybindings]] * [[#Tutorial Mode|Tutorial Mode]] ====== Features ====== ===== Commands ===== ==== Keybindings ==== Normal commands can be invoked in two ways: - Using a Metakey ([[#Fenrir Key|FenrirKey]]) - Shortcuts with a single key See section [[#Keyboard|Keyboard]] in ''settings.conf'' for more information. === Fenrir Key === The Fenrir Key is for invoking screen reader commands. Fenrir can utilize more than one FenrirKey at the same time. By default the following keys are used: - Insert - KeyPad Insert - Meta (Super, Windows) === Script Key === To invoke "Scripts" the Script Key is mandatory. The shortcut is encoded in the filename of the script. See [[#Scripting|Scripting]] === Desktop Layout === ^Shortcut ^Command ^ |FenrirKey + H|[[#Tutorial Mode|toggle tutorial mode]]| |CTRL|[[#shut up|shut up (interrupts speech)]]| |FenrirKey + KeyPad 9|[[#review bottom|reviews bottom]]| |FenrirKey + KeyPad 7|[[#review top|reviews top]]| |KeyPad 8|[[#review current line|reviews current line]]| |KeyPad 7|[[#review previous line|reviews previous line]]| |KeyPad 9|[[#review next line|reviews next line]]| |FenrirKey + KeyPad 4|[[#review line beginning|reviews line beginning]]| |FenrirKey + KeyPad 6|[[#review line ending|reviews line ending]]| |FenrirKey + KeyPad 1|[[#review line first character|reviews line first character]]| |FenrirKey + KeyPad 3|[[#review line last character|reviews line last character]]| |FenrirKey + Alt + 1|[[#present first line|presents first line]]| |FenrirKey + Alt + 2|[[#present last line|presents last line]]| |KeyPad 5|[[#review current word|reviews current word]]| |KeyPad 4|[[#review previous word|reviews previous word]]| |KeyPad 6|[[#review next word|reviews next word]]| |FenrirKey + Shift + KeyPad 5|[[#review current word phonetic|reviews current word phonetic]]| |FenrirKey + Shift + KeyPad 4|[[#review previous word phonetic|reviews previous word phonetic]]| |FenrirKey + Shift + KeyPad 6|[[#review next word phonetic|reviews next word phonetic]]| |KeyPad 2|[[#review current character|reviews current char]]| |KeyPad 1|[[#review previous character|reviews previous char]]| |KeyPad 3|[[#review next character|reviews next char]]| |FenrirKey + Shift + KeyPad 2|[[#review current character phonetic|reviews current character phonetic]]| |FenrirKey + Shift + KeyPad 1|[[#review previous character phonetic|reviews previous character phonetic]]| |FenrirKey + Shift + KeyPad 3|[[#review next character phonetic|reviews next character phonetic]]| |FenrirKey + CTRL + KeyPad 8|[[#review up|reviews up]]| |FenrirKey + CTRL + KeyPad 2|[[#review down|reviews down]]| |FenrirKey + KeyPad dot|[[#exit review|exit review]]| |KeyPad dot|[[#cursor position|cursor position]]| |FenrirKey + I|[[#indent current line|indent curr line]]| |FenrirKey + KeyPad 5|[[#current screen|current screen]]| |FenrirKey + KeyPad 8|[[#current screen before cursor|current screen before cursor]]| |FenrirKey + KeyPad 2|[[#current screen after cursor|current screen after cursor]]| ||[[#cursor read to end of line|cursor read to end of line]]| ||[[#cursor column|cursor column]]| ||[[#cursor line number|cursor line number]]| ||[[#braille flush|Braille flush]]| ||[[#braille pan left|Braille pan left]]| ||[[#braille pan right|Braille pan right]]| ||[[#braille return to cursor|Braille return to cursor]]| |FenrirKey + CTRL + 1|[[#clear Bookmark X|clear bookmark 1]]| |FenrirKey + Shift + 1|[[#set Bookmark X|set bookmark 1]]| |FenrirKey + 1|[[#read Bookmark X|bookmark 1]]| |FenrirKey + CTRL + 2|[[#clear Bookmark X|clear bookmark 2]]| |FenrirKey + Shift + 2|[[#set Bookmark X|set bookmark 2]]| |FenrirKey + 2|[[#read Bookmark X|bookmark 2]]| |FenrirKey + CTRL + 3|[[#clear Bookmark X|clear bookmark 3]]| |FenrirKey + Shift + 3|[[#set Bookmark X|set bookmark 3]]| |FenrirKey + 3|[[#read Bookmark X|bookmark 3]]| |FenrirKey + CTRL + 4|[[#clear Bookmark X|clear bookmark 4]]| |FenrirKey + Shift + 4|[[#set Bookmark X|set bookmark 4]]| |FenrirKey + 4|[[#read Bookmark X|bookmark 4]]| |FenrirKey + CTRL + 5|[[#clear Bookmark X|clear bookmark 5]]| |FenrirKey + Shift + 5|[[#set Bookmark X|set bookmark 5]]| |FenrirKey + 5|[[#read Bookmark X|bookmark 5]]| |FenrirKey + CTRL + 6|[[#clear Bookmark X|clear bookmark 6]]| |FenrirKey + Shift + 6|[[#set Bookmark X|set bookmark 6]]| |FenrirKey + 6|[[#read Bookmark X|bookmark 6]]| |FenrirKey + CTRL + 7|[[#clear Bookmark X|clear bookmark 7]]| |FenrirKey + Shift + 7|[[#set Bookmark X|set bookmark 7]]| |FenrirKey + 7|[[#read Bookmark X|bookmark 7]]| |FenrirKey + CTRL + 8|[[#clear Bookmark X|clear bookmark 8]]| |FenrirKey + Shift + 8|[[#set Bookmark X|set bookmark 8]]| |FenrirKey + 8|[[#read Bookmark X|bookmark 8]]| |FenrirKey + CTRL + 9|[[#clear Bookmark X|clear bookmark 9]]| |FenrirKey + Shift + 9|[[#set Bookmark X|set bookmark 9]]| |FenrirKey + 9|[[#read Bookmark X|bookmark 9]]| |FenrirKey + CTRL + 0|[[#clear Bookmark X|clear bookmark 10]]| |FenrirKey + Shift + 0|[[#set Bookmark X|set bookmark 10]]| |FenrirKey + 0|[[#read Bookmark X|bookmark 10]]| |FenrirKey + KeyPad Slash|[[#Create Window|set window application]]| |2 * FenrirKey + KeyPad Slash|[[#Remove Window|clear window application]]| |KeyPad Plus|[[#last incoming|read last incoming]]| |FenrirKey + F2|[[#toggle braille|toggles braille]]| |FenrirKey + F3|[[#toggle sound|toggles sound]]| |FenrirKey + F4|[[#toggle speech|toggles speech]]| |KeyPad Enter|[[#disable speech temporarily|temporarily disables speech]]| |FenrirKey + CTRL + P|[[#toggle punctuation level|toggles punctuation level]]| |FenrirKey + RightBrace|[[#toggle auto spell check|toggle auto spell check]]| |FenrirKey + Backslash|[[#toggle output|toggles output]]| |FenrirKey + CTRL + E|[[#toggle emoticons|toggles emoticons]]| |FenrirKey + KeyPad Enter|[[#toggle auto read|toggles auto read]]| |FenrirKey + CTRL + T|[[#toggle auto time|toggles auto time]]| |FenrirKey + KeyPad ASTERISK|[[#toggle highlight tracking|toggles highlight tracking]]| |FenrirKey + Q|[[#quit Fenrir|quits fenrir]]| |FenrirKey + T|[[#Time|Announce time]]| |2 * FenrirKey + T|[[#Date|Announce date]]| |FenrirKey + S|[[#spell check|spell check]]| |2 * FenrirKey + S|[[#add word to spell check|add word to spell check]]| |FenrirKey + Shift + S|[[#removes word from spell check|removes word from spell check]]| |FenrirKey + Backspace|[[#forward keypress|forward keypress]]| |FenrirKey + Up|[[#increase speech volume|increase speech volume]]| |FenrirKey + Down|[[#decrease speech volume|decrease speech volume]]| |FenrirKey + Right|[[#increase speech rate|increase speech rate]]| |FenrirKey + Left|[[#decrease speech rate|decrease speech rate]]| |FenrirKey + Alt + Right|[[#increase speech pitch|increase speech pitch]]| |FenrirKey + Alt + Left|[[#decrease speech pitch|decrease speech pitch]]| |FenrirKey + Alt + Up|[[#increase sound volume|increase sound volume]]| |FenrirKey + Alt + Down|[[#decrease sound volume|decrease sound volume]]| |FenrirKey + CTRL + Shift + C|[[#clear clipboard|clears clipboard]]| |FenrirKey + Home|[[#first clipboard|first clipboard]]| |FenrirKey + End|[[#last clipboard|last clipboard]]| |FenrirKey + PageUp|[[#previous clipboard|previous clipboard]]| |FenrirKey + PageDown|[[#next clipboard|next clipboard]]| |FenrirKey + Shift + C|[[#read current clipboard|current clipboard]]| |FenrirKey + C|[[#copy marked to clipboard|copy marked text to clipboard]]| |FenrirKey + V|[[#paste clipboard|paste clipboard contents]]| |FenrirKey + P|[[#import clipboard from file|import clipboard from file]]| |FenrirKey + Alt + Shift +C|[[#export clipboard to file|export clipboard to file]]| |FenrirKey + CTRL + Shift + X|[[#Remove Marks|remove marks]]| |FenrirKey + X|[[#Set mark|set mark]]| |FenrirKey + Shift + X|[[#Get text between marks|announce marked text]]| ^Linux specific ^ ||export clipboard to X| |FenrirKey + CTRL + Up|include Alsa volume| |FenrirKey + CTRL + Down|decrease Alsa volume| === Laptop Layout === ^Shortcut ^Command ^ |FenrirKey + H|[[#Tutorial Mode|toggle tutorial mode]]| |CTRL|[[#shut up|shut up (interrupts speech)]]| |FenrirKey + Shift + O|[[#review bottom|reviews bottom]]| |FenrirKey + Shift + U|[[#review top|reviews top]]| |FenrirKey + I|[[#review current line|reviews current line]]| |FenrirKey + U|[[#review previous line|reviews previous line]]| |FenrirKey + O|[[#review next line|reviews next line]]| |FenrirKey + Shift + J|[[#review line beginning|reviews line beginning]]| |FenrirKey + Shift + L|[[#review line ending|reviews line ending]]| |FenrirKey + CTRL + J|[[#review line first character|reviews line first character]]| |FenrirKey + CTRL + L|[[#review line last character|reviews line last character]]| |FenrirKey + Alt + 1|[[#present first line|presents first line]]| |FenrirKey + Alt + 2|[[#present last line|presents last line]]| |FenrirKey + K|[[#review current word|reviews current word]]| |FenrirKey + J|[[#review previous word|reviews previous word]]| |FenrirKey + L|[[#review next word|reviews next word]]| |FenrirKey + CTRL + ALT + K|[[#review current word phonetic|reviews current word phonetic]]| |FenrirKey + CTRL + ALT + J|[[#review previous word phonetic|reviews previous word phonetic]]| |FenrirKey + CTRL + ALT + L|[[#review next word phonetic|reviews next word phonetic]]| |FenrirKey + comma|[[#review current character|reviews current character]]| |FenrirKey + M|[[#review previous character|reviews previous character]]| |FenrirKey + dot|[[#review next character|reviews next character]]| |FenrirKey + CTRL + ALT + comma|[[#review current character phonetic|reviews current character phonetic]]| |FenrirKey + CTRL + ALT + M|[[#review previous character phonetic|reviews previous character phonetic]]| |FenrirKey + CTRL + ALT + dot|[[#review next character phonetic|reviews next character phonetic]]| |FenrirKey + CTRL + I|[[#review up|reviews up]]| |FenrirKey + CTRL + comma|[[#review down|reviews down]]| |FenrirKey + Slash|[[#exit review|exit review]]| |FenrirKey + Shift + dot|[[#cursor position|cursor position]]| |2 * FenrirKey + I|[[#indent current line|indent curr line]]| |FenrirKey + Shift + K|[[#current screen|current screen]]| |FenrirKey + Shift + I|[[#current screen before cursor|current screen before cursor]]| |FenrirKey + Shift + comma|[[#current screen after cursor|current screen after cursor]]| ||[[#cursor read to end of line|cursor read to end of line]]| ||[[#cursor column|cursor column]]| ||[[#cursor line number|cursor line number]]| ||[[#braille flush|Braille flush]]| ||[[#braille pan left|Braille pan left]]| ||[[#braille pan right|Braille pan right]]| ||[[#braille return to cursor|Braille return to cursor]]| |FenrirKey + CTRL + 1|[[#clear Bookmark X|clear bookmark 1]]| |FenrirKey + Shift + 1|[[#set Bookmark X|set bookmark 1]]| |FenrirKey + 1|[[#read Bookmark X|bookmark 1]]| |FenrirKey + CTRL + 2|[[#clear Bookmark X|clear bookmark 2]]| |FenrirKey + Shift + 2|[[#set Bookmark X|set bookmark 2]]| |FenrirKey + 2|[[#read Bookmark X|bookmark 2]]| |FenrirKey + CTRL + 3|[[#clear Bookmark X|clear bookmark 3]]| |FenrirKey + Shift + 3|[[#set Bookmark X|set bookmark 3]]| |FenrirKey + 3|[[#read Bookmark X|bookmark 3]]| |FenrirKey + CTRL + 4|[[#clear Bookmark X|clear bookmark 4]]| |FenrirKey + Shift + 4|[[#set Bookmark X|set bookmark 4]]| |FenrirKey + 4|[[#read Bookmark X|bookmark 4]]| |FenrirKey + CTRL + 5|[[#clear Bookmark X|clear bookmark 5]]| |FenrirKey + Shift + 5|[[#set Bookmark X|set bookmark 5]]| |FenrirKey + 5|[[#read Bookmark X|bookmark 5]]| |FenrirKey + CTRL + 6|[[#clear Bookmark X|clear bookmark 6]]| |FenrirKey + Shift + 6|[[#set Bookmark X|set bookmark 6]]| |FenrirKey + 6|[[#read Bookmark X|bookmark 6]]| |FenrirKey + CTRL + 7|[[#clear Bookmark X|clear bookmark 7]]| |FenrirKey + Shift + 7|[[#set Bookmark X|set bookmark 7]]| |FenrirKey + 7|[[#read Bookmark X|bookmark 7]]| |FenrirKey + CTRL + 8|[[#clear Bookmark X|clear bookmark 8]]| |FenrirKey + Shift + 8|[[#set Bookmark X|set bookmark 8]]| |FenrirKey + 8|[[#read Bookmark X|bookmark 8]]| |FenrirKey + CTRL + 9|[[#clear Bookmark X|clear bookmark 9]]| |FenrirKey + Shift + 9|[[#set Bookmark X|set bookmark 9]]| |FenrirKey + 9|[[#read Bookmark X|bookmark 9]]| |FenrirKey + CTRL + 0|[[#clear Bookmark X|clear bookmark 10]]| |FenrirKey + Shift + 0|[[#set Bookmark X|set bookmark 10]]| |FenrirKey + 0|[[#read Bookmark X|bookmark 10]]| |FenrirKey + CTRL + 8|[[#Create Window|set window application]]| |2 * FenrirKey + CTRL + 8|[[#Remove Window|clear window application]]| |FenrirKey + Semicolon|[[#last incoming|read last incoming]]| |FenrirKey + F2|[[#toggle braille|toggles braille]]| |FenrirKey + F3|[[#toggle sound|toggles sound]]| |FenrirKey + F4|[[#toggle speech|toggles speech]]| |FenrirKey + Enter|[[#disable speech temporarily|temporarily disables speech]]| |FenrirKey + Shift + CTRL + P|[[#toggle punctuation level|toggles punctuation level]]| |FenrirKey + RightBrace|[[#toggle auto spell check|toggle auto spell check]]| |FenrirKey + Shift + Enter|[[#toggle output|toggles output]]| |FenrirKey + Shift + E|[[#toggle emoticons|toggles emoticons]]| |FenrirKey + Enter|[[#toggle auto read|toggles auto read]]| |FenrirKey + CTRL + T|[[#toggle auto time|toggles auto time]]| |FenrirKey + Y|[[#toggle highlight tracking|toggles highlight tracking]]| |FenrirKey + Q|[[#quit Fenrir|quits fenrir]]| |FenrirKey + T|[[#Time|Announce time]]| |2 * FenrirKey + T|[[#Date|Announce date]]| |FenrirKey + S|[[#spell check|spell check]]| |2 * FenrirKey + S|[[#add word to spell check|add word to spell check]]| |FenrirKey + Shift + S|[[#removes word from spell check|removes word from spell check]]| |FenrirKey + Backspace|[[#forward keypress|forward keypress]]| |FenrirKey + Up|[[#increase speech volume|increase speech volume]]| |FenrirKey + Down|[[#decrease speech volume|decrease speech volume]]| |FenrirKey + Right|[[#increase speech rate|increase speech rate]]| |FenrirKey + Left|[[#decrease speech rate|decrease speech rate]]| |FenrirKey + Alt + Right|[[#increase speech pitch|increase speech pitch]]| |FenrirKey + Alt + Left|[[#decrease speech pitch|decrease speech pitch]]| |FenrirKey + Alt + Up|[[#increase sound volume|increase sound volume]]| |FenrirKey + Alt + Down|[[#decrease sound volume|decrease sound volume]]| |FenrirKey + CTRL + Shift + C|[[#clear clipboard|clears clipboard]]| |FenrirKey + Home|[[#first clipboard|first clipboard]]| |FenrirKey + End|[[#last clipboard|last clipboard]]| |FenrirKey + PageUp|[[#previous clipboard|previous clipboard]]| |FenrirKey + PageDown|[[#next clipboard|next clipboard]]| |FenrirKey + Shift + C|[[#read current clipboard|current clipboard]]| |FenrirKey + C|[[#copy marked to clipboard|copy marked text to clipboard]]| |FenrirKey + V|[[#paste clipboard|paste clipboard contents]]| |FenrirKey + F5|[[#import clipboard from file|import clipboard from file]]| |FenrirKey + Alt + Shift +C|[[#export clipboard to file|export clipboard to file]]| |FenrirKey + CTRL + Shift + X|[[#Remove Marks|remove marks]]| |FenrirKey + X|[[#Set mark|set mark]]| |FenrirKey + Shift + X|[[#Get text between marks|announce marked text]]| ^Linux specific ^ ||export clipboard to X| |FenrirKey + CTRL + Up|increases Alsa volume| |FenrirKey + CTRL + Down|decreases Alsa volume| ==== General ==== === quit Fenrir === Just stops fenrir. === shut up === Interrupt the current spoken. ==== Review Modes ==== Fenrir provides a virtual cursor, with it you can navigate all over the screen without changing the text cursor. Using the review feature will open the review mode automatically. The review cursor always starts from the text cursor. Attention: after using the review mode, the review cursor will stay open until you use the ''exit review'' shortcut. Think when using clipboard operations and similar. The review cursor is always prefered over the text cursor. Fenrir sounds a bell sound if the used review command jumps to another line or end of screen. === exit review === You can leave the review mode by pressing the ''exit review'' shortcut. === review bottom === Set the review cursor to first column in the last line. === review top === Set the review cursor to the first column in the first line === review current line === Set the review cursor to the beginn of the the current line and review it. === review previous line === Set the review cursor to the previous line and review it. === review next line === Set the review cursor to the next line and review it. === review line beginning === Set the review cursor to the begin of the current line === review line ending === Set the review cursor to the end of the current line === review line first character === Set the review cursor the first char (that is not space) in the current line and review it. === review line last character === Set the review cursor the last char (that is not space) in the current line and review it. === review current word === Sets the review cursor to the beginning of the current word and review it. === review previous word === Sets the review cursor to the beginning of the previous word and review it. === review next word === Sets the review cursor to the beginning of the next word and review it. === review current word phonetic === Sets the review cursor to the beginning of the current word and spell it phonetic. === review previous word phonetic === Sets the review cursor to the beginning of the previous word and spell it phonetic. === review next word phonetic === Sets the review cursor to the beginning of the next word and spell it phonetic. === review current character === Does not change the review cursor. Just announce the current char. === review previous character === Sets review cursor to the previous column and review it === review next character === Sets review cursor to the next column and review it === review current character phonetic === Does not change the review cursor. Just announce the current char phonetic. === review previous character phonetic === Sets review cursor to the previous column and announce the char phonetic. === review next character phonetic === Sets review cursor to the next column and announce the char phonetic. === review up === Set the review cursor in the same column one line above the current one and review it. === review down === Set the review cursor in the same column one line below the current one and review it. ==== Handling marking ==== A mark defines a point of origin or end to prepare to copy or paste a block of text. \\ Examples where you need marks are: * copy to clipboard * set window application * set bookmark 1 - X === Set mark === How to set a mark: - navigate with review or textcursor to the position you want to set the mark. Attention: if a review cursor is set, that is the prefered. If you want to use text cursor, be sure that you are not in review mode. - press shortcut for ''set mark'' you can set two marks (begin and end). Some commands allow some simpler usecases just using the whole line if only one mark is set. you may want to try this out. === Get text between marks === To get the text that is currently between your marks press shortcut for ''marked text''.\\ === Remove Marks === You can remove all current marks by pressing the shortcut for ''remove marks''. Changing the screen also removes the marks. ==== Screen Interaction ==== Fenrir provides several methods to interact with the current screen. === forward keypress === This just forwards the next shortcut to the screen Fenrir shortcut or not. This is useful if the currently pressed shortcut is also in use by Fenrir. === Clipboard === Fenrir provides a clipboard with multible items represented by a list. You navigate throught the list and paste the selected clipboard. == copy marked to clipboard == To copy something to the clipboard you need to set one or two marks. if you set one mark, the text between the mark and your current cursor is copied to clipboard. Setting two marks just copies the text between the marks into the clipboard. If you copy something it is always placed as the first item on your clipboard. == clear clipboard == You can remove all items from the current clipboard by ''clear clipboard'' functionality. == first clipboard == This moves quick to the first item of the clipboard. == last clipboard == This moves quick to the last item of the clipboard. == previous clipboard == Go to previous item in the clipboard. == next clipboard == Go to next item on the clipboard. == read current clipboard == Read the content of the current item of the clipboard. == paste clipboard == Pass whatever item is currently selected by first, last, prev or next clipboard commands. if no special clipboard is selected the (last copied) is used. == export clipboard to file == This allows you to export the current clipboard to a configurable filepath. This is useful to share the clipboard with a graphical desktop. == import clipboard from file == Import a clipboard from a configurable file. This is useful to share the clipboard with a graphical desktop. ==== Quick Settings ==== Fenrir provides shortcuts to change settings temporarily and on the fly without the need to permanently change the ''settings.conf'' file. === toggle braille === Enables and disables Braille. This is not persistent stored in your ''settings.conf'' but during run time. === toggle sound === Enables and disables sound. This is not persistent stored in your ''settings.conf'' but during run time. === toggle speech === Enables and disables speech. This is not persistent stored in your ''settings.conf'' but during run time. === disable speech temporarily === Disables the speech until next key press. it might be useful if you want to listen to music or similar. As soon as a key is pressed it is going to be enabled again. === toggle punctuation level === Cycle between all available punctuation levels. This is not persistent stored in your ''settings.conf'' but during run time. === toggle auto spell check === Enables and disables automatic spellchecker (when typing). This is not persistent stored in your ''settings.conf'' but during run time. === toggle emoticons === Enables and disables emoticons. This is not persistent stored in your ''settings.conf'' but during runtime. === toggle output === Enables and disables all output at once (sound, Braille, speech). This is not persistent stored in your ''settings.conf'' but during run time. === toggle auto read === Enables and disables what is automatically spoken. This is not persistent stored in your ''settings.conf'' but during run time. === toggle auto time === Enables and disables auto time functionality. This is not persistent stored in your ''settings.conf'' but during run time. === toggle highlight tracking === Enables and disables highlight tracking. This is not persistent stored in your ''settings.conf'' but during run time. === increase speech volume === Increase the volume of the speech. This is not persistent stored in your ''settings.conf'' but during runtime. === decrease speech volume === Decrease the volume of the speech. This is not persistent stored in your ''settings.conf'' but during runtime. === increase speech rate === Increase the rate of the speech. This is not persistent stored in your ''settings.conf'' but during runtime. === decrease speech rate === Decrease the rate of the speech. This is not persistent stored in your ''settings.conf'' but during runtime. === increase speech pitch === Increase the pitch of the speech. This is not persistent stored in your ''settings.conf'' but during runtime. === decrease speech pitch === Decrease the pitch of the speech. This is not persistent stored in your ''settings.conf'' but during runtime. === increase sound volume === Increase the volume of the sound. This is not persistent stored in your ''settings.conf'' but during runtime. === decrease sound volume === Decrease the volume of the sound. This is not persistent stored in your ''settings.conf'' but during runtime. ==== Window Mode ==== Fenrir supports window mode, a window is a partial area of the screen. === Create Window === To create a window you need to do the following: - set a beginning mark (as the start of the window) - set an end mark (where the window should end) - press ''set window application'' shortcut. Now Fenrir ignores anything outside of the window.\\ === Remove Window === You can remove the window by pressing ''the clear window application'' shortcut. Now Fenrir will read everything on the screen again. ==== Tracking Modes ==== Different types of tracking are currently supported See section [[#Focus|Focus]] in ''settings.conf'' for more information. === Cursor Tracking === This follows the text cursor. This is the typical way an application works. This is used by: * almost any shell such as (Bash, Zsh, sh) * vim * nano * emacs * mutt * tintin++ === Highlight Tracking === In some applications there are no text cursors. In those applications cursor changes are represented by different colors or attributes (underlined or bold). This mode tracks and announces these changes for you. This is used by: * wifi-menu * dialog * alpine ==== Tutorial Mode ==== Fenrir provides a Tutorial mode. When you enter tutorial mode, screen reader commands are intercepted and explained instead of executing them. ''Arrow up'' and ''Arrow Down'' let you navigate through a list of all available commands with shortcuts and description. Pressing escape leaves the tutorial mode. ==== Information ==== === Time === Announces the current Time. === Date === Announces the current Date. === Bookmarks === Bookmarks provide quick access to part of the screen without the need to navigate to the area. By default Fenrir provides 10 bookmarks. Those can be set and accessed via shortcut. This is useful for status lines or other information where the position does not change. == set Bookmark X == You need to set the bookmark first. For that you have to set one or two lines for use. - Set marks (one or two) - press shortcut for ''set bookmark X''. X represents the number 1 - 10. == read Bookmark X == If a bookmark is set you can access the area just by pressing the ''bookmark X'' shortcut. X represents the number 1 - 10. Bookmarks are dynamic. That means the content changes with the screen. == clear Bookmark X == to remove a bookmark just press the ''clear bookmark X'' shortcut. X represents the number 1 - 10. Afterward the bookmark is no longer available. === cursor position === You can get information about the current cursor and its position by using the "cursor position" functionality. === indent current line === Announce the current indent level of the current line. It represents the number of trailing spaces of the line. === current screen === Reads all the current screen from the beginning to the end. === current screen before cursor === Reads current screen from the beginning of the screen to the current cursor position. === current screen after cursor === Read anything after current cursor position to the end. === cursor read to end of line === Read from the current cursor position to the end of the current line. === cursor column === Read the current X position of a cursor (column of the current line). === cursor line number === Read the current Y position of a cursor (line number). === present first line === Reads just the first line. this is maybe useful for status information. === present last line === Presets the last line. This is maybe useful for status information. === last incoming === Repeat the last automatically incoming text. ===== Input ===== ==== Echo ==== Fenrir provides different methods of echoing content: * Word: Will speak each word after you push space * Character: speak any letter you type on the screen * Delete Character: speaks the character prior to the cursor when you push backspace ==== Silence on Key press ==== ==== Spellchecker ==== Fenrir has a built-in spellchecker, it can invoke automatically while typing or be called by a shortcut. Commands to add or remove the current word to the dictionary are included. As using the spellchecker is enhanced usage. You will need dictionary aspell-. See section [[#General|General]] in ''settings.conf'' for more information. === spell check === Invokes the spellcheck on the word that contains the Review or text cursor. === add word to spell check === Adds the word under the Review or Text cursor to the dictionary. === removes word from spell check === Removes the word under the Review or Text cursor from the dictionary. ===== Announcements ===== ==== Emoticons ==== If you want to replace ":)" emoticons with "smile" in speech you can use this feature. It can be toggled on or off. You can define emoticons in a dictionary, please see Emoticon Dictionary. See section [[#General|General]] in ''settings.conf'' to see how to enable or disable this feature. ==== Time ==== Announce the time at periodical increments, To track the time easily. You can define 2 different ways of time announcements. - periodic - on fix minutes Example periodic, every 20 minutes "delaySec=20": [time] enabled=True presentTime=True presentDate=True delaySec=20 onMinutes= announce=True interrupt=False Example on fix minutes in an hour. example every quarter "delaySec=0" and "onMinutes=00,15,30,45": [time] enabled=True presentTime=True presentDate=True #delaySec is repected bevore onMinutes so it need to be set to 0 delaySec=0 onMinutes=00,15,30,45 announce=True interrupt=False ==== Promoted List ==== Promoted Lists are a nice feature if you are away from your computer or performing more longer tasks. you can define a list of words which you want to hear a sound icon for after a period of inactivity. Example if the word "Chrys" appears after 120 Seconds of inactivity: [promote] enabled=True inactiveTimeoutSec=120 list=Chrys See section [[#Promote|Promote]] in ''settings.conf'' for more information. ==== Punctuation ==== Fenrir handles punctuation levels and names for you with several provided dictionaries. See levelDict See punctuationDict ===== Braille ===== Fenrir provides Braille support in Version >= 2.0. See section [[#Braille|Braille]] in ''settings.conf'' for more information. ==== braille flush ==== If a message appears on the Braille device you can flush it to get back to the review- or system cursor ==== Braille pan left ==== If a line is longer than your Braille devices you can move the view (called panning) to the left. So you can read stuff without the need to move the review- or system cursor. ==== Braille pan right ==== If a line is longer than your Braille devices you can move the view (called panning) to the right. So you can read stuff without the need to move the review- or system cursor. ==== braille return to cursor ==== When you have finished reading the line on the Braille device using panning, the focus can be returned to the current used cursor by using "return to cursor" command. ===== Dictionary ===== You can make use of different kinds of built-in dictionary's. A dictionary has a name and list of keys and values separated by :===: Example: [customDict] Chrys:===:Chrys is cool lollipop:===:lolli that means that every instance "chrys" is displayed, speech will say Chrys is cool. "lollipop" is spoken as "lolli". Before making changes to a dictionary we recommend making a backup of your current dictionary in case future updates overwrite your local changes. ==== Punctuation ==== === Level === The punctuation level dict contains lists with "what punctuation is spoken in what level". the default one looks like this: [levelDict] none:===: some:===:.-$~+*-/\@ most:===:.,:-$~+*-/\@!#%^&*()[]}{<>; all:===:!"#$%& \'()*+,-./:;<=>?@[\\]^_`{|}~ the level "none" has no values. so it should not speak any punctuation (sadly this is not respected by every TTS system) if "some" is the current level the following are spoken: dot dash dollar tilde plus star slash backslash at. same for most and all, you can add new levels. if you cycle punctuation levels they are recognized. the default punctuation level is set in settings.conf. The default is "some". === Punctuation === The punctuation dictionary "[punctDict]" contains how the punctuation is spoken. Example: [punctDict] _:===:line speaks an _ as "line". [punctDict] _:===:underscore speaks an _ as underscore. for question mark an ? is appended to the word that the TTS system can announce the question correctly. ==== Custom ==== The dict "[customDict]" is just for your own use, it just replace the key with the value without any special functionality. This might be used to fix incorrectly spoken words, make words more common, shorter or just for fun. :) ==== Emoticons ==== The Emoticons dictionary "[emoticonDict]" by default contains some emoticons. it can replace ":)" with "smile" or "XD" with "loool" Making chat more colorful. A nice feature with this dictionary is that you can toggle the substitution on or off during run time or in settings.conf. This is useful because while doing programming or other serious work you want to hear colons and perryns not smiles. ====== Configuration ====== You can configure Fenrir in the following places (ordered by priority): - Commandline Parameters ''-o'' see [[#Set settings coption|Set settings coption]] - /etc/fenrir/settings/settings.conf see [[#Settings|Settigns]] - /config/settings/settings.conf see [[#Settings|Settigns]] - hard coded defaults ===== Commandline Arguments ===== ==== Set settings option ==== You can specify options that overwrite the setting.conf. This is done with ''-o '' parameter. The list of options have the following syntax fenrir -o "section#setting=value;section#setting=value" For example changing the sound driver to gstreamer and disabling Braille fenrir -o "sound#driver=gstreamerDriver;braille#enabled=False=False" or change the debug level to verbose fenrir -o "general#debugLevel=3" You can find the available sections and variables here [[#Settings]] See Syntax [[#settings.conf syntax]] ==== settings.conf syntax ==== the syntax of the [[#Settings|settings.conf]] is quite simple and similar to a "*.ini" file, there are 4 different elements. - Sections - Settings - Values - Comments A comment starts with a # and is ignored by Fenrir. # this is a comment To group settings we have sections. A section can look like this: [Section] A setting looks like this: settingName=Value Example: [sound] # Turn sound on or off: enabled=True # Select the driver used to play sounds, choices are genericDriver and gstreamerDriver. # Sox is default. driver=genericDriver ===== Settings ===== ==== Sound ==== The sound is configured in section ''[sound]''. Turn sound on or off: enabled=True Values: on=''True'', off=''False'' Select the driver used to play sounds. The genericDriver using Sox is the default. driver=genericDriver Available Drivers: * ''genericDriver'' using the generic driver, for Fenrir <1.5 just use ''generic'' * ''gstreamerDriver'' using the gstreamer, for Fenrir <1.5 just use ''gstreamer'' These are the pack of sounds used for sound icons. theme=default By default we ship two sound packs. - ''default'' opus encoded, for newer Sox versions - ''default-wav'' wav encoded, just for compatibility Sound packs are located at /usr/share/sounds/fenrir/ Sound volume controls how loud the sounds for your selected sound pack are. volume=1.0 Values: ''0.0'' is quietest, ''1.0'' is loudest. === Generic Driver === The generic sound driver uses shell commands for play sound and frequencies. ''genericPlayFileCommand'' defines the command that is used to play a sound file. genericPlayFileCommand= ''genericFrequencyCommand'' defines the command that is used playing frequencies. genericFrequencyCommand= The following variables are substituted in ''genericPlayFileCommand'' and ''genericFrequencyCommand'': * ''fenrirVolume'' = the current volume setting * ''fenrirSoundFile'' = the sound file for an sound icon * ''fenrirFrequence'' = the frequency to play * ''fenrirDuration'' = the duration of the frequency Example genericPlayFileCommand (default) genericPlayFileCommand=play -q -v fenrirVolume fenrirSoundFile Example genericFrequencyCommand (default) genericFrequencyCommand=play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence ==== Speech ==== Speech is configured in section ''[speech]''. Turn speech on or off: enabled=True Values: on=''True'', off=''False'' # Select speech driver, options are speechdDriver (default), genericDriver or espeakDriver: driver=speechdDriver #driver=espeakDriver #driver=genericDriver Select the driver used to generate speech output. driver=speechdDriver Available Drivers: * ''genericDriver'' using the generic driver, for Fenrir <1.5 this is not available * ''speechdDriver'' using speech-dispatcher, for Fenrir <1.5 just use ''speechd'' * ''espeakDriver'' using the espeak directly, for Fenrir <1.5 just use ''espeak'' The rate selects how fast Fenrir will speak. rate=0.65 Values: Range Minimum:''0.0'' is slowest, Maximum:''1.0'' is fastest. Pitch controls the pitch of the voice. pitch=0.5 Values: Range Minimum:''0.0'' is lowest, Maximum:''1.0'' is highest. A Pitch for capital letters can be set. capitalPitch=0.9 Values: Range Minimum:''0.0'' is lowest, Maximum:''1.0'' is highest. The Volume controls the loudness of the voice. volume=1.0 Values: Range Minimum:''0.0'' is quietest, Maximum:''1.0'' is loudest. Some speech drivers like speechdDriver can support various modules. these can be set here. module=espeak Values: Text, Consult speech-dispatcher's configuration to see what modules are available. Voice selects the varient you want to use, for example, f5 will use the female voice #5 in Espeak, or if using the Espeak module in Speech-dispatcher. To find out which voices are available, consult the documentation provided with your selected synthesizer. voice= Values: Text, see your TTS synths documentation what is available. Select the language you want Fenrir to use. language=english-us Values: Text, see your TTS synths documentation what is available. Read new text as it occurs autoReadIncoming=True Values: on=''True'', off=''False'' === Generic Driver === The generic speech driver uses shell commands for speech synthisus. ''genericSpeechCommand'' defines the command that is executed for creating speech The following variables are substituted in ''genericSpeechCommand'': * ''FenrirText'' = is the text that should be spoken * ''fenrirModule'' = may be the speech module like used in speech-dispatcher, not every TTY needs this * ''fenrirLanguage'' = the language to speak in * ''fenrirVoice'' = is the current voice that should be used * ''fenrirVolume'' = is replaced with the current volume * ''fenrirPitch'' = is replaced with the current pitch * ''fenrirRate'' = is replaced with the current speed (speech rate) Example genericSpeechCommand (default): genericSpeechCommand=espeak -a fenrirVolume -s fenrirRate -p fenrirPitch -v fenrirVoice "fenrirText" These are the minimum and maximum values of the TTS system used in genericSpeechCommand. They are needed to calculate the abstract range in volume, rate and pitch 0.0 - 1.0. FenrirMinVolume=0 fenrirMaxVolume=200 fenrirMinPitch=0 fenrirMaxPitch=99 fenrirMinRate=80 fenrirMaxRate=450 The current volume, pitch and rate is calculated like this value = min + [volume,pitch,rate] * (min - max ) ==== Braille ==== Braille is a WIP and not ready yet. Braille support can be configured in section ''[braille]''. Turn braille on or off: enabled=False Values: on=''True'', off=''False'' Select the driver used for communication with a braille device. driver=brlapiDriver Values: Text, available Driver Available Drivers: * ''brlttyDriver'' using brltty for braille communication, for Fenrir <1.5 just use ''brltty'' The Braille layout can be configured here layout=en Values: Text, see braille driver for layouts. What should the flush timeout relate to flushMode=word Values: Text, an flushMode Existing flushModes: * ''word'' = flush after (number of words to display) * seconds * ''char'' = flush after (number of chars to display) * seconds * ''fix'' = flush after X seconds * ''none'' = no automatic flush (manual via shortcut) Seconds to flush (see flushMode) flushTimeout=3 Values: Integer, in Seconds or ''-1'' = no automatic flush (manual via shortcut) The total flush time calculates in relation to flushMode. How should the Braille cursor focus be tracked? cursorFocusMode=page Values: Text, an existing cursor focus mode Available cursor focus modes: * ''page'' = if the cursor crosses the border move to next page and start at begin * ''fixCell'' = ajust the cursor on a special cell where it is always placed. the display scroll here more smooth. Define the cell on the Braille device where Fenrir should scroll and keep the cursor fixCursorOnCell=-1 Values: Integer * ''0'' = first cell on device, * ''-1'' = last cell on device * ''>0'' = fix cell number What cursor should Fenrir show on the Braille device cursorFollowMode=review Values: Text, an exsiting cursor following mode. Existing cursor following mode: * ''none'' = no automatic toggle command used * ''review'' = priority to review * ''last'' = follow last used cursor number of cells in panning (horizontal). How many cell should be panned on press the routing key? panSizeHorizontal=0 Values: Integer, * ''0'' = display size * ''>0'' number of cells ==== Screen ==== The settings for screens, (TTY, PTY) are configured in the ''[screen]'' section. The driver to get the information from the screen: driver=vcsaDriver Available Drivers: * ''vcsaDriver'' using the VCSA driver (for TTYs), for Fenrir <1.5 just use ''vcsa'' The encoding of the screen encoding=cp850 Values:''cp850'' is used for Western languages like USA or Europe. The driver updates Fenrir with changes on the screen. screenUpdateDelay=0.05 Values: in Seconds If you want Fenrir to not be active on any screen for various reasons. Maybe an X server or Wayland is running on that screen. You can make Fenrir ignore it or multiple screens seperated by '','' with: suspendingScreen= Values: Depends on driver: * VCSA: the number of the TTY. TTY6 is ''6''. Example ignore TTY1 and TTY2: suspendingScreen=1,2 There is also the ability to let Fenrir auto detect screens that are running an X server. So Screens running an GUI can be ignored. autodetectSuspendingScreen=True Values: on=''True'', off=''False'' ==== Keyboard ==== The settings for keyboard and input related configuration is located in the section ''[keyboard]'' of the ''settings.conf'' file. Select the driver used for grabbing keybord input and for recieving shortcuts. driver=evdevDriver Values: Text, available Driver Available Drivers: * ''evdevDriver'' uses the evdev input system of linux, for Fenrir <1.5 just use ''evdev'' You can let Fenrir know about what input devices are to be used. device=ALL Values: * ''ALL'' use all devices with key capabilities. * ''NOMICE'' Exclude mices from handling. * '''' just use the device with the given name. Gives Fenrir exclusive access to the keyboard and lets it control keystrokes. This is needed to intercept Fenrir related shortcuts. grabDevices=True Values: on=''True'', off=''False'' The following makes sense if you are using a second screenreader and want to have some hooked events. Fenrir ignores all shortcuts then. ignoreShortcuts=False Values: on=''True'', off=''False'' The current keyboard layout used for shortcuts. keyboardLayout=desktop Values: An absolute Path to a Keyboard definition file or a Filename without extension located in ''/etc/fenrir/keyboard'' Announce characters while typing. charEcho=False Values: on=''True'', off=''False'' Announce deleted characters charDeleteEcho=True Values: on=''True'', off=''False'' Announce word after pressing space wordEcho=False Values: on=''True'', off=''False'' Interrupt speech on any keypress interruptOnKeyPress=False Values: on=''True'', off=''False'' You can filter the keys that speech should interrupt interruptOnKeyPressFilter= Values: (List) empty = all keys, otherwise interrupt with specified keys The timeout that is used for double tap shortcuts doubleTapTimeout=0.2 Values: Seconds ==== General ==== Overall settings can be configured from the section ''[general]''. Set the current debug level: debugLevel=1 Values: off=0, error=1, warning=2, info=3 the current punctuation and dict file in use: punctuationProfile=default Values: Text, see available profiles in ''/etc/fenrir/punctuation'' or in ''sourceTree/config/punctuation'' The current punctuation level in use: punctuationLevel=some Values: Text, See available levels in the used punctuation file. Respect pause for punctuations: respectPunctuationPause=True Values: on=''True'', off=''False'' Add a pause on Line break: newLinePause=True Values: on=''True'', off=''False'' Specify the path where the clipboard should be exported to. See [[#export clipboard to file|export clipboard to file]]. The variable ''$user'' is replaced by the current logged username. clipboardExportPath=/tmp/fenrirClipboard Values: Text, Systemfilepath The number of available clipboards: numberOfClipboards=10 Values: Integer, 1 - 999 Replace emoticons like :) or ;) with text insertions: emoticons=True Values: on=''True'', off=''False'' Define the current Fenrir keys: fenrirKeys=KEY_KP0,KEY_META,KEY_INSERT Values, Text list, separated by comma. Define the current script keys: scriptKey=KEY_COMPOSE Values, Text list, separated by comma. The time format to be used for (time command) output: timeFormat=%H:%M:%P Values: see python specification for [[https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior|datetime.strftime]] The date format to be used for (date command) output: dateFormat=%A, %B %d, %Y Values: see python specification for [[https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior|datetime.strftime]] Enable or Disable spellcheck whilst typing: autoSpellCheck=True Values: on=''True'', off=''False'' The use of the dictionary with spellcheck: spellCheckLanguage=en_US Values: Text, see aspell dictionary's. Folder Path for your scripts "scriptKey" functionality: scriptPath=/usr/share/fenrir/scripts Values: Text, Existing path on file system. Override commands or create new ones without changing the Fenrir defaults: commandPath=/usr/share/fenrir/commands Values: Text, Existing path on file system. Subfolders in commandPath are: * ''commands'' = to create shortcut commands * ''onInput'' = executed while typing * ''onScreenChange'' = executed on change the screen (change from TTY4 to TTY6) * ''onScreenUpdate'' = executed when the screen is captured ==== Focus ==== The configuration for basic focus is in the section ''[focus]''. Follow the text cursor: cursor=True Values: on=''True'', off=''False'' Follow highlighted text changes (Highlight Tracking): highlight=False Values: on=''True'', off=''False'' ==== Review ==== Configurations for the review mode are in the section ''[review]''. If "next word/ char" or "prev word/char" create a linebreak, announce it: lineBreak=True Values: on=''True'', off=''False'' If "next word/ char" or "prev word/char" cannot be performed because you reached the end of the screen, announce it: endOfScreen=True Values: on=''True'', off=''False'' Leave the review mode when pressing a key: leaveReviewOnKeypress=False Values: on=''True'', off=''False'' Leave the review mode when changing the screen (From TTY3 to TTY4): leaveReviewOnScreenChange=True Values: on=''True'', off=''False'' ==== Promote ==== "Promoted Lists" are configured in the section ''[promote]''. Turn Promoted Lists" on or off: enabled=True Values: on=''True'', off=''False'' The minimum time interval of inactivity to activate promoting. By default it promotes after 120 Seconds inactivity: inactiveTimeoutSec=120 Values: in Seconds Define a list of promoted words comma seperated: list= Values: text (comma seperated) Example to promote the word "nickname" or a bash prompt: list=nickname,$:,#: ==== Time ==== The automated time announcement is configured in the section ''[time]''. Time announcement is disabled by default. Turn time announcement on or off: enabled=True Values: on=''True'', off=''False'' Should the time be announced: presentTime=True Values: on=''True'', off=''False'' Should the date be announced (just on date change): presentDate=True Values: on=''True'', off=''False'' Announce after a given period of seconds: delaySec=0 Value: in Seconds, 0 = Deactivated Announce after fixed minutes in an hour. if delaySec is >0 onMinutes is ignored: onMinutes=00,30 Example every 15 minutes: onMinutes=00,15,30,45 Just play a soundicon, (not interrupting): announce=True Values: on=''True'', off=''False'' Interrupt current speech for time announcement: interrupt=False Values: on=''True'', off=''False'' ====== Customization ====== ===== Scripting ===== Scripts can be in any language, bash, python, sh or others. Place your scripts in the directory /usr/share/fenrir/scripts/ (the path is configurable in settings.conf). The script key is the applications key. Usually this key can be found on the keyboard located just left of the right most control key. When you name a script, the key name appears in the script seperated by the sequence __-__. So, for example, if you have a python weather script you want assigned to the script key plus the letter w you would name the script /usr/share/fenrir/scripts/weather__-__key_w.py Then, to access the script, simply press the script key and the letter w. Scripts must be executable. So, make sure to chmod 755 your script when you place it in the scripts directory. The script gets some parameters from fenrir when it is executed. So that information is available in your script then. ==== Parameterlist ==== ^Parameter ^Content ^ |$1|Username of the current logged in user| ==== Examples ==== Script that just speaks the current username when pressing ScriptKey + H.\\ File: ''/usr/share/fenrir/scripts/helloWorld__-__key_h.sh'': #!/bin/bash echo $1 ===== Commands ===== You can place your own commands in "/usr/share/fenrir/commands" (path is configurable in settings.conf). Commands are python files with a special scheme. You can assign them to a shortcut using the filename without an extension or place them in a hook trigger like OnInput or OnScreenChange. For further information see developer guide. Good Examples: [[https://github.com/chrys87/fenrir/blob/master/src/fenrir/commands/commands/date.py|"date.py"]] (announce the Date), [[https://github.com/chrys87/fenrir/blob/master/src/fenrir/commands/commands/shut_up.py|"shut_up.py"]] (interrupt output) the basic scheme for a command is as follows: from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('No description found') def run(self): pass def setCallback(self, callback): pass * [[https://github.com/chrys87/fenrir/blob/master/src/fenrir/commands/command_template.py|Template lives here]] * The class needs to have the name "command". * "initialize" is running once whilst loading the command. * "shutdown" is running on unload like the command (quit fenrir) * "getDescriptsion" just returns an string. That String is used in Tutorial Mode. * "run" is executed when the command is invoked. (shortcut is pressed, or trigger isn't running) * setCAllback is currently not used. and has no functionality yet. ====== Troubleshooting ====== ===== Fenrir does not start ===== - Have you installed all the dependencies [[#Support and Requirements|Support and Requirements]] - Try using master, a lot of changes take place there to make Fenrir compatible with more systems ===== Fenrir does not utilize the shortcuts ===== - Make sure you have python3-evdev installed - Use the latest Fenrir version - Make sure that Fenrir has permission to /dev/input/* and /dev/uinput (or run it as root) ===== No sound at all ===== - Run the script to configure Pulseaudio once as root and once as your user. This will setup Pulseaudio but require a restart of Pulseaudio. The script is located in ''tools/configure_pulse.sh'' - Use ALSA - [[https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/SystemWide/|Configure Pulse system wide]] (Not recommended) - Use gstreamerDriver: change ''settings.conf'' in the section ''sound'' the line ''driver=genericDriver'' to ''driver=gstreamerDriver'' - Use wave sound-icons: change ''settings.conf'' in the section ''sound'' the line ''theme=default'' to ''theme=default-wav'' - Use most current version of [[http://sox.sourceforge.net/|sox]] with opus support - Try [[https://github.com/i-rinat/apulse|apulse]] (not tested by myself but might work). Please give me feedback if you try it out. ===== You get sound-icons but no speech ===== - If you are using speech-dispatcher run "spd-conf" once as user and as root. - You can test if speech-dispatcher works by invoking it as root\\ ''sudo spd-say "hello world"'' ===== Bugreports and feature requests ===== Please report Bugs and feature requests to: [[https://github.com/chrys87/fenrir/issues|https://github.com/chrys87/fenrir/issues]] for bugs please provide a [[#Howto create a debug file|debug]] file that shows the issue. ==== How-to create a debug file ==== - Delete old debug stuff\\ ''sudo rm /var/log/fenrir.log'' - Start fenrir in debug mode\\ ''sudo fenrir -d'' - Do your stuff to reproduce the problem - Stop fenrir (''fenrirKey + q'') the debug file is located in ''/var/log/fenrir.log'' Please be as precise as possible to make it easy to solve the problem. fenrir-1.5.1/experimental/000077500000000000000000000000001317357605400155135ustar00rootroot00000000000000fenrir-1.5.1/experimental/selinux/000077500000000000000000000000001317357605400172025ustar00rootroot00000000000000fenrir-1.5.1/experimental/selinux/Readme.md000066400000000000000000000004121317357605400207160ustar00rootroot00000000000000install it. 1. build it make -f /usr/share/selinux/strict/include/Makefile fenrir.pp 2. install it semodule -i /path/to/fenrir.pp # created with that # systemctl start fenrir # ausearch -c '(r-daemon)' --raw | audit2allow -M fenrir # semodule -X 300 -i fenrir.pp fenrir-1.5.1/experimental/selinux/fenrir.te000066400000000000000000000003411317357605400210170ustar00rootroot00000000000000module fenrir 1.0; require { type user_home_t; type init_t; class file { execute execute_no_trans open read }; } #============= init_t ============== allow init_t user_home_t:file { execute execute_no_trans open read }; fenrir-1.5.1/install.sh000077500000000000000000000041511317357605400150240ustar00rootroot00000000000000#!/bin/bash #Basic install script for Fenrir. read -p "This will install Fenrir. Press ctrl+C to cancel, or enter to continue." continue # Fenrir main application install -m755 -d /opt/fenrir cp -af src/fenrir/* /opt/fenrir install -m644 -D "autostart/systemd/fenrir.service" /usr/lib/systemd/system/fenrir.service ln -fs /opt/fenrir/fenrir-daemon /usr/bin/fenrir-daemon ln -fs /opt/fenrir/fenrir /usr/bin/fenrir # tools install -m755 -d /usr/share/fenrir/tools cp -af tools/* /usr/share/fenrir/tools # scripts install -m755 -d /usr/share/fenrir/scripts cp -af "config/scripts/wlan__-__key_y.sh" /usr/share/fenrir/scripts/ # keyboard install -m644 -D "config/keyboard/desktop.conf" /etc/fenrir/keyboard/desktop.conf install -m644 -D "config/keyboard/laptop.conf" /etc/fenrir/keyboard/laptop.conf # punctuation install -m755 -d /etc/fenrir/punctuation cp -af config/punctuation/* /etc/fenrir/punctuation # sound install -d /usr/share/sounds/fenrir cp -af config/sound/default /usr/share/sounds/fenrir/default cp -af config/sound/default-wav /usr/share/sounds/fenrir/default-wav cp -af config/sound/template /usr/share/sounds/fenrir/template # config if [ -f "/etc/fenrir/settings/settings.conf" ]; then echo "Do you want to overwrite your current global settings? (y/n)" read yn if [ $yn = "Y" -o $yn = "y" ]; then mv /etc/fenrir/settings/settings.conf /etc/fenrir/settings/settings.conf.bak echo "Your old settings.conf has been backed up to settings.conf.bak." install -m644 -D "config/settings/settings.conf" /etc/fenrir/settings/settings.conf else install -m644 -D "config/settings/settings.conf" /etc/fenrir/settings/settings.conf.current fi else install -m644 -D "config/settings/settings.conf" /etc/fenrir/settings/settings.conf fi # end message cat << EOF Installation complete. install path:/opt/fenrir settings path:/etc/fenrir To test Fenrir sudo systemctl start fenrir To have Fenrir start on system boot: sudo systemctl enable fenrir Pulseaudio users may want to run /usr/share/fenrir/tools/configure_pulse.sh once from their user account, then once from the root. EOF fenrir-1.5.1/known bugs.txt000066400000000000000000000006571317357605400156440ustar00rootroot00000000000000Known Bugs (Problems with the logic ): - word echo triggers twice if there are two spaces after an word and you arrow over them - spellcheck triggers twice if there are two spaces after an word and you arrow over them Glitches (improve diff results): - currently None wishes: - whole status line in irssi is spoken insteed of just the changes (lilmike) - whole status line in vim is spoken insteed of just the changes (lilmike) fenrir-1.5.1/locale/000077500000000000000000000000001317357605400142555ustar00rootroot00000000000000fenrir-1.5.1/locale/es/000077500000000000000000000000001317357605400146645ustar00rootroot00000000000000fenrir-1.5.1/locale/es/LC_MESSAGES/000077500000000000000000000000001317357605400164515ustar00rootroot00000000000000fenrir-1.5.1/locale/es/LC_MESSAGES/fenrir.mo000066400000000000000000000342271317357605400203030ustar00rootroot00000000000000 8 9 $G l ( $    2Ba    7 &3 B$Pu $#"^2p'1BTZk'{'6$ , 9GW!m "#*BU&g>?= ,Kx+   23Ey!# * 5C Xc72- -96g15=/Am94;NlnjFXj\1(&O c7  $A]x,:BT@@>.X 7G$4C]y 0 : Q r    S 6"8L"$"7"*" ##1#N#`#x###%###$"!$D$b${$$$A$%%%">%(a%C%%%0%<&9Q&d&'&'06'-g'''''$'( 3(=(Q(,b(#(((-( ) ) )1)H)e){)):))+ *6*N*$c*D*P*W+:v+++4+ ,-,=,L,=g,<,,--8-O-n-- --- -4-#.>.V.q......% /)1/([/)/I/G/@0V0n00 o1 |11111I2&{22$2623 -3 :3[3{33!3"3$3#4'?4g47|44'4'4F 5R5Il505550 6.;6j6|66*667%77"8$8!A8c88#C3',B|mIk [$4&E]hw_if%NQWzA}b X) VL\@yuqsp.SZnl`0Mr:7<1>JOTK-gFUcDjR;/6o"!^+YeH 8x?a *2(dtPG~= 9{v5Autotime: {0}Bookmark for application {0} not setBookmark {0} not setBookmark {0} removed for application {1}Bookmark {0} set for application {1}BottomCapslock offCapslock onFenrir mutedFenrir unmutedFirst clipboard Forward next keypressLast clipboard Move braille view to the left.Move braille view to the right.No Mark foundNo punctuation found.Not in review modeNot in window ModeNumlock offNumlock onQuit FenrirReads from the top of the screen to the cursor positionRemove marksScrolllock offScrolllock onSet the braille view back to cursor.Set window begin and end marksStart FenrirTopTurn off window mode for applicationWindow Mode off for application {0}Window Mode on for application {0}You are leaving the tutorial mode. Press that shortcut again to enter the tutorial mode again.adds the current word to the exceptions dictionaryadjusts the volume for in coming soundsauto spellcheck disabledauto spellcheck enabledautoread disabledautoread enabledautotime disabledautotime enabledbeginning of lineblankbraille disabledbraille enabledchecks the spelling of the current wordclears the currently selected clipboardclipboard clearedclipboard emptycopies marked text to the currently selected clipboardcorrectcurrent linecurrent word.cursor trackingdecrease sound volumedecreases the pitch of the speechdecreases the rate of the speechdecreases the volume of the speechdisables speech until next keypressdisplays the last received textdisplays the position of the review cursoremoticons disabledemoticons enabledenables and disables output in brailleenables or disables announcement of emoticons instead of charsenables or disables automatic reading of new text as it appearsenables or disables automatic reading of time after an periodenables or disables automatic spell checkingenables or disables soundenables or disables speechenables or disables tracking of highlightedend of lineend of screenexits Fenrirexits review modeexport the current fenrir clipboard to X clipboardflush the braille device if a message is written onhighlight trackingincrease the speech rateincrease the speech volumeincreases the pitch of the speechinterrupts the current presentationlast char in lineleave review modeline breakline is emptyline {0}, column {1}misspelledmove review to bottom of screenmove review to top of screenmoves review focus to the previous word and presents itmoves review to the next character and presents itmoves review to the next line and presents itmoves review to the next word and presents itmoves review to the previous character and presents itmoves review to the previous line and presents itno review cursorone or two marks neededpastes the text from the currently selected clipboardphonetically presents the next character and set review to itphonetically presents the previous character and set review to itphonetically spells the current word and set review to itplaces marks to select text to copy to the clipboardplease set begin and endmarkpresent first linepresents the current character.presents the current column number for review cursor in review mode or the text cursor if not. Starts with 1presents the current line number for review cursor in review mode or the text cursor if not. Starts with 1presents the datepresents the timepyenchant is not installedread Bookmark {0}read to end of line, use review cursor if you are in review mode, otherwhise use text cursorreads from the cursor to the bottom of the screenreads the contents of the current screenremove Bookmark {0}removes marks from selected textremoves the current word from the exceptions dictionaryscreen is emptyscreen {0}script: {0} fullpath: {1}scriptfile does not existscriptfile is not a filescriptfile is not executableselects the first clipboardselects the last clipboardselects the next clipboardselects the previous clipboardsends the following keypress to the terminalset Bookmark {0}set Window Mode, needs 2 marks set markset review and phonetically presents the current characterset review cursor to begin of current line and display the contentset review cursor to char below the current char and present it.set review cursor to end of current line and display the contentset review cursor to the char in the line below and present itshows the indention level for the current linesound disabledsound enabledspeaks the contents of the currently selected clipboardspeaks the currently selected text that will be copied to the clipboardspeech disabledspeech enabledspeech temporary disabledtoggles all output settingsyou entered the tutorial mode. In that mode the commands are not executed. but you get a description of what the shortcut does. To leave the tutorial mode, press that shortcut again.{0} added{0} is already in dict{0} is already removed from dict{0} percent sound volume{0} percent speech pitch{0} percent speech rate{0} percent speech volume{0} removedProject-Id-Version: POT-Creation-Date: 2017-02-26 22:19+UTC PO-Revision-Date: 2017-02-26 17:01-0600 Last-Translator: Language-Team: Language: es MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Generated-By: pygettext.py 1.5 X-Generator: Poedit 1.6.11 Plural-Forms: nplurals=2; plural=(n != 1); Hora automática: {0}El marcador para la aplicación {0} no se ha establecidoNo se ha establecido el marcador {0}el marcador {0} de la aplicación {1} ha sido eliminadoAñadido marcador {0} para aplicación {1}FinBloqueo mayúsculas desactivadoBloqueo mayúsculas activadoFenrir silenciadoDesactivado el silencioPrimer portapapelesEnviar la siguiente teclaÚltimo portapapelesMover la vista Braille a la izquierdaMover la vista braille a la derechaNo se han encontrado marcasNo se ha encontrado la puntuaciónNo está en modo de revisiónNo está en modo ventanaBloqueo numérico desactivadoBloqueo numérico activadoCerrando FenrirLee desde el inicio de la pantalla hasta la posición del cursor.Marcas eliminadasBloqueo de desplazamiento desactivadoBloqueo de desplazamiento activadoEstablecer la vista Braille en el cursorEstablece una marca de principio y otra para el final de la ventanaIniciando fenrirFinDesactiva el modo de ventana para la aplicaciónEl modo de ventana está desactivado para la aplicación {0}El modo de ventana está activado para la aplicación {0}Has salido del tutorial. Presiona la misma combinación de teclado para entrar al tutorial de nuevo.añade la palabra actual al diccionarioaumenta el volumen del sonidocorrección ortográfica automática desactivadacorrección ortográfica automática activadaLectura automática desactivadaLectura automática activadaLectura automática de hora desactivadalectura automática de hora activadaprincipio de líneaen blancoBraille desactivadoBraille activadoRevisa la ortografía para la palabra actualVacía el portapapeles seleccionadoPortapapeles vacíoPortapapeles vacíoCopia el texto marcado al portapapeles en usoCorrectolínea actualPalabra actual. Seguimiento del cursorReduce el volumen del sonidoReduce el tono de vozReduce la velocidad de vozReduce el volumen de vozDesactiva el habla hasta la siguiente pulsación de teclasLee el último mensaje recibidoIndica la posición del cursor de revisiónEmoticonos desactivadosEmoticonos activadosActiva y desactiva la salida BrailleActiva o desactiva el anunciado de emoticonos en lugar de caracteresActiva o desactiva la lectura de texto cuando hay nuevo contenido en la pantallaActiva o desactiva la lectura automática de la hora después de un intervalo de tiempoActiva o desactiva la corrección ortográfica automáticaActiva o desactiva el sonidoActiva o desactiva el hablaActiva o desactiva el seguimiento de texto resaltadoFin de líneaFin de pantallaSale de FenrirSale del modo de revisiónExporta el contenido del portapapeles de Fenrir al servidor XLimpia el dispositivo braille al escribir un mensaje en él.Seguimiento del texto resaltadoAumenta la velocidad de vozAumenta el volumen de vozAumenta el tono de vozInterrumpe el habla y braille.último carácter de la líneaSaliendo del modo de revisiónNueva líneaLínea en blancoLínea {0}, columna {1}mal escritoMueve el cursor de revisión al final de la pantallair al final de la pantallaLee la palabra anteriorLee el siguiente carácterLee la siguiente líneaLee la siguiente palabraLee el carácter anteriorLee la línea anteriorNo hay cursor de revisiónse necesita una o dos marcasPega el texto del portapapeles en usoLee fonéticamente el siguiente carácterLee fonéticamente el carácter anteriorDeletrea fonéticamente la palabra actualEstablece marcas para seleccionar texto que será copiado al portapapelesEstablece una marca de principio y otra para el final de la selección.lee la primera líneaLee el carácter actualIndica el número de columna actual para el cursor de revisión si se está en el modo de revisión, o el cursor de texto si no.Indica el número de línea actual para el cursor de revisión si se está en el modo de revisión, o el cursor de texto si no.Lee la fechaLee la horaPyenchant no está instaladoLeer marcador {0}Leer hasta el fin de línea, utiliza el cursor de revisión cuando el modo de revisión está activo, de lo contrario utiliza el cursor de texto.Lee desde el cursor hasta el final de la pantallaLee el contenido de la pantalla actualEliminar marcador {0}Quitar marcas del texto seleccionadoQuita la palabra actual del diccionario de excepcionesLa pantalla está vacíapantalla {0}Script: {0} Ruta de archivo: {1}el archivo del script no existeEl script no es un archivoel script no es ejecutableSelecciona el primer portapapelesSelecciona el último portapapelesSelecciona el siguiente portapapelesSelecciona el portapapeles anteriorEnvía la siguiente tecla a la terminalAñadir marcador {0}se necesitan dos marcas para establecer el modo ventanaMarcarLee fonéticamente el último carácterlee la línea actual desde el principioMueve el cursor de revisión al carácter después del actual y lo leeLee el final de la líneaMueve el cursor de revisión al carácter en la siguiente línea y lo leeLee el nivel de indentación de la línea actualsonido desactivadoSonido activadoHabla el contenido del portapapeles seleccionadoLee el texto que será copiado al portapapelesHabla desactivadaHabla activadaHabla desactivada temporalmenteConmuta el silencio del lector de pantallaHas entrado al tutorial. En este modo las combinaciones de teclado no se ejecutarán pero te darán una descripción de lo que hacen. Para salir del tutorial, presiona la misma combinación de teclado de nuevo.{0} se ha añadido{0} ya se encuentra en el diccionario{0} no está en el diccionariovolumen de sonido al {0} porcientoTono de voz al {0} porcientoVelocidad de voz al {0} porcientoVolumen de voz al {0} porcientose ha eliminado {0}fenrir-1.5.1/locale/es/LC_MESSAGES/fenrir.po000066400000000000000000000777101317357605400203120ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR ORGANIZATION # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: \n" "POT-Creation-Date: 2017-02-26 22:19+UTC\n" "PO-Revision-Date: 2017-02-26 17:01-0600\n" "Last-Translator: \n" "Language-Team: \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: pygettext.py 1.5\n" "X-Generator: Poedit 1.6.11\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: ../src/fenrir/commands/commands/add_word_to_spell_check.py:27 msgid "adds the current word to the exceptions dictionary" msgstr "añade la palabra actual al diccionario" #: ../src/fenrir/commands/commands/add_word_to_spell_check.py:34 #: ../src/fenrir/commands/commands/remove_word_from_spell_check.py:34 #: ../src/fenrir/commands/commands/spell_check.py:29 #: ../src/fenrir/commands/commands/spell_check.py:36 msgid "pyenchant is not installed" msgstr "Pyenchant no está instalado" #: ../src/fenrir/commands/commands/add_word_to_spell_check.py:49 msgid "{0} is already in dict" msgstr "{0} ya se encuentra en el diccionario" #: ../src/fenrir/commands/commands/add_word_to_spell_check.py:52 msgid "{0} added" msgstr "{0} se ha añadido" #: ../src/fenrir/commands/commands/bookmark_1.py:19 #: ../src/fenrir/commands/commands/bookmark_10.py:19 #: ../src/fenrir/commands/commands/bookmark_2.py:19 #: ../src/fenrir/commands/commands/bookmark_3.py:19 #: ../src/fenrir/commands/commands/bookmark_4.py:19 #: ../src/fenrir/commands/commands/bookmark_5.py:19 #: ../src/fenrir/commands/commands/bookmark_6.py:19 #: ../src/fenrir/commands/commands/bookmark_7.py:19 #: ../src/fenrir/commands/commands/bookmark_8.py:19 #: ../src/fenrir/commands/commands/bookmark_9.py:19 msgid "read Bookmark {0}" msgstr "Leer marcador {0}" #: ../src/fenrir/commands/commands/bookmark_1.py:24 #: ../src/fenrir/commands/commands/bookmark_10.py:24 #: ../src/fenrir/commands/commands/bookmark_2.py:24 #: ../src/fenrir/commands/commands/bookmark_3.py:24 #: ../src/fenrir/commands/commands/bookmark_4.py:24 #: ../src/fenrir/commands/commands/bookmark_5.py:24 #: ../src/fenrir/commands/commands/bookmark_6.py:24 #: ../src/fenrir/commands/commands/bookmark_7.py:24 #: ../src/fenrir/commands/commands/bookmark_8.py:24 #: ../src/fenrir/commands/commands/bookmark_9.py:24 msgid "Bookmark {0} not set" msgstr "No se ha establecido el marcador {0}" #: ../src/fenrir/commands/commands/bookmark_1.py:27 #: ../src/fenrir/commands/commands/bookmark_1.py:30 #: ../src/fenrir/commands/commands/bookmark_10.py:27 #: ../src/fenrir/commands/commands/bookmark_10.py:30 #: ../src/fenrir/commands/commands/bookmark_2.py:27 #: ../src/fenrir/commands/commands/bookmark_2.py:30 #: ../src/fenrir/commands/commands/bookmark_3.py:27 #: ../src/fenrir/commands/commands/bookmark_3.py:30 #: ../src/fenrir/commands/commands/bookmark_4.py:27 #: ../src/fenrir/commands/commands/bookmark_4.py:30 #: ../src/fenrir/commands/commands/bookmark_5.py:27 #: ../src/fenrir/commands/commands/bookmark_5.py:30 #: ../src/fenrir/commands/commands/bookmark_6.py:27 #: ../src/fenrir/commands/commands/bookmark_6.py:30 #: ../src/fenrir/commands/commands/bookmark_7.py:27 #: ../src/fenrir/commands/commands/bookmark_7.py:30 #: ../src/fenrir/commands/commands/bookmark_8.py:27 #: ../src/fenrir/commands/commands/bookmark_8.py:30 #: ../src/fenrir/commands/commands/bookmark_9.py:27 #: ../src/fenrir/commands/commands/bookmark_9.py:30 msgid "Bookmark for application {0} not set" msgstr "El marcador para la aplicación {0} no se ha establecido" #: ../src/fenrir/commands/commands/bookmark_1.py:43 #: ../src/fenrir/commands/commands/bookmark_10.py:43 #: ../src/fenrir/commands/commands/bookmark_2.py:43 #: ../src/fenrir/commands/commands/bookmark_3.py:43 #: ../src/fenrir/commands/commands/bookmark_4.py:43 #: ../src/fenrir/commands/commands/bookmark_5.py:43 #: ../src/fenrir/commands/commands/bookmark_6.py:43 #: ../src/fenrir/commands/commands/bookmark_7.py:43 #: ../src/fenrir/commands/commands/bookmark_8.py:43 #: ../src/fenrir/commands/commands/bookmark_9.py:43 #: ../src/fenrir/commands/commands/curr_screen_after_cursor.py:27 #: ../src/fenrir/commands/commands/curr_screen_before_cursor.py:30 #: ../src/fenrir/commands/commands/cursor_read_to_end_of_line.py:27 #: ../src/fenrir/commands/commands/indent_curr_line.py:31 #: ../src/fenrir/commands/commands/marked_text.py:33 #: ../src/fenrir/commands/commands/present_first_line.py:25 #: ../src/fenrir/commands/commands/present_last_line.py:25 #: ../src/fenrir/commands/commands/review_curr_char_phonetic.py:27 #: ../src/fenrir/commands/commands/review_curr_line.py:27 #: ../src/fenrir/commands/commands/review_curr_word.py:27 #: ../src/fenrir/commands/commands/review_curr_word_phonetic.py:27 #: ../src/fenrir/commands/commands/review_line_begin.py:27 #: ../src/fenrir/commands/commands/review_next_line.py:29 #: ../src/fenrir/commands/commands/review_next_word.py:29 #: ../src/fenrir/commands/commands/review_next_word_phonetic.py:27 #: ../src/fenrir/commands/commands/review_prev_line.py:27 #: ../src/fenrir/commands/commands/review_prev_word.py:27 #: ../src/fenrir/commands/commands/review_prev_word_phonetic.py:27 #: ../src/fenrir/commands/onInput/55000-present_line_if_cursor_change_vertical.py:38 #: ../src/fenrir/commands/onInput/72000-history.py:50 msgid "blank" msgstr "en blanco" #: ../src/fenrir/commands/commands/braille_flush.py:17 msgid "flush the braille device if a message is written on" msgstr "Limpia el dispositivo braille al escribir un mensaje en él." #: ../src/fenrir/commands/commands/braille_pan_left.py:17 msgid "Move braille view to the left." msgstr "Mover la vista Braille a la izquierda" #: ../src/fenrir/commands/commands/braille_pan_right.py:17 msgid "Move braille view to the right." msgstr "Mover la vista braille a la derecha" #: ../src/fenrir/commands/commands/braille_return_to_cursor.py:17 msgid "Set the braille view back to cursor." msgstr "Establecer la vista Braille en el cursor" #: ../src/fenrir/commands/commands/clear_bookmark_1.py:17 #: ../src/fenrir/commands/commands/clear_bookmark_10.py:17 #: ../src/fenrir/commands/commands/clear_bookmark_2.py:17 #: ../src/fenrir/commands/commands/clear_bookmark_3.py:17 #: ../src/fenrir/commands/commands/clear_bookmark_4.py:17 #: ../src/fenrir/commands/commands/clear_bookmark_5.py:17 #: ../src/fenrir/commands/commands/clear_bookmark_6.py:17 #: ../src/fenrir/commands/commands/clear_bookmark_7.py:17 #: ../src/fenrir/commands/commands/clear_bookmark_8.py:17 #: ../src/fenrir/commands/commands/clear_bookmark_9.py:17 msgid "remove Bookmark {0}" msgstr "Eliminar marcador {0}" #: ../src/fenrir/commands/commands/clear_bookmark_1.py:24 #: ../src/fenrir/commands/commands/clear_bookmark_10.py:24 #: ../src/fenrir/commands/commands/clear_bookmark_2.py:24 #: ../src/fenrir/commands/commands/clear_bookmark_3.py:24 #: ../src/fenrir/commands/commands/clear_bookmark_4.py:24 #: ../src/fenrir/commands/commands/clear_bookmark_5.py:24 #: ../src/fenrir/commands/commands/clear_bookmark_6.py:24 #: ../src/fenrir/commands/commands/clear_bookmark_7.py:24 #: ../src/fenrir/commands/commands/clear_bookmark_8.py:24 #: ../src/fenrir/commands/commands/clear_bookmark_9.py:24 msgid "Bookmark {0} removed for application {1}" msgstr "el marcador {0} de la aplicación {1} ha sido eliminado" #: ../src/fenrir/commands/commands/clear_clipboard.py:17 msgid "clears the currently selected clipboard" msgstr "Vacía el portapapeles seleccionado" #: ../src/fenrir/commands/commands/clear_clipboard.py:22 msgid "clipboard cleared" msgstr "Portapapeles vacío" #: ../src/fenrir/commands/commands/clear_window_application.py:17 msgid "Turn off window mode for application" msgstr "Desactiva el modo de ventana para la aplicación" #: ../src/fenrir/commands/commands/clear_window_application.py:22 msgid "Window Mode off for application {0}" msgstr "El modo de ventana está desactivado para la aplicación {0}" #: ../src/fenrir/commands/commands/clear_window_application.py:24 msgid "Not in window Mode" msgstr "No está en modo ventana" #: ../src/fenrir/commands/commands/copy_marked_to_clipboard.py:18 msgid "copies marked text to the currently selected clipboard" msgstr "Copia el texto marcado al portapapeles en uso" #: ../src/fenrir/commands/commands/copy_marked_to_clipboard.py:22 msgid "one or two marks needed" msgstr "se necesita una o dos marcas" #: ../src/fenrir/commands/commands/curr_clipboard.py:17 msgid "speaks the contents of the currently selected clipboard" msgstr "Habla el contenido del portapapeles seleccionado" #: ../src/fenrir/commands/commands/curr_clipboard.py:21 #: ../src/fenrir/commands/commands/export_clipboard_to_x.py:29 #: ../src/fenrir/commands/commands/export_clipboard_to_x.py:32 #: ../src/fenrir/commands/commands/export_clipboard_to_x.py:35 #: ../src/fenrir/commands/commands/export_clipboard_to_x.py:38 #: ../src/fenrir/commands/commands/first_clipboard.py:21 #: ../src/fenrir/commands/commands/last_clipboard.py:21 #: ../src/fenrir/commands/commands/next_clipboard.py:21 #: ../src/fenrir/commands/commands/paste_clipboard.py:23 #: ../src/fenrir/commands/commands/paste_clipboard.py:26 #: ../src/fenrir/commands/commands/paste_clipboard.py:29 #: ../src/fenrir/commands/commands/paste_clipboard.py:32 #: ../src/fenrir/commands/commands/prev_clipboard.py:21 msgid "clipboard empty" msgstr "Portapapeles vacío" #: ../src/fenrir/commands/commands/curr_screen.py:17 msgid "reads the contents of the current screen" msgstr "Lee el contenido de la pantalla actual" #: ../src/fenrir/commands/commands/curr_screen.py:21 msgid "screen is empty" msgstr "La pantalla está vacía" #: ../src/fenrir/commands/commands/curr_screen_after_cursor.py:18 msgid "reads from the cursor to the bottom of the screen" msgstr "Lee desde el cursor hasta el final de la pantalla" #: ../src/fenrir/commands/commands/curr_screen_before_cursor.py:18 msgid "Reads from the top of the screen to the cursor position" msgstr "Lee desde el inicio de la pantalla hasta la posición del cursor." #: ../src/fenrir/commands/commands/cursor_column.py:17 msgid "" "presents the current column number for review cursor in review mode or the " "text cursor if not. Starts with 1" msgstr "" "Indica el número de columna actual para el cursor de revisión si se está en " "el modo de revisión, o el cursor de texto si no." #: ../src/fenrir/commands/commands/cursor_lineno.py:17 msgid "" "presents the current line number for review cursor in review mode or the " "text cursor if not. Starts with 1" msgstr "" "Indica el número de línea actual para el cursor de revisión si se está en el " "modo de revisión, o el cursor de texto si no." #: ../src/fenrir/commands/commands/cursor_position.py:17 msgid "displays the position of the review cursor" msgstr "Indica la posición del cursor de revisión" #: ../src/fenrir/commands/commands/cursor_position.py:23 msgid "line {0}, column {1}" msgstr "Línea {0}, columna {1}" #: ../src/fenrir/commands/commands/cursor_read_to_end_of_line.py:18 msgid "" "read to end of line, use review cursor if you are in review mode, otherwhise " "use text cursor" msgstr "" "Leer hasta el fin de línea, utiliza el cursor de revisión cuando el modo de " "revisión está activo, de lo contrario utiliza el cursor de texto." #: ../src/fenrir/commands/commands/date.py:18 msgid "presents the date" msgstr "Lee la fecha" #: ../src/fenrir/commands/commands/dec_sound_volume.py:18 msgid "decrease sound volume" msgstr "Reduce el volumen del sonido" #: ../src/fenrir/commands/commands/dec_sound_volume.py:29 #: ../src/fenrir/commands/commands/inc_sound_volume.py:29 msgid "{0} percent sound volume" msgstr "volumen de sonido al {0} porciento" #: ../src/fenrir/commands/commands/dec_speech_pitch.py:18 msgid "decreases the pitch of the speech" msgstr "Reduce el tono de voz" #: ../src/fenrir/commands/commands/dec_speech_pitch.py:27 #: ../src/fenrir/commands/commands/inc_speech_pitch.py:27 msgid "{0} percent speech pitch" msgstr "Tono de voz al {0} porciento" #: ../src/fenrir/commands/commands/dec_speech_rate.py:18 msgid "decreases the rate of the speech" msgstr "Reduce la velocidad de voz" #: ../src/fenrir/commands/commands/dec_speech_rate.py:27 #: ../src/fenrir/commands/commands/inc_speech_rate.py:27 msgid "{0} percent speech rate" msgstr "Velocidad de voz al {0} porciento" #: ../src/fenrir/commands/commands/dec_speech_volume.py:18 msgid "decreases the volume of the speech" msgstr "Reduce el volumen de voz" #: ../src/fenrir/commands/commands/dec_speech_volume.py:27 #: ../src/fenrir/commands/commands/inc_speech_volume.py:27 msgid "{0} percent speech volume" msgstr "Volumen de voz al {0} porciento" #: ../src/fenrir/commands/commands/exit_review.py:17 msgid "exits review mode" msgstr "Sale del modo de revisión" #: ../src/fenrir/commands/commands/exit_review.py:21 msgid "Not in review mode" msgstr "No está en modo de revisión" #: ../src/fenrir/commands/commands/exit_review.py:25 msgid "leave review mode" msgstr "Saliendo del modo de revisión" #: ../src/fenrir/commands/commands/export_clipboard_to_x.py:21 msgid "export the current fenrir clipboard to X clipboard" msgstr "Exporta el contenido del portapapeles de Fenrir al servidor X" #: ../src/fenrir/commands/commands/first_clipboard.py:17 msgid "selects the first clipboard" msgstr "Selecciona el primer portapapeles" #: ../src/fenrir/commands/commands/forward_keypress.py:17 msgid "sends the following keypress to the terminal" msgstr "Envía la siguiente tecla a la terminal" #: ../src/fenrir/commands/commands/forward_keypress.py:21 msgid "Forward next keypress" msgstr "Enviar la siguiente tecla" #: ../src/fenrir/commands/commands/inc_sound_volume.py:18 msgid "adjusts the volume for in coming sounds" msgstr "aumenta el volumen del sonido" #: ../src/fenrir/commands/commands/inc_speech_pitch.py:18 msgid "increases the pitch of the speech" msgstr "Aumenta el tono de voz" #: ../src/fenrir/commands/commands/inc_speech_rate.py:18 msgid "increase the speech rate" msgstr "Aumenta la velocidad de voz" #: ../src/fenrir/commands/commands/inc_speech_volume.py:18 msgid "increase the speech volume" msgstr "Aumenta el volumen de voz" #: ../src/fenrir/commands/commands/indent_curr_line.py:18 msgid "shows the indention level for the current line" msgstr "Lee el nivel de indentación de la línea actual" #: ../src/fenrir/commands/commands/indent_curr_line.py:33 msgid "indent {0}" msgstr "" #: ../src/fenrir/commands/commands/last_clipboard.py:17 msgid "selects the last clipboard" msgstr "Selecciona el último portapapeles" #: ../src/fenrir/commands/commands/last_incoming.py:17 msgid "displays the last received text" msgstr "Lee el último mensaje recibido" #: ../src/fenrir/commands/commands/marked_text.py:18 msgid "speaks the currently selected text that will be copied to the clipboard" msgstr "Lee el texto que será copiado al portapapeles" #: ../src/fenrir/commands/commands/marked_text.py:23 msgid "please set begin and endmark" msgstr "Establece una marca de principio y otra para el final de la selección." #: ../src/fenrir/commands/commands/next_clipboard.py:17 msgid "selects the next clipboard" msgstr "Selecciona el siguiente portapapeles" #: ../src/fenrir/commands/commands/next_clipboard.py:26 msgid "First clipboard " msgstr "Primer portapapeles" #: ../src/fenrir/commands/commands/paste_clipboard.py:18 msgid "pastes the text from the currently selected clipboard" msgstr "Pega el texto del portapapeles en uso" #: ../src/fenrir/commands/commands/present_first_line.py:18 msgid "present first line" msgstr "lee la primera línea" #: ../src/fenrir/commands/commands/present_last_line.py:18 #: ../src/fenrir/commands/commands/review_curr_line.py:18 msgid "current line" msgstr "línea actual" #: ../src/fenrir/commands/commands/prev_clipboard.py:17 msgid "selects the previous clipboard" msgstr "Selecciona el portapapeles anterior" #: ../src/fenrir/commands/commands/prev_clipboard.py:26 msgid "Last clipboard " msgstr "Último portapapeles" #: ../src/fenrir/commands/commands/quit_fenrir.py:17 msgid "exits Fenrir" msgstr "Sale de Fenrir" #: ../src/fenrir/commands/commands/remove_marks.py:17 msgid "removes marks from selected text" msgstr "Quitar marcas del texto seleccionado" #: ../src/fenrir/commands/commands/remove_marks.py:21 msgid "Remove marks" msgstr "Marcas eliminadas" #: ../src/fenrir/commands/commands/remove_word_from_spell_check.py:27 msgid "removes the current word from the exceptions dictionary" msgstr "Quita la palabra actual del diccionario de excepciones" #: ../src/fenrir/commands/commands/remove_word_from_spell_check.py:50 msgid "{0} is already removed from dict" msgstr "{0} no está en el diccionario" #: ../src/fenrir/commands/commands/remove_word_from_spell_check.py:53 msgid "{0} removed" msgstr "se ha eliminado {0}" #: ../src/fenrir/commands/commands/review_bottom.py:17 msgid "move review to bottom of screen" msgstr "Mueve el cursor de revisión al final de la pantalla" #: ../src/fenrir/commands/commands/review_bottom.py:21 msgid "Bottom" msgstr "Fin" #: ../src/fenrir/commands/commands/review_curr_char.py:18 msgid "presents the current character." msgstr "Lee el carácter actual" #: ../src/fenrir/commands/commands/review_curr_char_phonetic.py:18 msgid "set review and phonetically presents the current character" msgstr "Lee fonéticamente el último carácter" #: ../src/fenrir/commands/commands/review_curr_word.py:18 msgid "current word." msgstr "Palabra actual. " #: ../src/fenrir/commands/commands/review_curr_word.py:32 #: ../src/fenrir/commands/commands/review_curr_word_phonetic.py:36 #: ../src/fenrir/commands/commands/review_down.py:27 #: ../src/fenrir/commands/commands/review_next_char.py:28 #: ../src/fenrir/commands/commands/review_next_char_phonetic.py:30 #: ../src/fenrir/commands/commands/review_next_line.py:34 #: ../src/fenrir/commands/commands/review_next_word.py:34 #: ../src/fenrir/commands/commands/review_next_word_phonetic.py:36 #: ../src/fenrir/commands/commands/review_prev_char.py:31 #: ../src/fenrir/commands/commands/review_prev_char_phonetic.py:30 #: ../src/fenrir/commands/commands/review_prev_line.py:32 #: ../src/fenrir/commands/commands/review_prev_word.py:32 #: ../src/fenrir/commands/commands/review_prev_word_phonetic.py:36 #: ../src/fenrir/commands/commands/review_up.py:27 msgid "end of screen" msgstr "Fin de pantalla" #: ../src/fenrir/commands/commands/review_curr_word.py:35 #: ../src/fenrir/commands/commands/review_curr_word_phonetic.py:39 #: ../src/fenrir/commands/commands/review_next_char.py:31 #: ../src/fenrir/commands/commands/review_next_char_phonetic.py:33 #: ../src/fenrir/commands/commands/review_next_word.py:37 #: ../src/fenrir/commands/commands/review_next_word_phonetic.py:39 #: ../src/fenrir/commands/commands/review_prev_char.py:34 #: ../src/fenrir/commands/commands/review_prev_char_phonetic.py:33 #: ../src/fenrir/commands/commands/review_prev_word.py:35 #: ../src/fenrir/commands/commands/review_prev_word_phonetic.py:39 #: ../src/fenrir/commands/commands/review_up.py:30 msgid "line break" msgstr "Nueva línea" #: ../src/fenrir/commands/commands/review_curr_word_phonetic.py:19 #: ../src/fenrir/commands/commands/review_next_word_phonetic.py:19 #: ../src/fenrir/commands/commands/review_prev_word_phonetic.py:19 msgid "phonetically spells the current word and set review to it" msgstr "Deletrea fonéticamente la palabra actual" #: ../src/fenrir/commands/commands/review_down.py:18 msgid "set review cursor to char below the current char and present it." msgstr "Mueve el cursor de revisión al carácter después del actual y lo lee" #: ../src/fenrir/commands/commands/review_line_begin.py:18 msgid "set review cursor to begin of current line and display the content" msgstr "lee la línea actual desde el principio" #: ../src/fenrir/commands/commands/review_line_begin.py:30 msgid "beginning of line" msgstr "principio de línea" #: ../src/fenrir/commands/commands/review_line_end.py:18 #: ../src/fenrir/commands/commands/review_line_first_char.py:19 #: ../src/fenrir/commands/commands/review_line_last_char.py:18 msgid "set review cursor to end of current line and display the content" msgstr "Lee el final de la línea" #: ../src/fenrir/commands/commands/review_line_end.py:27 msgid "end of line" msgstr "Fin de línea" #: ../src/fenrir/commands/commands/review_line_first_char.py:26 msgid "line is empty" msgstr "Línea en blanco" #: ../src/fenrir/commands/commands/review_line_first_char.py:33 msgid "first char in line indent {0}" msgstr "" #: ../src/fenrir/commands/commands/review_line_last_char.py:27 msgid "last char in line" msgstr "último carácter de la línea" #: ../src/fenrir/commands/commands/review_next_char.py:18 msgid "moves review to the next character and presents it" msgstr "Lee el siguiente carácter" #: ../src/fenrir/commands/commands/review_next_char_phonetic.py:18 msgid "phonetically presents the next character and set review to it" msgstr "Lee fonéticamente el siguiente carácter" #: ../src/fenrir/commands/commands/review_next_line.py:18 msgid "moves review to the next line and presents it" msgstr "Lee la siguiente línea" #: ../src/fenrir/commands/commands/review_next_word.py:18 msgid "moves review to the next word and presents it" msgstr "Lee la siguiente palabra" #: ../src/fenrir/commands/commands/review_prev_char.py:18 msgid "moves review to the previous character and presents it" msgstr "Lee el carácter anterior" #: ../src/fenrir/commands/commands/review_prev_char_phonetic.py:18 msgid "phonetically presents the previous character and set review to it" msgstr "Lee fonéticamente el carácter anterior" #: ../src/fenrir/commands/commands/review_prev_line.py:18 msgid "moves review to the previous line and presents it" msgstr "Lee la línea anterior" #: ../src/fenrir/commands/commands/review_prev_word.py:18 msgid "moves review focus to the previous word and presents it" msgstr "Lee la palabra anterior" #: ../src/fenrir/commands/commands/review_top.py:18 msgid "move review to top of screen" msgstr "ir al final de la pantalla" #: ../src/fenrir/commands/commands/review_top.py:22 msgid "Top" msgstr "Fin" #: ../src/fenrir/commands/commands/review_up.py:18 msgid "set review cursor to the char in the line below and present it" msgstr "Mueve el cursor de revisión al carácter en la siguiente línea y lo lee" #: ../src/fenrir/commands/commands/set_bookmark_1.py:18 #: ../src/fenrir/commands/commands/set_bookmark_10.py:18 #: ../src/fenrir/commands/commands/set_bookmark_2.py:18 #: ../src/fenrir/commands/commands/set_bookmark_3.py:18 #: ../src/fenrir/commands/commands/set_bookmark_4.py:18 #: ../src/fenrir/commands/commands/set_bookmark_5.py:18 #: ../src/fenrir/commands/commands/set_bookmark_6.py:18 #: ../src/fenrir/commands/commands/set_bookmark_7.py:18 #: ../src/fenrir/commands/commands/set_bookmark_8.py:18 #: ../src/fenrir/commands/commands/set_bookmark_9.py:18 msgid "set Bookmark {0}" msgstr "Añadir marcador {0}" #: ../src/fenrir/commands/commands/set_bookmark_1.py:22 #: ../src/fenrir/commands/commands/set_bookmark_10.py:22 #: ../src/fenrir/commands/commands/set_bookmark_2.py:22 #: ../src/fenrir/commands/commands/set_bookmark_3.py:22 #: ../src/fenrir/commands/commands/set_bookmark_4.py:22 #: ../src/fenrir/commands/commands/set_bookmark_5.py:22 #: ../src/fenrir/commands/commands/set_bookmark_6.py:22 #: ../src/fenrir/commands/commands/set_bookmark_7.py:22 #: ../src/fenrir/commands/commands/set_bookmark_8.py:22 #: ../src/fenrir/commands/commands/set_bookmark_9.py:22 msgid "No Mark found" msgstr "No se han encontrado marcas" #: ../src/fenrir/commands/commands/set_bookmark_1.py:32 #: ../src/fenrir/commands/commands/set_bookmark_10.py:32 #: ../src/fenrir/commands/commands/set_bookmark_2.py:32 #: ../src/fenrir/commands/commands/set_bookmark_3.py:32 #: ../src/fenrir/commands/commands/set_bookmark_4.py:32 #: ../src/fenrir/commands/commands/set_bookmark_5.py:32 #: ../src/fenrir/commands/commands/set_bookmark_6.py:32 #: ../src/fenrir/commands/commands/set_bookmark_7.py:32 #: ../src/fenrir/commands/commands/set_bookmark_8.py:32 #: ../src/fenrir/commands/commands/set_bookmark_9.py:32 msgid "Bookmark {0} set for application {1}" msgstr "Añadido marcador {0} para aplicación {1}" #: ../src/fenrir/commands/commands/set_mark.py:17 msgid "places marks to select text to copy to the clipboard" msgstr "" "Establece marcas para seleccionar texto que será copiado al portapapeles" #: ../src/fenrir/commands/commands/set_mark.py:21 msgid "no review cursor" msgstr "No hay cursor de revisión" #: ../src/fenrir/commands/commands/set_mark.py:26 #: ../src/fenrir/commands/commands/set_mark.py:28 msgid "set mark" msgstr "Marcar" #: ../src/fenrir/commands/commands/set_window_application.py:17 msgid "set Window Mode, needs 2 marks " msgstr "se necesitan dos marcas para establecer el modo ventana" #: ../src/fenrir/commands/commands/set_window_application.py:22 msgid "Window Mode on for application {0}" msgstr "El modo de ventana está activado para la aplicación {0}" #: ../src/fenrir/commands/commands/set_window_application.py:25 msgid "Set window begin and end marks" msgstr "Establece una marca de principio y otra para el final de la ventana" #: ../src/fenrir/commands/commands/shut_up.py:17 msgid "interrupts the current presentation" msgstr "Interrumpe el habla y braille." #: ../src/fenrir/commands/commands/spell_check.py:26 msgid "checks the spelling of the current word" msgstr "Revisa la ortografía para la palabra actual" #: ../src/fenrir/commands/commands/spell_check.py:52 #: ../src/fenrir/commands/onInput/62000-spell_check.py:132 msgid "misspelled" msgstr "mal escrito" #: ../src/fenrir/commands/commands/spell_check.py:54 msgid "correct" msgstr "Correcto" #: ../src/fenrir/commands/commands/subprocess.py:21 msgid "script: {0} fullpath: {1}" msgstr "Script: {0} Ruta de archivo: {1}" #: ../src/fenrir/commands/commands/subprocess.py:24 msgid "scriptfile does not exist" msgstr "el archivo del script no existe" #: ../src/fenrir/commands/commands/subprocess.py:27 msgid "scriptfile is not a file" msgstr "El script no es un archivo" #: ../src/fenrir/commands/commands/subprocess.py:30 msgid "scriptfile is not executable" msgstr "el script no es ejecutable" #: ../src/fenrir/commands/commands/temp_disable_speech.py:17 #: ../src/fenrir/commands/onInput/15000-enable_temp_speech.py:17 msgid "disables speech until next keypress" msgstr "Desactiva el habla hasta la siguiente pulsación de teclas" #: ../src/fenrir/commands/commands/temp_disable_speech.py:21 msgid "speech temporary disabled" msgstr "Habla desactivada temporalmente" #: ../src/fenrir/commands/commands/time.py:18 msgid "presents the time" msgstr "Lee la hora" #: ../src/fenrir/commands/commands/toggle_auto_read.py:16 msgid "enables or disables automatic reading of new text as it appears" msgstr "" "Activa o desactiva la lectura de texto cuando hay nuevo contenido en la " "pantalla" #: ../src/fenrir/commands/commands/toggle_auto_read.py:21 msgid "autoread enabled" msgstr "Lectura automática activada" #: ../src/fenrir/commands/commands/toggle_auto_read.py:23 msgid "autoread disabled" msgstr "Lectura automática desactivada" #: ../src/fenrir/commands/commands/toggle_auto_spell_check.py:17 msgid "enables or disables automatic spell checking" msgstr "Activa o desactiva la corrección ortográfica automática" #: ../src/fenrir/commands/commands/toggle_auto_spell_check.py:22 msgid "auto spellcheck enabled" msgstr "corrección ortográfica automática activada" #: ../src/fenrir/commands/commands/toggle_auto_spell_check.py:24 msgid "auto spellcheck disabled" msgstr "corrección ortográfica automática desactivada" #: ../src/fenrir/commands/commands/toggle_auto_time.py:16 msgid "enables or disables automatic reading of time after an period" msgstr "" "Activa o desactiva la lectura automática de la hora después de un intervalo " "de tiempo" #: ../src/fenrir/commands/commands/toggle_auto_time.py:21 msgid "autotime enabled" msgstr "lectura automática de hora activada" #: ../src/fenrir/commands/commands/toggle_auto_time.py:23 msgid "autotime disabled" msgstr "Lectura automática de hora desactivada" #: ../src/fenrir/commands/commands/toggle_braille.py:17 msgid "enables and disables output in braille" msgstr "Activa y desactiva la salida Braille" #: ../src/fenrir/commands/commands/toggle_braille.py:21 msgid "braille disabled" msgstr "Braille desactivado" #: ../src/fenrir/commands/commands/toggle_braille.py:24 msgid "braille enabled" msgstr "Braille activado" #: ../src/fenrir/commands/commands/toggle_emoticons.py:16 msgid "enables or disables announcement of emoticons instead of chars" msgstr "Activa o desactiva el anunciado de emoticonos en lugar de caracteres" #: ../src/fenrir/commands/commands/toggle_emoticons.py:21 msgid "emoticons enabled" msgstr "Emoticonos activados" #: ../src/fenrir/commands/commands/toggle_emoticons.py:23 msgid "emoticons disabled" msgstr "Emoticonos desactivados" #: ../src/fenrir/commands/commands/toggle_highlight_tracking.py:16 #: ../src/fenrir/commands/onInput/56000-highlight_tracking.py:16 msgid "enables or disables tracking of highlighted" msgstr "Activa o desactiva el seguimiento de texto resaltado" #: ../src/fenrir/commands/commands/toggle_highlight_tracking.py:24 msgid "highlight tracking" msgstr "Seguimiento del texto resaltado" #: ../src/fenrir/commands/commands/toggle_highlight_tracking.py:26 msgid "cursor tracking" msgstr "Seguimiento del cursor" #: ../src/fenrir/commands/commands/toggle_output.py:17 msgid "toggles all output settings" msgstr "Conmuta el silencio del lector de pantalla" #: ../src/fenrir/commands/commands/toggle_output.py:23 msgid "Fenrir muted" msgstr "Fenrir silenciado" #: ../src/fenrir/commands/commands/toggle_output.py:31 msgid "Fenrir unmuted" msgstr "Desactivado el silencio" #: ../src/fenrir/commands/commands/toggle_punctuation_level.py:23 msgid "No punctuation found." msgstr "No se ha encontrado la puntuación" #: ../src/fenrir/commands/commands/toggle_sound.py:17 msgid "enables or disables sound" msgstr "Activa o desactiva el sonido" #: ../src/fenrir/commands/commands/toggle_sound.py:21 msgid "sound disabled" msgstr "sonido desactivado" #: ../src/fenrir/commands/commands/toggle_sound.py:24 msgid "sound enabled" msgstr "Sonido activado" #: ../src/fenrir/commands/commands/toggle_speech.py:17 msgid "enables or disables speech" msgstr "Activa o desactiva el habla" #: ../src/fenrir/commands/commands/toggle_speech.py:21 msgid "speech disabled" msgstr "Habla desactivada" #: ../src/fenrir/commands/commands/toggle_speech.py:24 #: ../src/fenrir/commands/onInput/15000-enable_temp_speech.py:28 msgid "speech enabled" msgstr "Habla activada" #: ../src/fenrir/commands/commands/toggle_tutorial_mode.py:18 msgid "" "You are leaving the tutorial mode. Press that shortcut again to enter the " "tutorial mode again." msgstr "" "Has salido del tutorial. Presiona la misma combinación de teclado para " "entrar al tutorial de nuevo." #: ../src/fenrir/commands/commands/toggle_tutorial_mode.py:21 msgid "" "you entered the tutorial mode. In that mode the commands are not executed. " "but you get a description of what the shortcut does. To leave the tutorial " "mode, press that shortcut again." msgstr "" "Has entrado al tutorial. En este modo las combinaciones de teclado no se " "ejecutarán pero te darán una descripción de lo que hacen. Para salir del " "tutorial, presiona la misma combinación de teclado de nuevo." #: ../src/fenrir/commands/onInput/80000-capslock.py:22 msgid "Capslock on" msgstr "Bloqueo mayúsculas activado" #: ../src/fenrir/commands/onInput/80000-capslock.py:24 msgid "Capslock off" msgstr "Bloqueo mayúsculas desactivado" #: ../src/fenrir/commands/onInput/80300-scrolllock.py:22 msgid "Scrolllock on" msgstr "Bloqueo de desplazamiento activado" #: ../src/fenrir/commands/onInput/80300-scrolllock.py:24 msgid "Scrolllock off" msgstr "Bloqueo de desplazamiento desactivado" #: ../src/fenrir/commands/onInput/80500-numlock.py:22 msgid "Numlock on" msgstr "Bloqueo numérico activado" #: ../src/fenrir/commands/onInput/80500-numlock.py:24 msgid "Numlock off" msgstr "Bloqueo numérico desactivado" #: ../src/fenrir/commands/onScreenChanged/80000-screen_change_announcement.py:20 msgid "screen {0}" msgstr "pantalla {0}" #: ../src/fenrir/commands/onScreenUpdate/76000-time.py:66 msgid "Autotime: {0}" msgstr "Hora automática: {0}" #: ../src/fenrir/fenrir.py:24 msgid "Start Fenrir" msgstr "Iniciando fenrir" #: ../src/fenrir/fenrir.py:99 msgid "Quit Fenrir" msgstr "Cerrando Fenrir" fenrir-1.5.1/play zone/000077500000000000000000000000001317357605400147175ustar00rootroot00000000000000fenrir-1.5.1/play zone/argp.py000077500000000000000000000006741317357605400162340ustar00rootroot00000000000000#!/bin/python3 import argparse parser = argparse.ArgumentParser(description="Fenrir Help") parser.add_argument('-s', '--setting', metavar='SETTING-FILE', default='/etc/fenrir/settings/settings.conf', help='Use a specified settingsfile') parser.add_argument('-o', '--options', metavar='SECTION:SETTING=VALUE,..', default='', help='Overwrite options in given settings file') args = parser.parse_args() parser.print_help() print(args.setting) fenrir-1.5.1/play zone/charmapTTY.py000077500000000000000000000047311317357605400173150ustar00rootroot00000000000000import time from fcntl import ioctl from array import array from struct import unpack_from from struct import unpack from struct import pack import errno import sys charmap = {} hichar = None def updateCharMap(screen): global hichar ttyno = '4' tty = open('/dev/tty' + screen, 'rb') GIO_UNIMAP = 0x4B66 VT_GETHIFONTMASK = 0x560D himask = array("H", (0,)) ioctl(tty, VT_GETHIFONTMASK, himask) hichar, = unpack_from("@H", himask) sz = 512 line = '' while True: try: unipairs = array("H", [0]*(2*sz)) unimapdesc = array("B", pack("@HP", sz, unipairs.buffer_info()[0])) ioctl(tty.fileno(), GIO_UNIMAP, unimapdesc) break except IOError as e: if e.errno != errno.ENOMEM: raise sz *= 2 tty.close() ncodes, = unpack_from("@H", unimapdesc) utable = unpack_from("@%dH" % (2*ncodes), unipairs) for u, b in zip(utable[::2], utable[1::2]): if charmap.get(b) is None: charmap[b] = chr(u) def autoDecodeVCSA(allData, rows, cols): allText = [] allAttrib = [] for y in range(rows): lineText = '' lineAttrib = [] i = 0 for x in range(cols): data = allData[i: i + 2] i += 2 if data == b' \x07': #attr = 7 #ink = 7 #paper = 0 #ch = ' ' lineAttrib.append(7) lineText += ' ' continue (sh,) = unpack("=H", data) attr = (sh >> 8) & 0xFF ch = sh & 0xFF if hichar == 0x100: attr >>= 1 lineAttrib.append(attr) ink = attr & 0x0F paper = (attr>>4) & 0x0F #if (ink != 7) or (paper != 0): # print(ink,paper) if sh & hichar: ch |= 0x100 try: lineText += charmap[ch] except: lineText += chr('?') allText.append(lineText) allAttrib.append(lineAttrib) return allText, allAttrib def m(screen): s = time.time() updateCharMap(str(screen)) print(time.time() -s ) vcsa = open('/dev/vcsa' + str(screen), 'rb') head = vcsa.read(4) rows = int(head[0]) cols = int(head[1]) text, attrib = autoDecodeVCSA(vcsa.read(), rows, cols) print(time.time() -s ) fenrir-1.5.1/play zone/colors.sh000066400000000000000000000016161317357605400165600ustar00rootroot00000000000000#!/bin/bash echo "foreground colors" echo -e "\e[39mDefault" echo -e "\e[30mBlack" echo -e "\e[31mRed" echo -e "\e[32mGreen" echo -e "\e[33mYellow" echo -e "\e[34mBlue" echo -e "\e[35mMagenta" echo -e "\e[36mCyan" echo -e "\e[37mLight gray" echo -e "\e[90mDark gray" echo -e "\e[91mLight red" echo -e "\e[92mLight green" echo -e "\e[93mLight yellow" echo -e "\e[94mLight blue" echo -e "\e[95mLight magenta" echo -e "\e[96mLight cyan" echo -e "\e[97mWhite" echo "background colors" echo -e "\e[49mDefault" echo -e "\e[40mBlack" echo -e "\e[41mRed" echo -e "\e[42mGreen" echo -e "\e[43mYellow" echo -e "\e[44mBlue" echo -e "\e[45mMagenta" echo -e "\e[46mCyan" echo -e "\e[47mLight gray" echo -e "\e[100mDark gray" echo -e "\e[101mLight red" echo -e "\e[102mLight green" echo -e "\e[103mLight yellow" echo -e "\e[104mLight blue" echo -e "\e[105mLight magenta" echo -e "\e[106mLight cyan" echo -e "\e[107mWhite" fenrir-1.5.1/play zone/consumeEvents.py000077500000000000000000000023651317357605400201400ustar00rootroot00000000000000#!/bin/python import evdev from evdev import InputDevice, UInput from select import select import time iDevices = map(evdev.InputDevice, (evdev.list_devices())) iDevices = {dev.fd: dev for dev in iDevices if evdev.events.EV_KEY in dev.capabilities()} uDevices = {} for fd in iDevices: dev = iDevices[fd] cap = dev.capabilities() del cap[0] uDevices[fd] = UInput( cap, dev.name, dev.info.vendor, # dev.info.product, # dev.version, # dev.info.bustype, # '/dev/uinput' ) dev.grab() i = 0 while i < 100: r, w, x = select(iDevices, [], []) if r != []: i += 1 for fd in r: for event in iDevices[fd].read(): if event.code != 30: # a print(event) uDevices[fd].write_event(event) uDevices[fd].syn() #print('Devicename:'+ devices[fd].name + ' Devicepath:' + devices[fd].fn + ' Events:' + str(devices[fd].active_keys(verbose=True)) + ' Value:' + str(event.value)) else: print('this key is consumed') for fd in iDevices: iDevices[fd].ungrab() iDevices[fd].close() uDevices[fd].close() iDevices.clear() uDevices.clear() fenrir-1.5.1/play zone/daemon.py000077500000000000000000000003061317357605400165360ustar00rootroot00000000000000from time import sleep from daemonize import Daemonize pid = "/tmp/test.pid" def main(): while True: sleep(5) daemon = Daemonize(app="test_app", pid=pid, action=main) daemon.start() fenrir-1.5.1/play zone/detectDevices.py000077500000000000000000000035111317357605400200470ustar00rootroot00000000000000#!/bin/python iDevices = {} iDeviceNo = 0 def updateInputDevices(force = False, init = False): global iDeviceNo if init: iDevices = {} iDeviceNo = 0 deviceFileList = evdev.list_devices() if not force: if len(deviceFileList) == iDeviceNo: return iDeviceNo = len(deviceFileList) mode = 'ALL' iDevicesFiles = [] for device in iDevices: iDevicesFiles.append(iDevices[device].fn) print(len(iDevicesFiles),len(deviceFileList)) if len(iDevicesFiles) == len(deviceFileList): return for deviceFile in deviceFileList: try: if deviceFile in iDevicesFiles: print('skip') continue open(deviceFile) # 3 pos absolute # 2 pos relative # 1 Keys currDevice = evdev.InputDevice(deviceFile) cap = currDevice.capabilities() if mode in ['ALL','NOMICE']: if 1 in cap: if 116 in cap[1] and len(cap[1]) < 5: print('power') continue if mode == 'ALL': iDevices[currDevice.fd] = currDevice print('Device added:' + iDevices[currDevice.fd].name) elif mode == 'NOMICE': if not ((2 in cap) or (3 in cap)): iDevices[currDevice.fd] = currDevice print('Device added:' + iDevices[currDevice.fd].name) elif currDevice.name.upper() in mode.split(','): iDevices[currDevice.fd] = currDevice print('Device added:' + iDevices[currDevice.fd].name) except Exception as e: print("Skip Inputdevice : " + deviceFile +' ' + str(e)) fenrir-1.5.1/play zone/epollScreen.py000066400000000000000000000021721317357605400175460ustar00rootroot00000000000000#!/bin/python import select import time currScreen = '2' vcsa = {} for i in range(1,7): vcsa[str(i)] = open('/dev/vcs'+str(i),'rb') tty = open('/sys/devices/virtual/tty/tty0/active','r') currScreen = str(tty.read()[3:-1]) oldScreen = currScreen watchdog = select.epoll() watchdog.register(vcsa[currScreen], select.EPOLLPRI) watchdog.register(tty, select.EPOLLPRI) while True: changes = watchdog.poll() print('-----------------------------') print(changes) for change in changes: fileno = change[0] event = change[1] print(change,fileno, tty.fileno()) if fileno == tty.fileno(): tty.seek(0) currScreen = str(tty.read()[3:-1]) if currScreen != oldScreen: watchdog.unregister(vcsa[ oldScreen ]) watchdog.register(vcsa[ currScreen ], select.EPOLLPRI) oldScreen = currScreen print('new screen '+ currScreen) else: vcsa[currScreen].seek(0) content = vcsa[currScreen].read() print('update '+ str(time.time())) fenrir-1.5.1/play zone/errorOnBrokenDevice.py000077500000000000000000000001771317357605400212100ustar00rootroot00000000000000#!/bin/python # in case that event13 is still the broken device f = open('/dev/input/event13') print('OK /dev/input/event13') fenrir-1.5.1/play zone/fg.sh000077500000000000000000000025241317357605400156550ustar00rootroot00000000000000#!/bin/bash echo "foreground colors" echo -e "\e[39mDefault" echo -e "\e[30mBlack" echo -e "\e[31mRed" echo -e "\e[32mGreen" echo -e "\e[33mYellow" echo -e "\e[34mBlue" echo -e "\e[35mMagenta" echo -e "\e[36mCyan" echo -e "\e[37mLight gray" echo -e "\e[90mDark gray" echo -e "\e[91mLight red" echo -e "\e[92mLight green" echo -e "\e[93mLight yellow" echo -e "\e[94mLight blue" echo -e "\e[95mLight magenta" echo -e "\e[96mLight cyan" echo -e "\e[97mWhite" #7: _('Default'), 0: _('Black'), 4: _('Red'), 2: _('Green'), 6: _('Yellow'), 1: _('Blue'), 5: _('Magenta'), 3: _('Cyan'), 7: _('Light gray'), 8: _('Dark gray'), 12: _('Light red'), 10: , ('Light green'), 14: _('Light yellow'), 9: _('Light blue'), 13: _('Light magenta'), 11: _('Light cyan'), 15: _('White') echo "background colors" echo -e "\e[49mDefault" echo -e "\e[40mBlack" echo -e "\e[41mRed" echo -e "\e[42mGreen" echo -e "\e[43mYellow" echo -e "\e[44mBlue" echo -e "\e[45mMagenta" echo -e "\e[46mCyan" echo -e "\e[47mLight gray" echo -e "\e[100mDark gray" echo -e "\e[101mLight red" echo -e "\e[102mLight green" echo -e "\e[103mLight yellow" echo -e "\e[104mLight blue" echo -e "\e[105mLight magenta" echo -e "\e[106mLight cyan" echo -e "\e[107mWhite" echo "format" echo -e "\e[1mBold" echo -e "\e[2mDim" echo -e "\e[4mUnderlined" echo -e "\e[5mBlink" echo -e "\e[7minverted" echo -e "\e[8mHidden" fenrir-1.5.1/play zone/listDevices.py000077500000000000000000000013521317357605400175530ustar00rootroot00000000000000#!/bin/python import evdev from evdev import InputDevice, UInput from select import select import time iDevices = map(evdev.InputDevice, (evdev.list_devices())) iDevices = {dev.fd: dev for dev in iDevices} print('----------------------') for fd in iDevices: dev = iDevices[fd] cap = dev.capabilities() print('Name: ' + str(dev.name)) print('LEDs: ' + str(dev.leds())) print('Has Keys: '+ str(evdev.events.EV_KEY in cap)) if evdev.events.EV_KEY in cap: print('No. of keys: ' + str(len(cap[evdev.events.EV_KEY]))) print('has Key 116: ' + str(116 in cap[evdev.events.EV_KEY])) print('Is Mouse: ' + str(((evdev.events.EV_REL in cap) or (evdev.events.EV_ABS in cap)))) print('----------------------') fenrir-1.5.1/play zone/marytts.py000077500000000000000000000065461317357605400170120ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # HTTP + URL packages import httplib2 from urllib.parse import urlencode, quote # For URL creation import time # To play wave files import pygame import math # For ceiling # Mary server informations mary_host = "127.0.0.1" mary_port = "59125" # Input text input_text = "das ist ein test das ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testd" # Build the query query_hash = {"INPUT_TEXT":input_text, "INPUT_TYPE":"TEXT", # Input text "LOCALE":"de", "VOICE":"bits3", # Voice informations (need to be compatible) "OUTPUT_TYPE":"AUDIO", "AUDIO":"WAVE", # Audio informations (need both) } starttime = time.time() query = urlencode(query_hash) #print("query = \"http://%s:%s/process?%s\"" % (mary_host, mary_port, query)) # Run the query to mary http server h_mary = httplib2.Http() #print("http://%s:%s/process?" % (mary_host, mary_port), "POST", query) resp, content = h_mary.request("http://%s:%s/process?" % (mary_host, mary_port), "POST", query) # Decode the wav file or raise an exception if no wav files if (resp["content-type"] == "audio/x-wav"): # Write the wav file f = open("/tmp/output_wav.wav", "wb") f.write(content) f.close() # Play the wav file pygame.mixer.init(frequency=16000) # Initialise the mixer #s = pygame.mixer.Sound(content) s = pygame.mixer.Sound("/tmp/output_wav.wav") print(str(time.time() -starttime)) s.play() print(str(time.time() -starttime)) pygame.time.wait(int(math.ceil(s.get_length() * 1000))) else: raise Exception(content) fenrir-1.5.1/play zone/parseProcessTree.py000077500000000000000000000034111317357605400205640ustar00rootroot00000000000000#!/bin/python import os import time start = time.time() pids = [pid for pid in os.listdir('/proc') if pid.isdigit()] #pids = ['5960'] tty = os.open('/dev/tty2', os.O_RDWR) fg = str(os.tcgetpgrp(tty)) tty.close() print(fg) for pid in pids: try: currStat = str(open('/proc/' + pid + '/stat', 'rb').read()) currStat = currStat.split(' ') if int(currStat[4]) == 0: continue #print(currStat) #print(fg,int(currStat[4])) if fg == currStat[4]: print(currStat[1]) #print( currStat ) #print(currStat[0]) major = os.major(int(currStat[6])) minor = os.minor(int(currStat[6])) ueventContent = open('/sys/dev/char/' + str(major) + ':' + str(minor) + '/uevent','r').read().split() #print(ueventContent) #print(int(currStat[4]),currStat[1]) except IOError: # proc has already terminated continue print(time.time()-start) ''' Table 1-4: Contents of the stat files (as of 2.6.30-rc7) .............................................................................. Field Content pid process id tcomm filename of the executable state state (R is running, S is sleeping, D is sleeping in an uninterruptible wait, Z is zombie, T is traced or stopped) ppid process id of the parent process pgrp pgrp of the process sid session id tty_nr tty the process uses tty_pgrp pgrp of the tty flags task flags min_flt number of minor faults cmin_flt number of minor faults with child's maj_flt number of major faults cmaj_flt number of major faults with child's ''' fenrir-1.5.1/play zone/passBrokenDevice.py000077500000000000000000000013731317357605400205270ustar00rootroot00000000000000#!/bin/python import evdev from evdev import InputDevice from select import select import time deviceList = evdev.list_devices() readableDevices = [] for dev in deviceList: try: open(dev) readableDevices.append(dev) print('OK '+dev) except Exception as e: print('skip ' + dev + ' Error ' + str(e)) devices = map(evdev.InputDevice, (readableDevices)) devices = {dev.fd: dev for dev in devices} while True: r, w, x = select(devices, [], []) if r != []: for fd in r: for event in devices[fd].read(): print('Devicename:'+ devices[fd].name + ' Devicepath:' + devices[fd].fn + ' Events:' + str(devices[fd].active_keys(verbose=True)) + ' Value:' + str(event.value)) fenrir-1.5.1/play zone/print_escape.py000066400000000000000000000021531317357605400177460ustar00rootroot00000000000000#!/bin/python3 import sys, os import pty import pyte class FenrirTermStream(pyte.Stream): def __init__(self): super().__init__() def attach(self, screen): super().attach(screen) def feed(self, text): super().feed(text) class FenrirTermEmu(): def __init__(self): self.shell = '/bin/bash' if 'SHELL' in os.environ: self.shell = os.environ['SHELL'] self.screen = pyte.Screen(80,24) self.stream = FenrirTermStream() self.stream.attach(self.screen) def outputCallback(self, fd): data = os.read(fd, 1024) self.stream.feed(data.decode('UTF8')) # alles #print(self.screen.display) # input #print(data.decode('UTF8')) return data def inputCallback(self, fd): data = os.read(fd, 1024) print('|'+str(data)+'|') if data == b'q': print('quit') return b'exit\r' return data def startEmulator(self): pty.spawn(self.shell, self.outputCallback, self.inputCallback) t = FenrirTermEmu() t.startEmulator() fenrir-1.5.1/play zone/pyterm.py000077500000000000000000000017071317357605400166210ustar00rootroot00000000000000#!/bin/python3 import sys, os import pty import pyte class FenrirTermStream(pyte.Stream): def __init__(self): super().__init__() def attach(self, screen): super().attach(screen) def feed(self, text): super().feed(text) class FenrirTermEmu(): def __init__(self): self.shell = '/bin/bash' if 'SHELL' in os.environ: self.shell = os.environ['SHELL'] self.screen = pyte.Screen(80,24) self.stream = FenrirTermStream() self.stream.attach(self.screen) def outputCallback(self, fd): data = os.read(fd, 1024) self.stream.feed(data.decode('UTF8')) # alles print(self.screen.display) # input print(data.decode('UTF8')) return data def inputCallback(self, fd): data = os.read(fd, 1024) return data def startEmulator(self): pty.spawn(self.shell, self.outputCallback, self.inputCallback) fenrir-1.5.1/play zone/terminalManagement000066400000000000000000000074111317357605400204550ustar00rootroot00000000000000import os import struct import sys import pty import tty import termios import shlex import signal import select import pyte import time class Terminal: def __init__(self, columns, lines, p_in): self.screen = pyte.HistoryScreen(columns, lines) self.screen.set_mode(pyte.modes.LNM) self.screen.write_process_input = \ lambda data: p_in.write(data.encode()) self.stream = pyte.ByteStream() self.stream.attach(self.screen) def feed(self, data): self.stream.feed(data) def dump(self): cursor = self.screen.cursor lines = [] for y in self.screen.dirty: line = self.screen.buffer[y] data = [(char.data, char.reverse, char.fg, char.bg) for char in (line[x] for x in range(self.screen.columns))] lines.append((y, data)) self.screen.dirty.clear() return {"c": (cursor.x, cursor.y), "lines": lines} def open_terminal(command="bash", columns=80, lines=24): p_pid, master_fd = pty.fork() if p_pid == 0: # Child. argv = shlex.split(command) env = os.environ.copy() env["TERM"] = 'vt100' os.execvpe(argv[0], argv, env) # File-like object for I/O with the child process aka command. p_out = os.fdopen(master_fd, "w+b", 0) return Terminal(columns, lines, p_out), p_pid, p_out def HandleTerminal(): debug = False running = True try: old_attr = termios.tcgetattr(sys.stdin) tty.setraw(0) terminal, p_pid, p_out = open_terminal() std_out = os.fdopen(sys.stdout.fileno(), "w+b", 0) while running: r, w, x = select.select([sys.stdin, p_out],[],[]) if r == []: continue if p_out in r: if debug: print('pre p_out') try: msgBytes = read_all(p_out.fileno()) except (EOFError, OSError): running = False break terminal.feed(msgBytes) os.write(sys.stdout.fileno(), msgBytes) if debug: print('after p_out') if sys.stdin in r: if debug: print('pre stdin') try: msgBytes = read_all(sys.stdin.fileno()) except (EOFError, OSError): running = False break terminal.feed(msgBytes) os.write(p_out.fileno(), msgBytes) if debug: print('after stdin') except Exception as e: # Process died? print(e) running = False finally: os.kill(p_pid, signal.SIGTERM) p_out.close() termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_attr) sys.exit(0) def get_terminal_size(fd): s = struct.pack('HHHH', 0, 0, 0, 0) rows, cols, _, _ = struct.unpack('HHHH', fcntl.ioctl(fd, termios.TIOCGWINSZ, s)) return rows, cols def resize_terminal(fd): s = struct.pack('HHHH', 0, 0, 0, 0) s = fcntl.ioctl(0, termios.TIOCGWINSZ, s) fcntl.ioctl(fd, termios.TIOCSWINSZ, s) rows, cols, _, _ = struct.unpack('hhhh', s) return rows, cols def read_all(fd): bytes = os.read(fd, 65536) if bytes == b'': raise EOFError while has_more(fd): data = os.read(fd, 65536) if data == b'': raise EOFError bytes += data return bytes def has_more(fd): r, w, e = select.select([fd], [], [], 0) return (fd in r) if __name__ == "__main__": HandleTerminal() fenrir-1.5.1/play zone/vcsa.py000077500000000000000000000041461317357605400162350ustar00rootroot00000000000000#!/usr/bin/python from cairo import * from fcntl import ioctl from array import array import struct import errno import sys GIO_UNIMAP = 0x4B66 VT_GETHIFONTMASK = 0x560D if len(sys.argv) != 3: print "Usage: %s " % sys.argv[0] exit() ttyno = int(sys.argv[1]) png = sys.argv[2] tty = open('/dev/tty%d' % ttyno, 'rb') himask = array("H", (0,)) ioctl(tty, VT_GETHIFONTMASK, himask) hichar, = struct.unpack_from("@H", himask) sz = 512 while True: try: unipairs = array("H", [0]*(2*sz)) unimapdesc = array("B", struct.pack("@HP", sz, unipairs.buffer_info()[0])) ioctl(tty.fileno(), GIO_UNIMAP, unimapdesc) break except IOError as e: if e.errno != errno.ENOMEM: raise sz *= 2 tty.close() ncodes, = struct.unpack_from("@H", unimapdesc) utable = struct.unpack_from("@%dH" % (2*ncodes), unipairs) charmap = {} for u, b in zip(utable[::2], utable[1::2]): if charmap.get(b) is None: charmap[b] = unichr(u) vcs = open('/dev/vcsa%d' % ttyno, 'rb') head = vcs.read(4) rows = ord(head[0]) cols = ord(head[1]) caretX = ord(head[2]) caretY = ord(head[3]) surf = ImageSurface(FORMAT_RGB24, cols * 8, rows * 16) cr = Context(surf) cr.set_source_rgb(1,1,1) cr.set_font_face(ToyFontFace("Mono", FONT_SLANT_NORMAL, FONT_WEIGHT_NORMAL)); m = Matrix() m.scale(10.0, 12.0) cr.set_font_matrix(m) def CairoColor(b, a): return (b if a & 4 else 0, b if a & 2 else 0, b if a & 1 else 0) for y in range(rows): for x in range(cols): data = vcs.read(2) (sh,) = struct.unpack("=H", data) attr = (sh >> 8) & 0xFF ch = sh & 0xFF if hichar == 0x100: attr >>= 1 ink = attr & 0x0F paper = (attr>>4) & 0x0F b = 1.0 if attr & 0x80 else 0.75 if sh & hichar: ch |= 0x100 cr.set_source_rgb(*CairoColor(b, paper)) cr.rectangle(x*8, y*16, 8, 16) cr.fill() cr.set_source_rgb(*CairoColor(b, ink)) cr.move_to(x*8, 12 + y*16) cr.show_text(charmap.get(ch, u'?')) cr.stroke() vcs.close() surf.write_to_png(png) fenrir-1.5.1/play zone/wrapWord.py000077500000000000000000000105671317357605400171120ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. #from core import debug import string # X Y Word END BREAK # -1, -1, '', True False def getPrevWord(currX,currY, currText): lineBreak = False endOfScreen = False if currText == '': return -1, -1, '', endOfScreen, lineBreak if currText.strip( string.whitespace) == '': return currX, currY, '', endOfScreen, lineBreak x, y, currWord, endOfScreen, lineBreakCurrWord = getCurrentWord(currX,currY,currText) if endOfScreen: return x, y, currWord, endOfScreen, lineBreak wrappedLines = currText.split('\n') currLine = wrappedLines[y] if x - 1 < 0: if y - 1 < 0: lineBreak = False endOfScreen = True return currX, currY, '', endOfScreen, lineBreak else: y -= 1 currLine = wrappedLines[y] x = len( wrappedLines[y]) - 1 lineBreak = True else: x -= 1 lineBreakCurrWord = lineBreak or lineBreakCurrWord x, y, currWord, endOfScreen, lineBreak = getCurrentWord(x,y,currText) lineBreak = lineBreak or lineBreakCurrWord return x, y, currWord, endOfScreen, lineBreak def getCurrentWord(currX,currY, currText): lineBreak = False endOfScreen = False if currText == '': return -1, -1, '', endOfScreen, lineBreak if currText.strip( string.whitespace) == '': return currX, currY, '', endOfScreen, lineBreak x = currX y = currY currWord = '' wrappedLines = currText.split('\n') currLine = wrappedLines[y] Found = False while(not Found): if not currLine[x] in string.whitespace: if x == 0: Found = True else: if currLine[x - 1] in string.whitespace: Found = True if not Found: if x - 1 < 0: if y - 1 < 0: lineBreak = False endOfScreen = True return currX, currY, '', endOfScreen, lineBreak else: y -= 1 currLine = wrappedLines[y] x = len( wrappedLines[y]) - 1 lineBreak = True else: x -= 1 if Found: currWord = currLine[x:] for d in string.whitespace: delimiterPos = currWord.find(d) if delimiterPos != -1: currWord = currWord[:delimiterPos] return x, y, currWord, endOfScreen, lineBreak return currX, currY, '', False, False def getNextWord(currX,currY, currText): lineBreak = False endOfScreen = False if currText == '': return -1, -1, '', endOfScreen, lineBreak if currText.strip( string.whitespace) == '': return currX, currY, '', endOfScreen, lineBreak x = currX y = currY currWord = '' wrappedLines = currText.split('\n') currLine = wrappedLines[y] Found = False while(not Found): if not Found: if x + 1 > len( currLine ) - 1: if y + 1 > len( wrappedLines ) - 1: lineBreak = False endOfScreen = True return currX, currY, '', endOfScreen, lineBreak else: y += 1 currLine = wrappedLines[y] x = 0 lineBreak = True else: x += 1 if not currLine[x] in string.whitespace: if x == 0: Found = True else: if currLine[x - 1] in string.whitespace: Found = True if Found: currWord = currLine[x:] for d in string.whitespace: delimiterPos = currWord.find(d) if delimiterPos != -1: currWord = currWord[:delimiterPos] return x, y, currWord, endOfScreen, lineBreak return currX, currY, '', False, False data = """das ist ein test lol das ist ein test l das ist ein test asdf asdf a test test te test""" print('__DATA START__') print(data) print('__DATA END__\n\n') x = 3 y = 0 x, y, currWord, endOfScreen, lineBreak = getCurrentWord(x,y,data) print(x,y,currWord) fenrir-1.5.1/play zone/writeBrl.py000077500000000000000000000005421317357605400170670ustar00rootroot00000000000000#!/bin/python import brlapi import time brl = brlapi.Connection() brl.enterTtyModeWithPath() print('display size' + str(brl.displaySize)) print('driver name'+str(brl.driverName)) t = time.time() #while(time.time() - t <= 5): try: brl.writeText( 'this is a 5 second test') except Exception as e: print(e) time.sleep(5) brl.leaveTtyMode() fenrir-1.5.1/setup.py000077500000000000000000000105071317357605400145360ustar00rootroot00000000000000#!/bin/python #https://python-packaging.readthedocs.io/en/latest/minimal.html import os, glob, sys import os.path from shutil import copyfile from setuptools import find_packages from setuptools import setup fenrirVersion = '1.5' packageVersion = 'post10' # handle flags for package manager like yaourt and pacaur. forceSettings = False if "--force-settings" in sys.argv: forceSettings = True sys.argv.remove("--force-settings") data_files = [] directories = glob.glob('config/*') for directory in directories: files = glob.glob(directory+'/*') destDir = '' if 'config/punctuation' in directory : destDir = '/etc/fenrir/punctuation' elif 'config/keyboard' in directory: destDir = '/etc/fenrir/keyboard' elif 'config/settings' in directory: destDir = '/etc/fenrir/settings' if not forceSettings: try: del(files[files.index('config/settings/settings.conf')]) except: pass elif 'config/scripts' in directory: destDir = '/usr/share/fenrir/scripts' if destDir != '': data_files.append((destDir, files)) files = glob.glob('config/sound/default-wav/*') destDir = '/usr/share/sounds/fenrir/default-wav' data_files.append((destDir, files)) files = glob.glob('config/sound/default/*') destDir = '/usr/share/sounds/fenrir/default' data_files.append((destDir, files)) files = glob.glob('config/sound//template/*') destDir = '/usr/share/sounds/fenrir/template' data_files.append((destDir, files)) files = glob.glob('tools/*') data_files.append(('/usr/share/fenrir/tools', files)) data_files.append(('/usr/lib/systemd/system', ['autostart/systemd/fenrir.service'])) data_files.append(('/usr/share/man/man1', ['docu/fenrir.1'])) def read(fname): return open(os.path.join(os.path.dirname(__file__), fname)).read() setup( # Application name: name="fenrir-screenreader", # Version number: version=fenrirVersion + '.' + packageVersion, # description description="A TTY Screen Reader for Linux.", long_description=read('README.md'), keywords=['screenreader', 'a11y', 'accessibility', 'terminal', 'TTY', 'console'], license="License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", url="https://github.com/chrys87/fenrir/", download_url = 'https://github.com/chrys87/fenrir/archive/' + fenrirVersion + '.tar.gz', classifiers=[ "Programming Language :: Python", "License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)", "Development Status :: 5 - Production/Stable", "Topic :: Multimedia :: Sound/Audio :: Speech", "Environment :: Console", ], # Application author details: author="Chrys, Storm_dragon, Jeremiah and others", author_email="chrysg@linux-a11y.org", # Packages packages=find_packages('src/fenrir'), package_dir={'': 'src/fenrir'}, scripts=['src/fenrir/fenrir','src/fenrir/fenrir-daemon'], # Include additional files into the package include_package_data=True, zip_safe=False, data_files=data_files, # Dependent packages (distributions) install_requires=[ "evdev", "daemonize", "dbus-python", "pyenchant", "pyudev", "setuptools", "pexpect", ], ) if not forceSettings: print('') # create settings file from example if not exist if not os.path.isfile('/etc/fenrir/settings/settings.conf'): try: copyfile('/etc/fenrir/settings/settings.conf.example', '/etc/fenrir/settings/settings.conf') print('create settings file in /etc/fenrir/settings/settings.conf') except: pass else: print('settings.conf file found. It is not overwritten automatical') print('') print('To have Fenrir start at boot:') print('sudo systemctl enable fenrir') print('Pulseaudio users may want to run:') print('/usr/share/fenrir/tools/configure_pulse.sh') print('once as their user account and once as root to configure Pulseaudio.') print('Please install the following packages manually:') print('- Speech-dispatcher: for the default speech driver') print('- Espeak: as basic TTS engine') print('- BrlTTY: for Braille') print('- sox: is a player for the generic sound driver') fenrir-1.5.1/src/000077500000000000000000000000001317357605400136055ustar00rootroot00000000000000fenrir-1.5.1/src/__init__.py000077500000000000000000000000001317357605400157070ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/000077500000000000000000000000001317357605400150725ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/__init__.py000077500000000000000000000000001317357605400171740ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/brailleDriver/000077500000000000000000000000001317357605400176605ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/brailleDriver/__init__.py000077500000000000000000000000001317357605400217620ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/brailleDriver/brlapiDriver.py000066400000000000000000000035401317357605400226610ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class driver(): def __init__(self): self._isInitialized = False self._brl = None def initialize(self, environment): self.env = environment try: import brlapi self._brl = brlapi.Connection() self._deviceSize = self._brl.displaySize except Exception as e: print(e) self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) return self._isInitialized = True def getDeviceSize(self): if not self._isInitialized: return (0,0) if not self._deviceSize: return (0,0) return self._deviceSize def flush(self): if not self._isInitialized: return try: self._brl.writeText('',0) except Exception as e: self.env['runtime']['debug'].writeDebugOut('BRAILLE.flush '+str(e),debug.debugLevel.ERROR) def writeText(self,text): if not self._isInitialized: return try: self._brl.writeText(text) except Exception as e: self.env['runtime']['debug'].writeDebugOut('BRAILLE.writeText '+str(e),debug.debugLevel.ERROR) def connectDevice(self): self._brl = brlapi.Connection() def enterScreen(self, screen): if not self._isInitialized: return self._brl.enterTtyMode(int(screen)) def leveScreen(self): if not self._isInitialized: return self._brl.leaveTtyMode() def shutdown(self): if not self._isInitialized: return self.leveScreen() fenrir-1.5.1/src/fenrir/brailleDriver/dummyDriver.py000066400000000000000000000030141317357605400225370ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class driver(): def __init__(self): self.printMessages = False def initialize(self, environment): self.env = environment self._isInitialized = True self.deviceSize = (40,0) if self.printMessages: print('BrailleDummyDriver: Initialize') def getDeviceSize(self): if not self._isInitialized: return (0,0) if self.printMessages: print('BrailleDummyDriver: getDeviceSize ' + str(self.deviceSize)) return self.deviceSize def writeText(self,text): if not self._isInitialized: return if self.printMessages: print('BrailleDummyDriver: writeText:' + str(text)) print('BrailleDummyDriver: -----------------------------------') def connectDevice(self): if self.printMessages: print('BrailleDummyDriver: connectDevice') def enterScreen(self, screen): if not self._isInitialized: return if self.printMessages: print('BrailleDummyDriver: enterScreen') def leveScreen(self): if not self._isInitialized: return if self.printMessages: print('BrailleDummyDriver: leveScreen') def shutdown(self): if not self._isInitialized: return if self.printMessages: print('BrailleDummyDriver: Shutdown') fenrir-1.5.1/src/fenrir/commands/000077500000000000000000000000001317357605400166735ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/commands/__init__.py000077500000000000000000000000001317357605400207750ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/commands/command_template.py000066400000000000000000000007341317357605400225620ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return 'No description found' def run(self): pass def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/000077500000000000000000000000001317357605400204745ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/commands/commands/__init__.py000077500000000000000000000000001317357605400225760ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/commands/commands/add_word_to_spell_check.py000066400000000000000000000042561317357605400256760ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import word_utils import string initialized = False try: import enchant initialized = True except: pass class command(): def __init__(self): self.language = '' self.spellChecker = None def initialize(self, environment): self.env = environment self.updateSpellLanguage() def shutdown(self): pass def getDescription(self): return _('adds the current word to the exceptions dictionary') def updateSpellLanguage(self): self.spellChecker = enchant.Dict(self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage')) self.language = self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage') def run(self): if not initialized: self.env['runtime']['outputManager'].presentText(_('pyenchant is not installed'), interrupt=True) return if self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage') != self.language: try: self.updateSpellLanguage() except Exception as e: return cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() # get the word newContent = self.env['screen']['newContentText'].split('\n')[cursorPos['y']] x, y, currWord, endOfScreen, lineBreak = word_utils.getCurrentWord(cursorPos['x'], 0, newContent) currWord = currWord.strip(string.whitespace + '!"#$%&\()*+,-./:;<=§>?@[\\]^_{|}~') if currWord != '': if self.spellChecker.is_added(currWord): self.env['runtime']['outputManager'].presentText(_('{0} is already in dict').format(currWord,), soundIcon='Cancel', interrupt=True) else: self.spellChecker.add(currWord) self.env['runtime']['outputManager'].presentText(_('{0} added').format(currWord,), soundIcon='Accept', interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/attribute_cursor.py000066400000000000000000000021261317357605400244470ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import screen_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return 'No description found' def run(self): cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() attributes = screen_utils.splitEvery(self.env['screen']['newContentAttrib'], self.env['screen']['columns']) attributes = attributes[cursorPos['y']][cursorPos['x']] attributeFormatString = self.env['runtime']['settingsManager'].getSetting('general', 'attributeFormatString') attributeFormatString = self.env['runtime']['screenManager'].formatAttributes(attributes, attributeFormatString) self.env['runtime']['outputManager'].presentText(attributeFormatString, soundIcon='', interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/bookmark_1.py000066400000000000000000000040251317357605400230740ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import mark_utils from utils import line_utils class command(): def __init__(self): self.ID = '1' def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('read Bookmark {0}').format(self.ID,) def run(self): currApp = self.env['runtime']['applicationManager'].getCurrentApplication() if not self.env['commandBuffer']['bookMarks'][self.ID]: self.env['runtime']['outputManager'].presentText(_('Bookmark {0} not set').format(self.ID,), interrupt=True) return if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]: self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True) return if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1']: self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True) return # set marks marked = '' startMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'].copy() if self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2']: endMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'].copy() marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screen']['newContentText']) else: x, y, marked = \ line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screen']['newContentText']) if marked.isspace(): self.env['runtime']['outputManager'].presentText(_('blank'), soundIcon='EmptyLine', interrupt=True) else: self.env['runtime']['outputManager'].presentText(marked, interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/bookmark_10.py000066400000000000000000000040261317357605400231550ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import mark_utils from utils import line_utils class command(): def __init__(self): self.ID = '10' def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('read Bookmark {0}').format(self.ID,) def run(self): currApp = self.env['runtime']['applicationManager'].getCurrentApplication() if not self.env['commandBuffer']['bookMarks'][self.ID]: self.env['runtime']['outputManager'].presentText(_('Bookmark {0} not set').format(self.ID,), interrupt=True) return if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]: self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True) return if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1']: self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True) return # set marks marked = '' startMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'].copy() if self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2']: endMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'].copy() marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screen']['newContentText']) else: x, y, marked = \ line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screen']['newContentText']) if marked.isspace(): self.env['runtime']['outputManager'].presentText(_('blank'), soundIcon='EmptyLine', interrupt=True) else: self.env['runtime']['outputManager'].presentText(marked, interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/bookmark_2.py000066400000000000000000000040251317357605400230750ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import mark_utils from utils import line_utils class command(): def __init__(self): self.ID = '2' def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('read Bookmark {0}').format(self.ID,) def run(self): currApp = self.env['runtime']['applicationManager'].getCurrentApplication() if not self.env['commandBuffer']['bookMarks'][self.ID]: self.env['runtime']['outputManager'].presentText(_('Bookmark {0} not set').format(self.ID,), interrupt=True) return if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]: self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True) return if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1']: self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True) return # set marks marked = '' startMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'].copy() if self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2']: endMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'].copy() marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screen']['newContentText']) else: x, y, marked = \ line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screen']['newContentText']) if marked.isspace(): self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True) else: self.env['runtime']['outputManager'].presentText(marked, interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/bookmark_3.py000066400000000000000000000040251317357605400230760ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import mark_utils from utils import line_utils class command(): def __init__(self): self.ID = '3' def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('read Bookmark {0}').format(self.ID,) def run(self): currApp = self.env['runtime']['applicationManager'].getCurrentApplication() if not self.env['commandBuffer']['bookMarks'][self.ID]: self.env['runtime']['outputManager'].presentText(_('Bookmark {0} not set').format(self.ID,), interrupt=True) return if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]: self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True) return if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1']: self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True) return # set marks marked = '' startMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'].copy() if self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2']: endMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'].copy() marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screen']['newContentText']) else: x, y, marked = \ line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screen']['newContentText']) if marked.isspace(): self.env['runtime']['outputManager'].presentText(_('blank'), soundIcon='EmptyLine', interrupt=True) else: self.env['runtime']['outputManager'].presentText(marked, interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/bookmark_4.py000066400000000000000000000040251317357605400230770ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import mark_utils from utils import line_utils class command(): def __init__(self): self.ID = '4' def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('read Bookmark {0}').format(self.ID,) def run(self): currApp = self.env['runtime']['applicationManager'].getCurrentApplication() if not self.env['commandBuffer']['bookMarks'][self.ID]: self.env['runtime']['outputManager'].presentText(_('Bookmark {0} not set').format(self.ID,), interrupt=True) return if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]: self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True) return if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1']: self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True) return # set marks marked = '' startMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'].copy() if self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2']: endMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'].copy() marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screen']['newContentText']) else: x, y, marked = \ line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screen']['newContentText']) if marked.isspace(): self.env['runtime']['outputManager'].presentText(_('blank'), soundIcon='EmptyLine', interrupt=True) else: self.env['runtime']['outputManager'].presentText(marked, interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/bookmark_5.py000066400000000000000000000040251317357605400231000ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import mark_utils from utils import line_utils class command(): def __init__(self): self.ID = '5' def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('read Bookmark {0}').format(self.ID,) def run(self): currApp = self.env['runtime']['applicationManager'].getCurrentApplication() if not self.env['commandBuffer']['bookMarks'][self.ID]: self.env['runtime']['outputManager'].presentText(_('Bookmark {0} not set').format(self.ID,), interrupt=True) return if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]: self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True) return if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1']: self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True) return # set marks marked = '' startMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'].copy() if self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2']: endMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'].copy() marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screen']['newContentText']) else: x, y, marked = \ line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screen']['newContentText']) if marked.isspace(): self.env['runtime']['outputManager'].presentText(_('blank'), soundIcon='EmptyLine', interrupt=True) else: self.env['runtime']['outputManager'].presentText(marked, interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/bookmark_6.py000066400000000000000000000040251317357605400231010ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import mark_utils from utils import line_utils class command(): def __init__(self): self.ID = '6' def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('read Bookmark {0}').format(self.ID,) def run(self): currApp = self.env['runtime']['applicationManager'].getCurrentApplication() if not self.env['commandBuffer']['bookMarks'][self.ID]: self.env['runtime']['outputManager'].presentText(_('Bookmark {0} not set').format(self.ID,), interrupt=True) return if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]: self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True) return if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1']: self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True) return # set marks marked = '' startMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'].copy() if self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2']: endMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'].copy() marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screen']['newContentText']) else: x, y, marked = \ line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screen']['newContentText']) if marked.isspace(): self.env['runtime']['outputManager'].presentText(_('blank'), soundIcon='EmptyLine', interrupt=True) else: self.env['runtime']['outputManager'].presentText(marked, interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/bookmark_7.py000066400000000000000000000040251317357605400231020ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import mark_utils from utils import line_utils class command(): def __init__(self): self.ID = '7' def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('read Bookmark {0}').format(self.ID,) def run(self): currApp = self.env['runtime']['applicationManager'].getCurrentApplication() if not self.env['commandBuffer']['bookMarks'][self.ID]: self.env['runtime']['outputManager'].presentText(_('Bookmark {0} not set').format(self.ID,), interrupt=True) return if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]: self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True) return if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1']: self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True) return # set marks marked = '' startMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'].copy() if self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2']: endMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'].copy() marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screen']['newContentText']) else: x, y, marked = \ line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screen']['newContentText']) if marked.isspace(): self.env['runtime']['outputManager'].presentText(_('blank'), soundIcon='EmptyLine', interrupt=True) else: self.env['runtime']['outputManager'].presentText(marked, interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/bookmark_8.py000066400000000000000000000040251317357605400231030ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import mark_utils from utils import line_utils class command(): def __init__(self): self.ID = '8' def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('read Bookmark {0}').format(self.ID,) def run(self): currApp = self.env['runtime']['applicationManager'].getCurrentApplication() if not self.env['commandBuffer']['bookMarks'][self.ID]: self.env['runtime']['outputManager'].presentText(_('Bookmark {0} not set').format(self.ID,), interrupt=True) return if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]: self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True) return if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1']: self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True) return # set marks marked = '' startMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'].copy() if self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2']: endMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'].copy() marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screen']['newContentText']) else: x, y, marked = \ line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screen']['newContentText']) if marked.isspace(): self.env['runtime']['outputManager'].presentText(_('blank'), soundIcon='EmptyLine', interrupt=True) else: self.env['runtime']['outputManager'].presentText(marked, interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/bookmark_9.py000066400000000000000000000040251317357605400231040ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import mark_utils from utils import line_utils class command(): def __init__(self): self.ID = '9' def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('read Bookmark {0}').format(self.ID,) def run(self): currApp = self.env['runtime']['applicationManager'].getCurrentApplication() if not self.env['commandBuffer']['bookMarks'][self.ID]: self.env['runtime']['outputManager'].presentText(_('Bookmark {0} not set').format(self.ID,), interrupt=True) return if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]: self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True) return if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1']: self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True) return # set marks marked = '' startMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'].copy() if self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2']: endMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'].copy() marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screen']['newContentText']) else: x, y, marked = \ line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screen']['newContentText']) if marked.isspace(): self.env['runtime']['outputManager'].presentText(_('blank'), soundIcon='EmptyLine', interrupt=True) else: self.env['runtime']['outputManager'].presentText(marked, interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/braille_flush.py000066400000000000000000000010471317357605400236630ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('flush the braille device if a message is written on') def run(self): self.env['runtime']['outputManager'].clearFlushTime() def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/braille_pan_left.py000066400000000000000000000010371317357605400243310ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('Move braille view to the left.') def run(self): panned = self.env['runtime']['outputManager'].setPanLeft() def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/braille_pan_right.py000066400000000000000000000010411317357605400245070ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('Move braille view to the right.') def run(self): panned = self.env['runtime']['outputManager'].setPanRight() def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/braille_return_to_cursor.py000066400000000000000000000010371317357605400261570ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('Set the braille view back to cursor.') def run(self): self.env['runtime']['outputManager'].removePanning() def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/clear_bookmark_1.py000066400000000000000000000014101317357605400242350ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): self.ID = '1' def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('remove Bookmark {0}').format(self.ID,) def run(self): currApp = self.env['runtime']['applicationManager'].getCurrentApplication() del self.env['commandBuffer']['bookMarks'][self.ID][currApp] self.env['runtime']['outputManager'].presentText(_('Bookmark {0} removed for application {1}').format(self.ID, currApp), interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/clear_bookmark_10.py000066400000000000000000000014111317357605400243160ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): self.ID = '10' def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('remove Bookmark {0}').format(self.ID,) def run(self): currApp = self.env['runtime']['applicationManager'].getCurrentApplication() del self.env['commandBuffer']['bookMarks'][self.ID][currApp] self.env['runtime']['outputManager'].presentText(_('Bookmark {0} removed for application {1}').format(self.ID, currApp), interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/clear_bookmark_2.py000066400000000000000000000014101317357605400242360ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): self.ID = '2' def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('remove Bookmark {0}').format(self.ID,) def run(self): currApp = self.env['runtime']['applicationManager'].getCurrentApplication() del self.env['commandBuffer']['bookMarks'][self.ID][currApp] self.env['runtime']['outputManager'].presentText(_('Bookmark {0} removed for application {1}').format(self.ID, currApp), interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/clear_bookmark_3.py000066400000000000000000000014101317357605400242370ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): self.ID = '3' def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('remove Bookmark {0}').format(self.ID,) def run(self): currApp = self.env['runtime']['applicationManager'].getCurrentApplication() del self.env['commandBuffer']['bookMarks'][self.ID][currApp] self.env['runtime']['outputManager'].presentText(_('Bookmark {0} removed for application {1}').format(self.ID, currApp), interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/clear_bookmark_4.py000066400000000000000000000014101317357605400242400ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): self.ID = '4' def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('remove Bookmark {0}').format(self.ID,) def run(self): currApp = self.env['runtime']['applicationManager'].getCurrentApplication() del self.env['commandBuffer']['bookMarks'][self.ID][currApp] self.env['runtime']['outputManager'].presentText(_('Bookmark {0} removed for application {1}').format(self.ID, currApp), interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/clear_bookmark_5.py000066400000000000000000000014101317357605400242410ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): self.ID = '5' def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('remove Bookmark {0}').format(self.ID,) def run(self): currApp = self.env['runtime']['applicationManager'].getCurrentApplication() del self.env['commandBuffer']['bookMarks'][self.ID][currApp] self.env['runtime']['outputManager'].presentText(_('Bookmark {0} removed for application {1}').format(self.ID, currApp), interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/clear_bookmark_6.py000066400000000000000000000014101317357605400242420ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): self.ID = '6' def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('remove Bookmark {0}').format(self.ID,) def run(self): currApp = self.env['runtime']['applicationManager'].getCurrentApplication() del self.env['commandBuffer']['bookMarks'][self.ID][currApp] self.env['runtime']['outputManager'].presentText(_('Bookmark {0} removed for application {1}').format(self.ID, currApp), interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/clear_bookmark_7.py000066400000000000000000000014101317357605400242430ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): self.ID = '7' def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('remove Bookmark {0}').format(self.ID,) def run(self): currApp = self.env['runtime']['applicationManager'].getCurrentApplication() del self.env['commandBuffer']['bookMarks'][self.ID][currApp] self.env['runtime']['outputManager'].presentText(_('Bookmark {0} removed for application {1}').format(self.ID, currApp), interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/clear_bookmark_8.py000066400000000000000000000014101317357605400242440ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): self.ID = '8' def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('remove Bookmark {0}').format(self.ID,) def run(self): currApp = self.env['runtime']['applicationManager'].getCurrentApplication() del self.env['commandBuffer']['bookMarks'][self.ID][currApp] self.env['runtime']['outputManager'].presentText(_('Bookmark {0} removed for application {1}').format(self.ID, currApp), interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/clear_bookmark_9.py000066400000000000000000000014101317357605400242450ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): self.ID = '9' def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('remove Bookmark {0}').format(self.ID,) def run(self): currApp = self.env['runtime']['applicationManager'].getCurrentApplication() del self.env['commandBuffer']['bookMarks'][self.ID][currApp] self.env['runtime']['outputManager'].presentText(_('Bookmark {0} removed for application {1}').format(self.ID, currApp), interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/clear_clipboard.py000066400000000000000000000013251317357605400241540ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('clears the currently selected clipboard') def run(self): self.env['commandBuffer']['currClipboard'] = -1 del self.env['commandBuffer']['clipboard'][:] self.env['runtime']['outputManager'].presentText(_('clipboard cleared'), interrupt=True) return def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/clear_window_application.py000066400000000000000000000015701317357605400261110ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('Turn off window mode for application') def run(self): if self.env['runtime']['cursorManager'].clearWindowForApplication(): currApp = self.env['runtime']['applicationManager'].getCurrentApplication() self.env['runtime']['outputManager'].presentText(_('Window Mode off for application {0}').format(currApp,), interrupt=True) else: self.env['runtime']['outputManager'].presentText(_("Not in window Mode"), interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/copy_marked_to_clipboard.py000066400000000000000000000030461317357605400260670ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import mark_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('copies marked text to the currently selected clipboard') def run(self): if not self.env['commandBuffer']['Marks']['1']: self.env['runtime']['outputManager'].presentText(_("one or two marks needed"), interrupt=True) return if not self.env['commandBuffer']['Marks']['2']: self.env['runtime']['cursorManager'].setMark() # use the last first and the last setted mark as range startMark = self.env['commandBuffer']['Marks']['1'].copy() endMark = self.env['commandBuffer']['Marks']['2'].copy() marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screen']['newContentText']) self.env['commandBuffer']['clipboard'] = [marked] + self.env['commandBuffer']['clipboard'][:self.env['runtime']['settingsManager'].getSettingAsInt('general', 'numberOfClipboards') -1] self.env['commandBuffer']['currClipboard'] = 0 # reset marks self.env['runtime']['cursorManager'].clearMarks() self.env['runtime']['outputManager'].presentText(marked, soundIcon='CopyToClipboard', interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/curr_clipboard.py000066400000000000000000000015331317357605400240420ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('speaks the contents of the currently selected clipboard') def run(self): if len(self.env['commandBuffer']['clipboard']) == 0: self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True) return self.env['runtime']['outputManager'].presentText(self.env['commandBuffer']['clipboard'][self.env['commandBuffer']['currClipboard']], interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/curr_screen.py000066400000000000000000000014461317357605400233650ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('reads the contents of the current screen') def run(self): if self.env['screen']['newContentText'].isspace(): self.env['runtime']['outputManager'].presentText(_("screen is empty"), soundIcon='EmptyLine', interrupt=True) else: self.env['runtime']['outputManager'].presentText(self.env['screen']['newContentText'],interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/curr_screen_after_cursor.py000066400000000000000000000017451317357605400261450ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import mark_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('reads from the cursor to the bottom of the screen') def run(self): # Prefer review cursor over text cursor cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() textAfterCursor = mark_utils.getTextAfterMark(cursorPos, self.env['screen']['newContentText']) if textAfterCursor.isspace(): self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True) else: self.env['runtime']['outputManager'].presentText(textAfterCursor, interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/curr_screen_before_cursor.py000066400000000000000000000021461317357605400263020ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import mark_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('Reads from the top of the screen to the cursor position') def run(self): # Prefer review cursor over text cursor if self.env['screen']['newCursorReview']: cursorPos = self.env['screen']['newCursorReview'].copy() else: cursorPos = self.env['screen']['newCursor'].copy() textBeforeCursor = mark_utils.getTextBeforeMark(cursorPos, self.env['screen']['newContentText']) if textBeforeCursor.isspace(): self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True) else: self.env['runtime']['outputManager'].presentText(textBeforeCursor, interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/cursor_column.py000066400000000000000000000016121317357605400237400ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('presents the current column number for review cursor in review mode or the text cursor if not. Starts with 1') def run(self): cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() self.env['runtime']['outputManager'].presentText(str(cursorPos['x'] + 1) , interrupt=True) self.env['runtime']['outputManager'].announceActiveCursor() self.env['runtime']['outputManager'].presentText(' column number' , interrupt=False) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/cursor_lineno.py000066400000000000000000000016071317357605400237330ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('presents the current line number for review cursor in review mode or the text cursor if not. Starts with 1') def run(self): cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() self.env['runtime']['outputManager'].presentText(str(cursorPos['y'] + 1), interrupt=True) self.env['runtime']['outputManager'].announceActiveCursor() self.env['runtime']['outputManager'].presentText(' line number' , interrupt=False) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/cursor_position.py000066400000000000000000000013511317357605400243070ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('displays the position of the review cursor') def run(self): # Prefer review cursor over text cursor cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() self.env['runtime']['outputManager'].presentText(_("line {0}, column {1}").format(cursorPos['y']+1, cursorPos['x']+1), interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/cursor_read_to_end_of_line.py000066400000000000000000000021351317357605400264020ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import line_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('read to end of line, use review cursor if you are in review mode, otherwhise use text cursor') def run(self): cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() x, y, currLine = \ line_utils.getCurrentLine(cursorPos['x'], cursorPos['y'], self.env['screen']['newContentText']) if currLine.isspace(): self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True) else: self.env['runtime']['outputManager'].presentText(currLine[cursorPos['x']], interrupt=True) self.env['runtime']['outputManager'].announceActiveCursor() def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/date.py000066400000000000000000000016171317357605400217700ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug import datetime class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('presents the date') def run(self): dateFormat = self.env['runtime']['settingsManager'].getSetting('general', 'dateFormat') # get the time formatted dateString = datetime.datetime.strftime(datetime.datetime.now(), dateFormat) # present the time via speak and braile, there is no soundicon, interrupt the current speech self.env['runtime']['outputManager'].presentText(dateString , soundIcon='', interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/dec_alsa_volume.py000066400000000000000000000017271317357605400241770ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. initialized = False try: import alsaaudio initialized = True except: pass from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _("Decrease system volume") def run(self): if not initialized: self.env['runtime']['outputManager'].presentText(_('alsaaudio is not installed'), interrupt=True) return mixer = alsaaudio.Mixer() value = mixer.getvolume()[0] value = value - 5 if value < 5: value = 5 mixer.setvolume(value) self.env['runtime']['outputManager'].presentText(_("{0} percent system volume").format(value), interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/dec_sound_volume.py000066400000000000000000000016721317357605400244060ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug import math class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('decrease sound volume') def run(self): value = self.env['runtime']['settingsManager'].getSettingAsFloat('sound', 'volume') value = round((math.ceil(10 * value) / 10) - 0.1, 2) if value < 0.1: value = 0.1 self.env['runtime']['settingsManager'].setSetting('sound', 'volume', str(value)) self.env['runtime']['outputManager'].presentText(_("{0} percent sound volume").format(int(value * 100)), soundIcon='SoundOff', interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/dec_speech_pitch.py000066400000000000000000000016571317357605400243300ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug import math class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('decreases the pitch of the speech') def run(self): value = self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'pitch') value = round((math.ceil(10 * value) / 10) - 0.1, 2) if value < 0.0: value = 0.0 self.env['runtime']['settingsManager'].setSetting('speech', 'pitch', str(value)) self.env['runtime']['outputManager'].presentText(_('{0} percent speech pitch').format(int(value * 100)), soundIcon='', interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/dec_speech_rate.py000066400000000000000000000016561317357605400241530ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug import math class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('decreases the rate of the speech') def run(self): value = self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'rate') value = round((math.ceil(10 * value) / 10) - 0.1, 2) if value < 0.0: value = 0.0 self.env['runtime']['settingsManager'].setSetting('speech', 'rate', str(value)) self.env['runtime']['outputManager'].presentText(_("{0} percent speech rate").format(int(value * 100)), soundIcon='', interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/dec_speech_volume.py000066400000000000000000000016671317357605400245310ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug import math class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('decreases the volume of the speech') def run(self): value = self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'volume') value = round((math.ceil(10 * value) / 10) - 0.1, 2) if value < 0.1: value = 0.1 self.env['runtime']['settingsManager'].setSetting('speech', 'volume', str(value)) self.env['runtime']['outputManager'].presentText(_("{0} percent speech volume").format(int(value * 100)), soundIcon='', interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/exit_review.py000066400000000000000000000015011317357605400233750ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('exits review mode') def run(self): if not self.env['runtime']['cursorManager'].isReviewMode(): self.env['runtime']['outputManager'].presentText(_("Not in review mode"), interrupt=True) return self.env['runtime']['cursorManager'].clearReviewCursor() self.env['runtime']['outputManager'].presentText(_("leave review mode"), interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/export_clipboard_to_file.py000066400000000000000000000046031317357605400261120ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug import os class command(): def __init__(self): pass def initialize(self, environment, scriptPath=''): self.env = environment def shutdown(self): pass def getDescription(self): return _('export the current fenrir clipboard to a file') def run(self): clipboardFilePath = self.env['runtime']['settingsManager'].getSetting('general', 'clipboardExportPath') clipboardFilePath = clipboardFilePath.replace('$user',self.env['general']['currUser']) clipboardFilePath = clipboardFilePath.replace('$USER',self.env['general']['currUser']) clipboardFilePath = clipboardFilePath.replace('$User',self.env['general']['currUser']) clipboardFile = open(clipboardFilePath,'w') try: currClipboard = self.env['commandBuffer']['currClipboard'] if currClipboard < 0: self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True) return if not self.env['commandBuffer']['clipboard']: self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True) return if not self.env['commandBuffer']['clipboard'][currClipboard]: self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True) return if self.env['commandBuffer']['clipboard'][currClipboard] == '': self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True) return clipboardFile.write(self.env['commandBuffer']['clipboard'][currClipboard]) clipboardFile.close() os.chmod(clipboardFilePath, 0o666) self.env['runtime']['outputManager'].presentText(_('clipboard exported to file'), interrupt=True) except Exception as e: self.env['runtime']['debug'].writeDebugOut('export_clipboard_to_file:run: Filepath:'+ clipboardFile +' trace:' + str(e),debug.debugLevel.ERROR) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/export_clipboard_to_x.py000066400000000000000000000055701317357605400254460ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug import subprocess, os from subprocess import Popen, PIPE import _thread class command(): def __init__(self): pass def initialize(self, environment, scriptPath=''): self.env = environment self.scriptPath = scriptPath def shutdown(self): pass def getDescription(self): return _('export the current fenrir clipboard to X clipboard') def run(self): _thread.start_new_thread(self._threadRun , ()) def _threadRun(self): try: currClipboard = self.env['commandBuffer']['currClipboard'] if currClipboard < 0: self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True) return if not self.env['commandBuffer']['clipboard']: self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True) return if not self.env['commandBuffer']['clipboard'][currClipboard]: self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True) return if self.env['commandBuffer']['clipboard'][currClipboard] == '': self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True) return for display in range(10): p = Popen('su ' + self.env['general']['currUser'] + ' -c "echo -n \\\"' + self.env['commandBuffer']['clipboard'][currClipboard].replace('"','\\\\\\"') +'\\\" | xclip -d :' + str(display) + ' -selection c"' , stdout=PIPE, stderr=PIPE, shell=True) stdout, stderr = p.communicate() self.env['runtime']['outputManager'].interruptOutput() #screenEncoding = self.env['runtime']['settingsManager'].getSetting('screen', 'encoding') stderr = stderr.decode('utf-8') stdout = stdout.decode('utf-8') if (stderr == ''): break #stderr = stderr.decode(screenEncoding, "replace").encode('utf-8').decode('utf-8') #stdout = stdout.decode(screenEncoding, "replace").encode('utf-8').decode('utf-8') if stderr != '': self.env['runtime']['outputManager'].presentText(stderr , soundIcon='', interrupt=False) else: self.env['runtime']['outputManager'].presentText('exported to the X session.', interrupt=True) except Exception as e: self.env['runtime']['outputManager'].presentText(e , soundIcon='', interrupt=False) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/first_clipboard.py000066400000000000000000000015701317357605400242170ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('selects the first clipboard') def run(self): if len(self.env['commandBuffer']['clipboard']) == 0: self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True) return self.env['commandBuffer']['currClipboard'] = 0 self.env['runtime']['outputManager'].presentText(self.env['commandBuffer']['clipboard'][self.env['commandBuffer']['currClipboard']], interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/forward_keypress.py000066400000000000000000000012051317357605400244350ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('sends the following keypress to the terminal') def run(self): self.env['input']['keyForeward'] = 3 self.env['runtime']['outputManager'].presentText(_('Forward next keypress'), interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/import_clipboard_from_file.py000066400000000000000000000033371317357605400264270ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import mark_utils import os class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('imports text from clipboard file to the clipboard') def run(self): clipboardFilePath = self.env['runtime']['settingsManager'].getSetting('general', 'clipboardExportPath') clipboardFilePath = clipboardFilePath.replace('$user',self.env['general']['currUser']) clipboardFilePath = clipboardFilePath.replace('$USER',self.env['general']['currUser']) clipboardFilePath = clipboardFilePath.replace('$User',self.env['general']['currUser']) if not os.path.exists(clipboardFilePath): self.env['runtime']['outputManager'].presentText(_('File does not exist'), soundIcon='', interrupt=True) return clipboardFile = open(clipboardFilePath,'r') imported = clipboardFile.read() clipboardFile.close() self.env['commandBuffer']['clipboard'] = [imported] + self.env['commandBuffer']['clipboard'][:self.env['runtime']['settingsManager'].getSettingAsInt('general', 'numberOfClipboards') -1] self.env['commandBuffer']['currClipboard'] = 0 self.env['runtime']['outputManager'].presentText('Import to Clipboard', soundIcon='CopyToClipboard', interrupt=True) self.env['runtime']['outputManager'].presentText(imported, soundIcon='', interrupt=False) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/inc_alsa_volume.py000066400000000000000000000017331317357605400242120ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. initialized = False try: import alsaaudio initialized = True except: pass from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _("Increase system volume") def run(self): if not initialized: self.env['runtime']['outputManager'].presentText(_('alsaaudio is not installed'), interrupt=True) return mixer = alsaaudio.Mixer() value = mixer.getvolume()[0] value = value + 5 if value > 100: value = 100 mixer.setvolume(value) self.env['runtime']['outputManager'].presentText(_("{0} percent system volume").format(value), interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/inc_sound_volume.py000066400000000000000000000017101317357605400244150ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug import math class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('adjusts the volume for in coming sounds') def run(self): value = self.env['runtime']['settingsManager'].getSettingAsFloat('sound', 'volume') value = round((math.ceil(10 * value) / 10) + 0.1, 2) if value > 1.0: value = 1.0 self.env['runtime']['settingsManager'].setSetting('sound', 'volume', str(value)) self.env['runtime']['outputManager'].presentText(_("{0} percent sound volume").format(int(value * 100)), soundIcon='SoundOn', interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/inc_speech_pitch.py000066400000000000000000000016641317357605400243440ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug import math class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('increases the pitch of the speech') def run(self): value = self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'pitch') value = round((math.ceil(10 * value) / 10) + 0.1, 2) if value > 1.0: value = 1.0 self.env['runtime']['settingsManager'].setSetting('speech', 'pitch', str(value)) self.env['runtime']['outputManager'].presentText(_("{0} percent speech pitch").format(int(value * 100)), soundIcon='', interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/inc_speech_rate.py000066400000000000000000000016461317357605400241700ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug import math class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('increase the speech rate') def run(self): value = self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'rate') value = round((math.ceil(10 * value) / 10) + 0.1, 2) if value > 1.0: value = 1.0 self.env['runtime']['settingsManager'].setSetting('speech', 'rate', str(value)) self.env['runtime']['outputManager'].presentText(_("{0} percent speech rate").format(int(value * 100)), soundIcon='', interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/inc_speech_volume.py000066400000000000000000000016571317357605400245460ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug import math class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('increase the speech volume') def run(self): value = self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'volume') value = round((math.ceil(10 * value) / 10) + 0.1, 2) if value > 1.0: value = 1.0 self.env['runtime']['settingsManager'].setSetting('speech', 'volume', str(value)) self.env['runtime']['outputManager'].presentText(_("{0} percent speech volume").format(int(value * 100)), soundIcon='', interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/indent_curr_line.py000066400000000000000000000022531317357605400243730ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import line_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('shows the indention level for the current line') def run(self): # Prefer review cursor over text cursor if self.env['screen']['newCursorReview']: cursorPos = self.env['screen']['newCursorReview'].copy() else: cursorPos = self.env['screen']['newCursor'].copy() x, y, currLine = \ line_utils.getCurrentLine(cursorPos['x'], cursorPos['y'], self.env['screen']['newContentText']) if currLine.isspace(): self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True) else: self.env['runtime']['outputManager'].presentText(_("indent {0}").format(len(currLine) - len(currLine.lstrip())), interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/last_clipboard.py000066400000000000000000000016451317357605400240360ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('selects the last clipboard') def run(self): if len(self.env['commandBuffer']['clipboard']) == 0: self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True) return self.env['commandBuffer']['currClipboard'] = len(self.env['commandBuffer']['clipboard']) -1 self.env['runtime']['outputManager'].presentText(self.env['commandBuffer']['clipboard'][self.env['commandBuffer']['currClipboard']], interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/last_incoming.py000066400000000000000000000011201317357605400236660ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('displays the last received text') def run(self): self.env['runtime']['outputManager'].presentText(self.env['screen']['newDelta'], interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/marked_text.py000066400000000000000000000024551317357605400233630ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import mark_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('speaks the currently selected text that will be copied to the clipboard') def run(self): if not (self.env['commandBuffer']['Marks']['1'] and \ self.env['commandBuffer']['Marks']['2']): self.env['runtime']['outputManager'].presentText(_("please set begin and endmark"), interrupt=True) return # use the last first and the last setted mark as range startMark = self.env['commandBuffer']['Marks']['1'].copy() endMark = self.env['commandBuffer']['Marks']['2'].copy() marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screen']['newContentText']) if marked.isspace(): self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True) else: self.env['runtime']['outputManager'].presentText(marked, interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/next_clipboard.py000066400000000000000000000025221317357605400240440ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('selects the next clipboard') def run(self): if len(self.env['commandBuffer']['clipboard']) == 0: self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True) return self.env['commandBuffer']['currClipboard'] += 1 if self.env['commandBuffer']['currClipboard'] > len(self.env['commandBuffer']['clipboard']) -1: self.env['commandBuffer']['currClipboard'] = 0 self.env['runtime']['outputManager'].presentText(_('First clipboard '), interrupt=True) self.env['runtime']['outputManager'].presentText(self.env['commandBuffer']['clipboard'][self.env['commandBuffer']['currClipboard']], interrupt=False) else: self.env['runtime']['outputManager'].presentText(self.env['commandBuffer']['clipboard'][self.env['commandBuffer']['currClipboard']], interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/paste_clipboard.py000066400000000000000000000031411317357605400242000ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug import time class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('pastes the text from the currently selected clipboard') def run(self): currClipboard = self.env['commandBuffer']['currClipboard'] if currClipboard < 0: self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True) return if not self.env['commandBuffer']['clipboard']: self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True) return if not self.env['commandBuffer']['clipboard'][currClipboard]: self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True) return if self.env['commandBuffer']['clipboard'][currClipboard] == '': self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True) return self.env['runtime']['outputManager'].presentText('paste clipboard', soundIcon='PasteClipboardOnScreen', interrupt=True) time.sleep(0.01) self.env['runtime']['screenManager'].injectTextToScreen(self.env['commandBuffer']['clipboard'][currClipboard]) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/present_first_line.py000066400000000000000000000015121317357605400247430ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import line_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('present first line') def run(self): x, y, firstLine = \ line_utils.getCurrentLine(0, 0, self.env['screen']['newContentText']) if firstLine.isspace(): self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True) else: self.env['runtime']['outputManager'].presentText(firstLine, interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/present_last_line.py000066400000000000000000000015261317357605400245640ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import line_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('current line') def run(self): x, y, lastLine = \ line_utils.getCurrentLine(0, self.env['screen']['lines'] -1, self.env['screen']['newContentText']) if lastLine.isspace(): self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True) else: self.env['runtime']['outputManager'].presentText(lastLine, interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/prev_clipboard.py000066400000000000000000000025221317357605400240420ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('selects the previous clipboard') def run(self): if len(self.env['commandBuffer']['clipboard']) == 0: self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True) return self.env['commandBuffer']['currClipboard'] -= 1 if self.env['commandBuffer']['currClipboard'] < 0: self.env['commandBuffer']['currClipboard'] = len(self.env['commandBuffer']['clipboard']) -1 self.env['runtime']['outputManager'].presentText(_('Last clipboard '), interrupt=True) self.env['runtime']['outputManager'].presentText(self.env['commandBuffer']['clipboard'][self.env['commandBuffer']['currClipboard']], interrupt=False) else: self.env['runtime']['outputManager'].presentText(self.env['commandBuffer']['clipboard'][self.env['commandBuffer']['currClipboard']], interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/quit_fenrir.py000066400000000000000000000010251317357605400233730ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('exits Fenrir') def run(self): self.env['runtime']['eventManager'].stopMainEventLoop() def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/remove_marks.py000066400000000000000000000011451317357605400235410ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('removes marks from selected text') def run(self): self.env['runtime']['cursorManager'].clearMarks() self.env['runtime']['outputManager'].presentText(_('Remove marks'), interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/remove_word_from_spell_check.py000066400000000000000000000043421317357605400267600ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import word_utils import string initialized = False try: import enchant initialized = True except: pass class command(): def __init__(self): self.language = '' self.spellChecker = None def initialize(self, environment): self.env = environment self.updateSpellLanguage() def shutdown(self): pass def getDescription(self): return _('removes the current word from the exceptions dictionary') def updateSpellLanguage(self): self.spellChecker = enchant.Dict(self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage')) self.language = self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage') def run(self): if not initialized: self.env['runtime']['outputManager'].presentText(_('pyenchant is not installed'), interrupt=True) return if self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage') != self.language: try: self.updateSpellLanguage() except: return cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() # get the word newContent = self.env['screen']['newContentText'].split('\n')[cursorPos['y']] x, y, currWord, endOfScreen, lineBreak = word_utils.getCurrentWord(cursorPos['x'], 0, newContent) currWord = currWord.strip(string.whitespace + '!"#$%&\()*+,-./:;<=§>?@[\\]^_{|}~') if not currWord.isspace(): if self.spellChecker.is_removed(currWord): self.env['runtime']['outputManager'].presentText(_('{0} is already removed from dict').format(currWord,), soundIcon='Cancel', interrupt=True) else: self.spellChecker.remove(currWord) self.env['runtime']['outputManager'].presentText(_('{0} removed').format(currWord,), soundIcon='Accept', interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/review_bottom.py000066400000000000000000000012211317357605400237270ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('move review to bottom of screen') def run(self): self.env['screen']['newCursorReview'] = { 'x': 0, 'y':self.env['screen']['lines'] -1} self.env['runtime']['outputManager'].presentText(_("Bottom"), interrupt=True, flush=False) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/review_curr_char.py000066400000000000000000000017411317357605400244020ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import char_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('presents the current character.') def run(self): self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor() self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], currChar = \ char_utils.getCurrentChar(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) self.env['runtime']['outputManager'].presentText(currChar ,interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/review_curr_char_phonetic.py000066400000000000000000000022571317357605400262760ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import char_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('set review and phonetically presents the current character') def run(self): self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor() self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], currChar = \ char_utils.getCurrentChar(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) if currChar.isspace(): self.env['runtime']['outputManager'].presentText(_("blank"), interrupt=True, flush=False) else: currChar = char_utils.getPhonetic(currChar) self.env['runtime']['outputManager'].presentText(currChar ,interrupt=True, announceCapital=True, flush=False) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/review_curr_line.py000066400000000000000000000021551317357605400244140ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import line_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('current line') def run(self): self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor() self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], currLine = \ line_utils.getCurrentLine(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) if currLine.isspace(): self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True, flush=False) else: self.env['runtime']['outputManager'].presentText(currLine, interrupt=True, flush=False) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/review_curr_word.py000066400000000000000000000031501317357605400244340ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import word_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('current word.') def run(self): self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor() self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], currWord, endOfScreen, lineBreak = \ word_utils.getCurrentWord(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) if currWord.isspace(): self.env['runtime']['outputManager'].presentText(_("blank"), interrupt=True, flush=False) else: self.env['runtime']['outputManager'].presentText(currWord, interrupt=True, flush=False) if endOfScreen: if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen') if lineBreak: if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'): self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine') def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/review_curr_word_phonetic.py000066400000000000000000000036071317357605400263340ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import word_utils from utils import char_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('phonetically spells the current word and set review to it') def run(self): self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor() self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], currWord, endOfScreen, lineBreak = \ word_utils.getCurrentWord(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) if currWord.isspace(): self.env['runtime']['outputManager'].presentText(_("blank"), interrupt=True, flush=False) else: firstSequence = True for c in currWord: currChar = char_utils.getPhonetic(c) self.env['runtime']['outputManager'].presentText(currChar, interrupt=firstSequence, announceCapital=True, flush=False) firstSequence = False if endOfScreen: if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen') if lineBreak: if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'): self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine') def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/review_down.py000066400000000000000000000024221317357605400233760ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import char_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('set review cursor to char below the current char and present it.') def run(self): cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], downChar, endOfScreen = \ char_utils.getDownChar(self.env['screen']['newCursorReview']['x'],self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) self.env['runtime']['outputManager'].presentText(downChar ,interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False) if endOfScreen: if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen') def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/review_line_begin.py000066400000000000000000000025251317357605400245260ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import char_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('set review cursor to begin of current line and display the content') def run(self): cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() self.env['runtime']['cursorManager'].setReviewCursorPosition(0 ,cursorPos['y']) self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], currChar = \ char_utils.getCurrentChar(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) if currChar.isspace(): self.env['runtime']['outputManager'].presentText(_("blank"), interrupt=True, flush=False) else: self.env['runtime']['outputManager'].presentText(currChar ,interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False) self.env['runtime']['outputManager'].presentText(_("beginning of line"), interrupt=False) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/review_line_end.py000066400000000000000000000023241317357605400242050ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import char_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('set review cursor to end of current line and display the content') def run(self): cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() self.env['runtime']['cursorManager'].setReviewCursorPosition(self.env['screen']['columns']-1 ,cursorPos['y']) self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], currChar = \ char_utils.getCurrentChar(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) self.env['runtime']['outputManager'].presentText(currChar ,interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False) self.env['runtime']['outputManager'].presentText(_("end of line"), interrupt=False) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/review_line_first_char.py000066400000000000000000000031511317357605400255620ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import line_utils from utils import char_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('set review cursor to end of current line and display the content') def run(self): cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() x, y, currLine = \ line_utils.getCurrentLine(cursorPos['x'], cursorPos['y'], self.env['screen']['newContentText']) if currLine.isspace(): self.env['runtime']['outputManager'].presentText(_("line is empty"), interrupt=True) return self.env['runtime']['cursorManager'].setReviewCursorPosition((len(currLine) - len(currLine.lstrip())), cursorPos['y']) self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], currChar = \ char_utils.getCurrentChar(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) self.env['runtime']['outputManager'].presentText(currChar ,interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False) self.env['runtime']['outputManager'].presentText(_("first char in line indent {0}").format(str(len(currLine) - len(currLine.lstrip()))), interrupt=False) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/review_line_last_char.py000066400000000000000000000022711317357605400254000ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import char_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('set review cursor to end of current line and display the content') def run(self): cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() self.env['runtime']['cursorManager'].setReviewCursorPosition(self.env['screen']['columns']-1 ,cursorPos['y']) self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], lastChar = \ char_utils.getLastCharInLine(self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) self.env['runtime']['outputManager'].presentText(lastChar ,interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False) self.env['runtime']['outputManager'].presentText(_("last char in line"), interrupt=False) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/review_next_char.py000066400000000000000000000030141317357605400244000ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import char_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('moves review to the next character and presents it') def run(self): self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor() self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], nextChar, endOfScreen, lineBreak = \ char_utils.getNextChar(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) self.env['runtime']['outputManager'].presentText(nextChar, interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False) if endOfScreen: if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen') if lineBreak: if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'): self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine') def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/review_next_char_phonetic.py000066400000000000000000000030631317357605400262750ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import char_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('phonetically presents the next character and set review to it') def run(self): self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor() self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], nextChar, endOfScreen, lineBreak = \ char_utils.getNextChar(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) nextChar = char_utils.getPhonetic(nextChar) self.env['runtime']['outputManager'].presentText(nextChar ,interrupt=True, announceCapital=True, flush=False) if endOfScreen: if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen') if lineBreak: if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'): self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine') def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/review_next_line.py000066400000000000000000000031041317357605400244120ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import line_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('moves review to the next line and presents it') def run(self): self.env['screen']['oldCursorReview'] = self.env['screen']['newCursorReview'] if not self.env['screen']['newCursorReview']: self.env['screen']['newCursorReview'] = self.env['screen']['newCursor'].copy() self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], nextLine, endOfScreen = \ line_utils.getNextLine(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) if nextLine.isspace(): self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True, flush=False) else: self.env['runtime']['outputManager'].presentText(nextLine, interrupt=True, flush=False) if endOfScreen: if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen') def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/review_next_word.py000066400000000000000000000034721317357605400244460ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import word_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('moves review to the next word and presents it') def run(self): self.env['screen']['oldCursorReview'] = self.env['screen']['newCursorReview'] if self.env['screen']['newCursorReview'] == None: self.env['screen']['newCursorReview'] = self.env['screen']['newCursor'].copy() self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], nextWord, endOfScreen, lineBreak = \ word_utils.getNextWord(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) if nextWord.isspace(): self.env['runtime']['outputManager'].presentText(_("blank"), interrupt=True, flush=False) else: self.env['runtime']['outputManager'].presentText(nextWord, interrupt=True, flush=False) if endOfScreen: if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen') if lineBreak: if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'): self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine') def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/review_next_word_phonetic.py000066400000000000000000000036051317357605400263350ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import word_utils from utils import char_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('phonetically spells the current word and set review to it') def run(self): self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor() self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], nextWord, endOfScreen, lineBreak = \ word_utils.getNextWord(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) if nextWord.isspace(): self.env['runtime']['outputManager'].presentText(_("blank"), interrupt=True, flush=False) else: firstSequence = True for c in nextWord: currChar = char_utils.getPhonetic(c) self.env['runtime']['outputManager'].presentText(currChar, interrupt=firstSequence, announceCapital=True, flush=False) firstSequence = False if endOfScreen: if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen') if lineBreak: if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'): self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine') def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/review_prev_char.py000066400000000000000000000032601317357605400244010ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import char_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('moves review to the previous character and presents it') def run(self): self.env['screen']['oldCursorReview'] = self.env['screen']['newCursorReview'] if not self.env['screen']['newCursorReview']: self.env['screen']['newCursorReview'] = self.env['screen']['newCursor'].copy() self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], prevChar, endOfScreen, lineBreak = \ char_utils.getPrevChar(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) self.env['runtime']['outputManager'].presentText(prevChar, interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False) if endOfScreen: if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen') if lineBreak: if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'): self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine') def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/review_prev_char_phonetic.py000066400000000000000000000030671317357605400262770ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import char_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('phonetically presents the previous character and set review to it') def run(self): self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor() self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], prevChar, endOfScreen, lineBreak = \ char_utils.getPrevChar(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) prevChar = char_utils.getPhonetic(prevChar) self.env['runtime']['outputManager'].presentText(prevChar ,interrupt=True, announceCapital=True, flush=False) if endOfScreen: if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen') if lineBreak: if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'): self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine') def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/review_prev_line.py000066400000000000000000000026521317357605400244170ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import line_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('moves review to the previous line and presents it') def run(self): self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor() self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], prevLine, endOfScreen = \ line_utils.getPrevLine(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) if prevLine.isspace(): self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True, flush=False) else: self.env['runtime']['outputManager'].presentText(prevLine, interrupt=True, flush=False) if endOfScreen: if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen') def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/review_prev_word.py000066400000000000000000000032361317357605400244420ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import word_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('moves review focus to the previous word and presents it') def run(self): self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor() self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], prevWord, endOfScreen, lineBreak = \ word_utils.getPrevWord(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) if prevWord.isspace(): self.env['runtime']['outputManager'].presentText(_("blank"), interrupt=True, flush=False) else: self.env['runtime']['outputManager'].presentText(prevWord, interrupt=True, flush=False) if endOfScreen: if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=False, soundIcon='EndOfScreen') if lineBreak: if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'): self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine') def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/review_prev_word_phonetic.py000066400000000000000000000036051317357605400263330ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import word_utils from utils import char_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('phonetically spells the current word and set review to it') def run(self): self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor() self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], prevWord, endOfScreen, lineBreak = \ word_utils.getPrevWord(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) if prevWord.isspace(): self.env['runtime']['outputManager'].presentText(_("blank"), interrupt=True, flush=False) else: firstSequence = True for c in prevWord: currChar = char_utils.getPhonetic(c) self.env['runtime']['outputManager'].presentText(currChar, interrupt=firstSequence, announceCapital=True, flush=False) firstSequence = False if endOfScreen: if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen') if lineBreak: if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'): self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine') def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/review_top.py000066400000000000000000000012021317357605400232240ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import char_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('move review to top of screen') def run(self): self.env['screen']['newCursorReview'] = {'x':0,'y':0} self.env['runtime']['outputManager'].presentText(_("Top"), interrupt=True, flush=False) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/review_up.py000066400000000000000000000030021317357605400230460ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import char_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('set review cursor to the char in the line below and present it') def run(self): cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], upChar, endOfScreen = \ char_utils.getUpChar(self.env['screen']['newCursorReview']['x'],self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) self.env['runtime']['outputManager'].presentText(upChar ,interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False) if endOfScreen: if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen') if lineBreak: if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'): self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine') def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/set_bookmark_1.py000066400000000000000000000027441317357605400237550ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): self.ID = '1' def initialize(self, environment): self.env = environment self.env['commandBuffer']['bookMarks'][self.ID] = {} def shutdown(self): pass def getDescription(self): return _('set Bookmark {0}').format(self.ID,) def run(self): if not self.env['commandBuffer']['Marks']['1']: self.env['runtime']['outputManager'].presentText(_("No Mark found"), interrupt=True) return currApp = self.env['runtime']['applicationManager'].getCurrentApplication() self.env['commandBuffer']['bookMarks'][self.ID][currApp] = {} self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'] = self.env['commandBuffer']['Marks']['1'].copy() if self.env['commandBuffer']['Marks']['2']: self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = self.env['commandBuffer']['Marks']['2'].copy() else: self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = None self.env['runtime']['outputManager'].presentText(_('Bookmark {0} set for application {1}').format(self.ID, currApp), interrupt=True) self.env['commandBuffer']['Marks']['1'] = None self.env['commandBuffer']['Marks']['2'] = None def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/set_bookmark_10.py000066400000000000000000000027451317357605400240360ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): self.ID = '10' def initialize(self, environment): self.env = environment self.env['commandBuffer']['bookMarks'][self.ID] = {} def shutdown(self): pass def getDescription(self): return _('set Bookmark {0}').format(self.ID,) def run(self): if not self.env['commandBuffer']['Marks']['1']: self.env['runtime']['outputManager'].presentText(_("No Mark found"), interrupt=True) return currApp = self.env['runtime']['applicationManager'].getCurrentApplication() self.env['commandBuffer']['bookMarks'][self.ID][currApp] = {} self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'] = self.env['commandBuffer']['Marks']['1'].copy() if self.env['commandBuffer']['Marks']['2']: self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = self.env['commandBuffer']['Marks']['2'].copy() else: self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = None self.env['runtime']['outputManager'].presentText(_('Bookmark {0} set for application {1}').format(self.ID, currApp), interrupt=True) self.env['commandBuffer']['Marks']['1'] = None self.env['commandBuffer']['Marks']['2'] = None def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/set_bookmark_2.py000066400000000000000000000027441317357605400237560ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): self.ID = '2' def initialize(self, environment): self.env = environment self.env['commandBuffer']['bookMarks'][self.ID] = {} def shutdown(self): pass def getDescription(self): return _('set Bookmark {0}').format(self.ID,) def run(self): if not self.env['commandBuffer']['Marks']['1']: self.env['runtime']['outputManager'].presentText(_("No Mark found"), interrupt=True) return currApp = self.env['runtime']['applicationManager'].getCurrentApplication() self.env['commandBuffer']['bookMarks'][self.ID][currApp] = {} self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'] = self.env['commandBuffer']['Marks']['1'].copy() if self.env['commandBuffer']['Marks']['2']: self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = self.env['commandBuffer']['Marks']['2'].copy() else: self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = None self.env['runtime']['outputManager'].presentText(_('Bookmark {0} set for application {1}').format(self.ID, currApp), interrupt=True) self.env['commandBuffer']['Marks']['1'] = None self.env['commandBuffer']['Marks']['2'] = None def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/set_bookmark_3.py000066400000000000000000000027441317357605400237570ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): self.ID = '3' def initialize(self, environment): self.env = environment self.env['commandBuffer']['bookMarks'][self.ID] = {} def shutdown(self): pass def getDescription(self): return _('set Bookmark {0}').format(self.ID,) def run(self): if not self.env['commandBuffer']['Marks']['1']: self.env['runtime']['outputManager'].presentText(_("No Mark found"), interrupt=True) return currApp = self.env['runtime']['applicationManager'].getCurrentApplication() self.env['commandBuffer']['bookMarks'][self.ID][currApp] = {} self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'] = self.env['commandBuffer']['Marks']['1'].copy() if self.env['commandBuffer']['Marks']['2']: self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = self.env['commandBuffer']['Marks']['2'].copy() else: self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = None self.env['runtime']['outputManager'].presentText(_('Bookmark {0} set for application {1}').format(self.ID, currApp), interrupt=True) self.env['commandBuffer']['Marks']['1'] = None self.env['commandBuffer']['Marks']['2'] = None def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/set_bookmark_4.py000066400000000000000000000027441317357605400237600ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): self.ID = '4' def initialize(self, environment): self.env = environment self.env['commandBuffer']['bookMarks'][self.ID] = {} def shutdown(self): pass def getDescription(self): return _('set Bookmark {0}').format(self.ID,) def run(self): if not self.env['commandBuffer']['Marks']['1']: self.env['runtime']['outputManager'].presentText(_("No Mark found"), interrupt=True) return currApp = self.env['runtime']['applicationManager'].getCurrentApplication() self.env['commandBuffer']['bookMarks'][self.ID][currApp] = {} self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'] = self.env['commandBuffer']['Marks']['1'].copy() if self.env['commandBuffer']['Marks']['2']: self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = self.env['commandBuffer']['Marks']['2'].copy() else: self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = None self.env['runtime']['outputManager'].presentText(_('Bookmark {0} set for application {1}').format(self.ID, currApp), interrupt=True) self.env['commandBuffer']['Marks']['1'] = None self.env['commandBuffer']['Marks']['2'] = None def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/set_bookmark_5.py000066400000000000000000000027441317357605400237610ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): self.ID = '5' def initialize(self, environment): self.env = environment self.env['commandBuffer']['bookMarks'][self.ID] = {} def shutdown(self): pass def getDescription(self): return _('set Bookmark {0}').format(self.ID,) def run(self): if not self.env['commandBuffer']['Marks']['1']: self.env['runtime']['outputManager'].presentText(_("No Mark found"), interrupt=True) return currApp = self.env['runtime']['applicationManager'].getCurrentApplication() self.env['commandBuffer']['bookMarks'][self.ID][currApp] = {} self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'] = self.env['commandBuffer']['Marks']['1'].copy() if self.env['commandBuffer']['Marks']['2']: self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = self.env['commandBuffer']['Marks']['2'].copy() else: self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = None self.env['runtime']['outputManager'].presentText(_('Bookmark {0} set for application {1}').format(self.ID, currApp), interrupt=True) self.env['commandBuffer']['Marks']['1'] = None self.env['commandBuffer']['Marks']['2'] = None def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/set_bookmark_6.py000066400000000000000000000027441317357605400237620ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): self.ID = '6' def initialize(self, environment): self.env = environment self.env['commandBuffer']['bookMarks'][self.ID] = {} def shutdown(self): pass def getDescription(self): return _('set Bookmark {0}').format(self.ID,) def run(self): if not self.env['commandBuffer']['Marks']['1']: self.env['runtime']['outputManager'].presentText(_("No Mark found"), interrupt=True) return currApp = self.env['runtime']['applicationManager'].getCurrentApplication() self.env['commandBuffer']['bookMarks'][self.ID][currApp] = {} self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'] = self.env['commandBuffer']['Marks']['1'].copy() if self.env['commandBuffer']['Marks']['2']: self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = self.env['commandBuffer']['Marks']['2'].copy() else: self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = None self.env['runtime']['outputManager'].presentText(_('Bookmark {0} set for application {1}').format(self.ID, currApp), interrupt=True) self.env['commandBuffer']['Marks']['1'] = None self.env['commandBuffer']['Marks']['2'] = None def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/set_bookmark_7.py000066400000000000000000000027441317357605400237630ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): self.ID = '7' def initialize(self, environment): self.env = environment self.env['commandBuffer']['bookMarks'][self.ID] = {} def shutdown(self): pass def getDescription(self): return _('set Bookmark {0}').format(self.ID,) def run(self): if not self.env['commandBuffer']['Marks']['1']: self.env['runtime']['outputManager'].presentText(_("No Mark found"), interrupt=True) return currApp = self.env['runtime']['applicationManager'].getCurrentApplication() self.env['commandBuffer']['bookMarks'][self.ID][currApp] = {} self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'] = self.env['commandBuffer']['Marks']['1'].copy() if self.env['commandBuffer']['Marks']['2']: self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = self.env['commandBuffer']['Marks']['2'].copy() else: self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = None self.env['runtime']['outputManager'].presentText(_('Bookmark {0} set for application {1}').format(self.ID, currApp), interrupt=True) self.env['commandBuffer']['Marks']['1'] = None self.env['commandBuffer']['Marks']['2'] = None def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/set_bookmark_8.py000066400000000000000000000027441317357605400237640ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): self.ID = '8' def initialize(self, environment): self.env = environment self.env['commandBuffer']['bookMarks'][self.ID] = {} def shutdown(self): pass def getDescription(self): return _('set Bookmark {0}').format(self.ID,) def run(self): if not self.env['commandBuffer']['Marks']['1']: self.env['runtime']['outputManager'].presentText(_("No Mark found"), interrupt=True) return currApp = self.env['runtime']['applicationManager'].getCurrentApplication() self.env['commandBuffer']['bookMarks'][self.ID][currApp] = {} self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'] = self.env['commandBuffer']['Marks']['1'].copy() if self.env['commandBuffer']['Marks']['2']: self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = self.env['commandBuffer']['Marks']['2'].copy() else: self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = None self.env['runtime']['outputManager'].presentText(_('Bookmark {0} set for application {1}').format(self.ID, currApp), interrupt=True) self.env['commandBuffer']['Marks']['1'] = None self.env['commandBuffer']['Marks']['2'] = None def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/set_bookmark_9.py000066400000000000000000000027441317357605400237650ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): self.ID = '9' def initialize(self, environment): self.env = environment self.env['commandBuffer']['bookMarks'][self.ID] = {} def shutdown(self): pass def getDescription(self): return _('set Bookmark {0}').format(self.ID,) def run(self): if not self.env['commandBuffer']['Marks']['1']: self.env['runtime']['outputManager'].presentText(_("No Mark found"), interrupt=True) return currApp = self.env['runtime']['applicationManager'].getCurrentApplication() self.env['commandBuffer']['bookMarks'][self.ID][currApp] = {} self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'] = self.env['commandBuffer']['Marks']['1'].copy() if self.env['commandBuffer']['Marks']['2']: self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = self.env['commandBuffer']['Marks']['2'].copy() else: self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = None self.env['runtime']['outputManager'].presentText(_('Bookmark {0} set for application {1}').format(self.ID, currApp), interrupt=True) self.env['commandBuffer']['Marks']['1'] = None self.env['commandBuffer']['Marks']['2'] = None def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/set_mark.py000066400000000000000000000020031317357605400226460ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('places marks to select text to copy to the clipboard') def run(self): if not self.env['runtime']['cursorManager'].isReviewMode(): self.env['runtime']['outputManager'].presentText(_('no review cursor'), interrupt=True) return currMark = self.env['runtime']['cursorManager'].setMark() if currMark == 1: self.env['runtime']['outputManager'].presentText(_('set mark'), soundIcon='PlaceStartMark', interrupt=True) elif currMark == 2: self.env['runtime']['outputManager'].presentText(_('set mark'),soundIcon='PlaceEndMark', interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/set_window_application.py000066400000000000000000000016711317357605400256200ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('set Window Mode, needs 2 marks ') def run(self): if self.env['runtime']['cursorManager'].setWindowForApplication(): currApp = self.env['runtime']['applicationManager'].getCurrentApplication() self.env['runtime']['outputManager'].presentText(_('Window Mode on for application {0}').format(currApp), interrupt=True) self.env['runtime']['cursorManager'].clearMarks() else: self.env['runtime']['outputManager'].presentText(_("Set window begin and end marks"), interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/shut_up.py000066400000000000000000000012341317357605400225350ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('interrupts the current presentation') def run(self): if len(self.env['input']['prevDeepestInput']) > len(self.env['input']['currInput']): return self.env['runtime']['outputManager'].interruptOutput() def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/spell_check.py000066400000000000000000000042071317357605400233250ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import word_utils initialized = False try: import enchant initialized = True except: pass class command(): def __init__(self): self.language = '' self.spellChecker = None def initialize(self, environment): self.env = environment self.updateSpellLanguage() def shutdown(self): pass def getDescription(self): return _('checks the spelling of the current word') def updateSpellLanguage(self): if not initialized: self.env['runtime']['outputManager'].presentText(_('pyenchant is not installed'), interrupt=True) return self.spellChecker = enchant.Dict(self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage')) self.language = self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage') def run(self): if not initialized: self.env['runtime']['outputManager'].presentText(_('pyenchant is not installed'), interrupt=True) return if self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage') != self.language: try: self.updateSpellLanguage() except: return cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() # get the word newContent = self.env['screen']['newContentText'].split('\n')[cursorPos['y']] x, y, currWord, endOfScreen, lineBreak = word_utils.getCurrentWord(cursorPos['x'], 0, newContent) if not currWord.isspace(): if not self.spellChecker.check(currWord): self.env['runtime']['outputManager'].presentText(_('misspelled'),soundIcon='mispell', interrupt=True) elif not ignore: self.env['runtime']['outputManager'].presentText(_('correct'),soundIcon='', interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/subprocess.py000066400000000000000000000041551317357605400232430ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug import subprocess, os from subprocess import Popen, PIPE import _thread class command(): def __init__(self): pass def initialize(self, environment, scriptPath=''): self.env = environment self.scriptPath = scriptPath def shutdown(self): pass def getDescription(self): return _('script: {0} fullpath: {1}').format(os.path.basename(self.scriptPath), self.scriptPath) def run(self): if not os.path.exists(self.scriptPath): self.env['runtime']['outputManager'].presentText(_('scriptfile does not exist'), soundIcon='', interrupt=False) return if not os.path.isfile(self.scriptPath): self.env['runtime']['outputManager'].presentText(_('scriptfile is not a file'), soundIcon='', interrupt=False) return if not os.access(self.scriptPath, os.X_OK): self.env['runtime']['outputManager'].presentText(_('scriptfile is not executable'), soundIcon='', interrupt=False) return _thread.start_new_thread(self._threadRun , ()) def _threadRun(self): try: callstring = self.scriptPath + ' ' + self.env['general']['currUser'] p = Popen(callstring , stdout=PIPE, stderr=PIPE, shell=True) stdout, stderr = p.communicate() stdout = stdout.decode('utf-8') stderr = stderr.decode('utf-8') self.env['runtime']['outputManager'].interruptOutput() if stderr != '': self.env['runtime']['outputManager'].presentText(str(stderr) , soundIcon='', interrupt=False) if stdout != '': self.env['runtime']['outputManager'].presentText(str(stdout) , soundIcon='', interrupt=False) except Exception as e: self.env['runtime']['outputManager'].presentText(e , soundIcon='', interrupt=False) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/temp_disable_speech.py000066400000000000000000000020231317357605400250220ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('disables speech until next keypress') def run(self): if self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled'): self.env['runtime']['outputManager'].presentText(_("speech temporary disabled"), soundIcon='SpeechOff', interrupt=True) self.env['commandBuffer']['enableSpeechOnKeypress'] = True self.env['runtime']['settingsManager'].setSetting('speech', 'enabled', str(not self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled'))) self.env['runtime']['outputManager'].interruptOutput() def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/time.py000066400000000000000000000016131317357605400220050ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug import datetime class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('presents the time') def run(self): timeFormat = self.env['runtime']['settingsManager'].getSetting('general', 'timeFormat') # get the time formatted timeString = datetime.datetime.strftime(datetime.datetime.now(), timeFormat) # present the time via speak and braile, there is no soundicon, interrupt the current speech self.env['runtime']['outputManager'].presentText(timeString , soundIcon='', interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/toggle_auto_read.py000066400000000000000000000020661317357605400243560ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('enables or disables automatic reading of new text as it appears') def run(self): self.env['runtime']['settingsManager'].setSetting('speech', 'autoReadIncoming', str(not self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'autoReadIncoming'))) if self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'autoReadIncoming'): self.env['runtime']['outputManager'].presentText(_("autoread enabled"), soundIcon='', interrupt=True) else: self.env['runtime']['outputManager'].presentText(_("autoread disabled"), soundIcon='', interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/toggle_auto_spell_check.py000066400000000000000000000020701317357605400257120ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('enables or disables automatic spell checking') def run(self): self.env['runtime']['settingsManager'].setSetting('general', 'autoSpellCheck', str(not self.env['runtime']['settingsManager'].getSettingAsBool('general', 'autoSpellCheck'))) if self.env['runtime']['settingsManager'].getSettingAsBool('general', 'autoSpellCheck'): self.env['runtime']['outputManager'].presentText(_("auto spellcheck enabled"), soundIcon='', interrupt=True) else: self.env['runtime']['outputManager'].presentText(_("auto spellcheck disabled"), soundIcon='', interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/toggle_auto_time.py000066400000000000000000000020231317357605400243720ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('enables or disables automatic reading of time after an period') def run(self): self.env['runtime']['settingsManager'].setSetting('time', 'enabled', str(not self.env['runtime']['settingsManager'].getSettingAsBool('time', 'enabled'))) if self.env['runtime']['settingsManager'].getSettingAsBool('time', 'enabled'): self.env['runtime']['outputManager'].presentText(_("autotime enabled"), soundIcon='', interrupt=True) else: self.env['runtime']['outputManager'].presentText(_("autotime disabled"), soundIcon='', interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/toggle_braille.py000066400000000000000000000021241317357605400240200ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('enables and disables output in braille') def run(self): if self.env['runtime']['settingsManager'].getSettingAsBool('braille', 'enabled'): self.env['runtime']['outputManager'].presentText(_('braille disabled'), soundIcon='BrailleOff', interrupt=True) self.env['runtime']['settingsManager'].setSetting('braille', 'enabled', str(not self.env['runtime']['settingsManager'].getSettingAsBool('braille', 'enabled'))) if self.env['runtime']['settingsManager'].getSettingAsBool('braille', 'enabled'): self.env['runtime']['outputManager'].presentText(_('braille enabled'), soundIcon='BrailleOn', interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/toggle_emoticons.py000066400000000000000000000020451317357605400244100ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('enables or disables announcement of emoticons instead of chars') def run(self): self.env['runtime']['settingsManager'].setSetting('general', 'emoticons', str(not self.env['runtime']['settingsManager'].getSettingAsBool('general', 'emoticons'))) if self.env['runtime']['settingsManager'].getSettingAsBool('general', 'emoticons'): self.env['runtime']['outputManager'].presentText(_('emoticons enabled'), soundIcon='', interrupt=True) else: self.env['runtime']['outputManager'].presentText(_('emoticons disabled'), soundIcon='', interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/toggle_highlight_tracking.py000066400000000000000000000022231317357605400262370ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('enables or disables tracking of highlighted text') def run(self): currMode = self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'highlight') self.env['runtime']['settingsManager'].setSetting('focus', 'highlight', str(not currMode)) self.env['runtime']['settingsManager'].setSetting('focus', 'cursor', str(currMode)) if self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'highlight'): self.env['runtime']['outputManager'].presentText(_('highlight tracking'), soundIcon='', interrupt=True) else: self.env['runtime']['outputManager'].presentText(_('cursor tracking'), soundIcon='', interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/toggle_output.py000066400000000000000000000030231317357605400237450ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('toggles all output settings') def run(self): if self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled') or \ self.env['runtime']['settingsManager'].getSettingAsBool('sound', 'enabled') or \ self.env['runtime']['settingsManager'].getSettingAsBool('braille', 'enabled'): self.env['runtime']['outputManager'].presentText(_('Fenrir muted'), soundIcon='Accept', interrupt=True) self.env['runtime']['settingsManager'].setSetting('speech', 'enabled','False') self.env['runtime']['settingsManager'].setSetting('sound', 'enabled','False') self.env['runtime']['settingsManager'].setSetting('braille', 'enabled','False') else: self.env['runtime']['settingsManager'].setSetting('speech', 'enabled','True') self.env['runtime']['settingsManager'].setSetting('sound', 'enabled','True') self.env['runtime']['settingsManager'].setSetting('braille', 'enabled','True') self.env['runtime']['outputManager'].presentText(_('Fenrir unmuted'), soundIcon='Cancel', interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/toggle_punctuation_level.py000066400000000000000000000015111317357605400261450ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return '' def run(self): if self.env['runtime']['punctuationManager'].cyclePunctuation(): self.env['runtime']['outputManager'].presentText(self.env['runtime']['settingsManager'].getSetting('general', 'punctuationLevel'), interrupt=True, ignorePunctuation=True) else: self.env['runtime']['outputManager'].presentText(_('No punctuation found.'), interrupt=True, ignorePunctuation=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/toggle_sound.py000066400000000000000000000020711317357605400235370ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('enables or disables sound') def run(self): if self.env['runtime']['settingsManager'].getSettingAsBool('sound', 'enabled'): self.env['runtime']['outputManager'].presentText(_('sound disabled'), soundIcon='SoundOff', interrupt=True) self.env['runtime']['settingsManager'].setSetting('sound', 'enabled', str(not self.env['runtime']['settingsManager'].getSettingAsBool('sound', 'enabled'))) if self.env['runtime']['settingsManager'].getSettingAsBool('sound', 'enabled'): self.env['runtime']['outputManager'].presentText(_('sound enabled'), soundIcon='SoundOn', interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/toggle_speech.py000066400000000000000000000020741317357605400236610ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('enables or disables speech') def run(self): if self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled'): self.env['runtime']['outputManager'].presentText(_('speech disabled'), soundIcon='SpeechOff', interrupt=True) self.env['runtime']['settingsManager'].setSetting('speech', 'enabled', str(not self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled'))) if self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled'): self.env['runtime']['outputManager'].presentText(_('speech enabled'), soundIcon='SpeechOn', interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/commands/toggle_tutorial_mode.py000066400000000000000000000020201317357605400252500ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): self.env['runtime']['helpManager'].toggleTutorialMode() #self.env['runtime']['outputManager'].presentText(, interrupt=True) return _('You are leaving the tutorial mode. Press that shortcut again to enter the tutorial mode again.') def run(self): self.env['runtime']['helpManager'].toggleTutorialMode() self.env['runtime']['outputManager'].presentText( _('you entered the tutorial mode. In that mode the commands are not executed. but you get a description of what the shortcut does. To leave the tutorial mode, press that shortcut again.'), interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/help/000077500000000000000000000000001317357605400176235ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/commands/help/Readme.txt000066400000000000000000000001411317357605400215550ustar00rootroot00000000000000this folder contains help and tutorial related functions. those are not bindable but hard coded. fenrir-1.5.1/src/fenrir/commands/help/__init__.py000077500000000000000000000000001317357605400217250ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/commands/help/curr_help.py000066400000000000000000000011751317357605400221640ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('get current help message') def run(self): text = self.env['runtime']['helpManager'].getHelpForCurrentIndex() self.env['runtime']['outputManager'].presentText(text, interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/help/next_help.py000066400000000000000000000012611317357605400221630ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('get next help message') def run(self): self.env['runtime']['helpManager'].nextIndex() text = self.env['runtime']['helpManager'].getHelpForCurrentIndex() self.env['runtime']['outputManager'].presentText(text, interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/help/prev_help.py000066400000000000000000000012611317357605400221610ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('get prev help message') def run(self): self.env['runtime']['helpManager'].prevIndex() text = self.env['runtime']['helpManager'].getHelpForCurrentIndex() self.env['runtime']['outputManager'].presentText(text, interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onApplicationChange/000077500000000000000000000000001317357605400226015ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/commands/onApplicationChange/__init__.py000066400000000000000000000000001317357605400247000ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/commands/onApplicationChange/inactive/000077500000000000000000000000001317357605400244035ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/commands/onApplicationChange/inactive/test.py000066400000000000000000000421311317357605400257350ustar00rootroot00000000000000#!/bi[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]/py[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]ho[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']] # -*- [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]odi[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]g: u[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]f-8 -*- # F[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]i[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']] TTY [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']] [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]d[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']] # By Ch[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]y[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']], S[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]o[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]m [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]go[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']], [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]d [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]o[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]ibu[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]. f[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]om [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]o[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']] impo[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']] d[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]bug [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]l[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']] [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]omm[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]d(): d[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]f __i[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]i[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]__([['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]lf): p[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']] d[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]f i[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]i[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]i[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]liz[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]([['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]lf, [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]vi[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]o[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]m[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]): [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]lf.[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]v = [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]vi[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]o[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]m[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']] d[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]f [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]hu[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]dow[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]([['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]lf): p[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']] d[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]f g[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]ip[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]io[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]([['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]lf): [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]u[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']] [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]No d[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]ip[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]io[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']] fou[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]d[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']] d[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]f [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]u[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]([['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]lf): #p[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]i[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]([['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]w [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']], [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]lf.[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]v[[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]][[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]wAppli[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]io[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]]) #p[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]i[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]([['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]old [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']], [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]lf.[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]v[[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]][[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]oldAppli[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]io[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]]) #p[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]i[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]([['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]-----------[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]) p[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']] d[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]f [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]C[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]llb[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]k([['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]lf, [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]llb[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]k): p[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']] fenrir-1.5.1/src/fenrir/commands/onCursorChange/000077500000000000000000000000001317357605400216135ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/commands/onCursorChange/45000-char_echo.py000066400000000000000000000027071317357605400245540ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return 'No Description found' def run(self): if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'charEcho'): return # detect deletion or chilling if self.env['screen']['newCursor']['x'] <= self.env['screen']['oldCursor']['x']: return # is there any change? if not self.env['runtime']['screenManager'].isDelta(): return # big changes are no char (but the value is bigger than one maybe the differ needs longer than you can type, so a little strange random buffer for now) if len(self.env['screen']['newDelta'].strip(' \n\t')) > 1: return # filter unneded space on word begin currDelta = self.env['screen']['newDelta'] if len(currDelta.strip()) != len(currDelta) and \ currDelta.strip() != '': currDelta = currDelta.strip() self.env['runtime']['outputManager'].presentText(currDelta, interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onCursorChange/50000-present_char_if_cursor_change_horizontal.py000066400000000000000000000043351317357605400331420ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import char_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return '' def run(self): if not self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'cursor'): return if self.env['runtime']['screenManager'].isScreenChange(): return # detect an change on the screen, we just want to cursor arround, so no change should appear if self.env['runtime']['screenManager'].isDelta(): return if self.env['runtime']['screenManager'].isNegativeDelta(): return # is a vertical change? if self.env['runtime']['cursorManager'].isCursorVerticalMove(): return # is it a horizontal change? if not self.env['runtime']['cursorManager'].isCursorHorizontalMove(): return # echo word insteed of char if self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'wordEcho'): if abs(self.env['screen']['oldCursor']['x'] - self.env['screen']['newCursor']['x']) != 1: # get the word newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] x, y, currWord, endOfScreen, lineBreak = \ word_utils.getCurrentWord(self.env['screen']['newCursor']['x'], 0, newContent) if self.env['screen']['newCursor']['x'] == x: return x, y, currChar = char_utils.getCurrentChar(self.env['screen']['newCursor']['x'], self.env['screen']['newCursor']['y'], self.env['screen']['newContentText']) if not currChar.isspace(): self.env['runtime']['outputManager'].presentText(currChar, interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onCursorChange/55000-present_line_if_cursor_change_vertical.py000066400000000000000000000027571317357605400326070ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import line_utils from utils import word_utils class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return '' def run(self): if not self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'cursor'): return if self.env['runtime']['screenManager'].isScreenChange(): return # this leads to problems in vim -> status line change -> no announcement, so we do check the lengh as hack if self.env['runtime']['screenManager'].isDelta(): return # is a vertical change? if not self.env['runtime']['cursorManager'].isCursorVerticalMove(): return x, y, currLine = line_utils.getCurrentLine(self.env['screen']['newCursor']['x'], self.env['screen']['newCursor']['y'], self.env['screen']['newContentText']) if currLine.isspace(): self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True, flush=False) else: self.env['runtime']['outputManager'].presentText(currLine, interrupt=True, flush=False) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onCursorChange/60000-word_echo_type.py000066400000000000000000000040201317357605400256360ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import word_utils import string class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return 'No Description found' def run(self): # is it enabled? if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'wordEcho'): return # is naviation? if self.env['screen']['newCursor']['x'] - self.env['screen']['oldCursor']['x'] != 1: return # just when cursor move worddetection is needed if not self.env['runtime']['cursorManager'].isCursorHorizontalMove(): return # for now no new line if self.env['runtime']['cursorManager'].isCursorVerticalMove(): return # currently writing if self.env['runtime']['screenManager'].isDelta(): return # get the word newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] x, y, currWord, endOfScreen, lineBreak = \ word_utils.getCurrentWord(self.env['screen']['newCursor']['x'], 0, newContent) # is there a word? if currWord == '': return # at the end of a word if not newContent[self.env['screen']['newCursor']['x']].isspace(): return # at the end of a word if (x + len(currWord) != self.env['screen']['newCursor']['x']) and \ (x + len(currWord) != self.env['screen']['newCursor']['x']-1): return self.env['runtime']['outputManager'].presentText(currWord, interrupt=True, flush=False) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onCursorChange/61000-word_echo_navigation.py000066400000000000000000000033701317357605400270240ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import word_utils import string class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return 'No Description found' def run(self): # is navigation? if not abs(self.env['screen']['oldCursor']['x'] - self.env['screen']['newCursor']['x']) > 1: return # just when cursor move worddetection is needed if not self.env['runtime']['cursorManager'].isCursorHorizontalMove(): return # for now no new line if self.env['runtime']['cursorManager'].isCursorVerticalMove(): return # currently writing if self.env['runtime']['screenManager'].isDelta(): return # get the word newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] x, y, currWord, endOfScreen, lineBreak = \ word_utils.getCurrentWord(self.env['screen']['newCursor']['x'], 0, newContent) # is there a word? if currWord == '': return # at the start of a word if (x + len(currWord) != self.env['screen']['newCursor']['x']) and \ (self.env['screen']['newCursor']['x'] != x): return self.env['runtime']['outputManager'].presentText(currWord, interrupt=True, flush=False) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onCursorChange/62000-spell_check.py000066400000000000000000000114631317357605400251130ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import word_utils import os, string initialized = False try: import enchant initialized = True except: pass class command(): def __init__(self): self.language = '' self.spellChecker = '' def initialize(self, environment): self.env = environment self.updateSpellLanguage() def shutdown(self): pass def getDescription(self): return 'No Description found' def updateSpellLanguage(self): if not initialized: self.env['runtime']['outputManager'].presentText('pychant is not installed', interrupt=True) return self.spellChecker = enchant.Dict(self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage')) self.language = self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage') def run(self): if not initialized: return if not self.env['runtime']['settingsManager'].getSettingAsBool('general', 'autoSpellCheck'): return if self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage') != self.language: try: self.updateSpellLanguage() except: return # just when horizontal cursor move worddetection is needed if not self.env['runtime']['cursorManager'].isCursorHorizontalMove(): return # for now no new line if self.env['runtime']['cursorManager'].isCursorVerticalMove(): return # more than a keyecho? if len(self.env['screen']['newDelta']) > 1: return # deletion if self.env['runtime']['screenManager'].isNegativeDelta(): return # first place could not be the end of a word if self.env['screen']['newCursor']['x'] == 0: return # get the word (just for speedup only look at current line newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] x, y, currWord, endOfScreen, lineBreak = word_utils.getCurrentWord(self.env['screen']['newCursor']['x'], 0, newContent) # was this a typed word? if self.env['runtime']['screenManager'].isDelta(): if not(newContent[self.env['screen']['oldCursor']['x']] in string.whitespace + '!"#$%&()*+,-./:;<=>?@[\\]^_{|}~' and x != self.env['screen']['oldCursor']['x']): return else: currWord = currWord.strip(string.whitespace + '!"#$%&()*+,-./:;<=>?@[\\]^_{|}~') else: # or just arrow arround? if not newContent[self.env['screen']['newCursor']['x']].isspace(): return if (x + len(currWord) != self.env['screen']['newCursor']['x']) and \ (x + len(currWord) != self.env['screen']['newCursor']['x']-1): return # just on end of word if self.env['screen']['newCursor']['x'] > 0: if not newContent[self.env['screen']['oldCursor']['x'] - 1].lower() in string.ascii_lowercase: return # ignore bash buildins if currWord in ['cd','fg','bg','alias','bind','dir','caller','buildin','command','declare','echo','enable','help','let','local','logout',\ 'mapfile','printf','read','readarray','source','type','typeset','ulimit','unalias']: return # ignore the application name if currWord.upper() == 'FENRIR': return if currWord[0] =='-': return if currWord[0] == '/': return if currWord[0] == '#': return if currWord.startswith('./'): return if '@' in currWord and '.' in currWord: return if currWord[0] == '@': return if currWord.isnumeric(): return if currWord.isdecimal(): return if currWord.isspace(): return try: if os.path.exists("/bin/"+currWord): return except: pass try: if os.path.exists("/usr/bin/"+currWord): return except: pass try: if os.path.exists("/sbin/"+currWord): return except: pass if not self.spellChecker.check(currWord): self.env['runtime']['outputManager'].presentText(_('misspelled'), soundIcon='mispell', interrupt=False, flush=False) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onCursorChange/65000-char_delete_echo.py000066400000000000000000000031011317357605400260650ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return 'No Description found' def run(self): if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'charDeleteEcho'): return # detect typing or chilling if self.env['screen']['newCursor']['x'] >= self.env['screen']['oldCursor']['x']: return # More than just a deletion happend if self.env['runtime']['screenManager'].isDelta(): return # no deletion if not self.env['runtime']['screenManager'].isNegativeDelta(): return # too much for a single backspace... # word begin produce a diff wiht len == 2 |a | others with 1 |a| if len(self.env['screen']['newNegativeDelta']) > 2: return currNegativeDelta = self.env['screen']['newNegativeDelta'] if len(currNegativeDelta.strip()) != len(currNegativeDelta) and \ currNegativeDelta.strip() != '': currNegativeDelta = currNegativeDelta.strip() self.env['runtime']['outputManager'].presentText(currNegativeDelta, interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onCursorChange/66000-exit_review_mode.py000066400000000000000000000013541317357605400261770ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('exits review mode') def run(self): if not self.env['runtime']['settingsManager'].getSettingAsBool('review', 'leaveReviewOnCursorChange'): return if self.env['runtime']['cursorManager'].isReviewMode(): self.env['runtime']['cursorManager'].clearReviewCursor() def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onCursorChange/__init__.py000077500000000000000000000000001317357605400237150ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/commands/onHeartBeat/000077500000000000000000000000001317357605400210675ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/commands/onHeartBeat/2000-GetSessionInfo.py000077500000000000000000000013271317357605400247250ustar00rootroot00000000000000#!/bin/python import time # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug import time import datetime class command(): def __init__(self): pass def initialize(self, environment): self.env = environment self.lastTime = datetime.datetime.now() self.lastDateString = '' self.lastTimeString = '' def shutdown(self): pass def getDescription(self): return 'No Description found' def run(self): self.env['runtime']['screenDriver'].getSessionInformation() def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onHeartBeat/76000-time.py000077500000000000000000000062251317357605400230610ustar00rootroot00000000000000#!/bin/python import time # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug import time import datetime class command(): def __init__(self): pass def initialize(self, environment): self.env = environment self.lastTime = datetime.datetime.now() self.lastDateString = '' self.lastTimeString = '' def shutdown(self): pass def getDescription(self): return 'No Description found' def run(self): if not self.env['runtime']['settingsManager'].getSettingAsBool('time', 'enabled'): return onMinutes = self.env['runtime']['settingsManager'].getSetting('time', 'onMinutes') delaySec = self.env['runtime']['settingsManager'].getSettingAsInt('time', 'delaySec') # no need if onMinutes == '' and delaySec <= 0: return onMinutes = onMinutes.split(',') now = datetime.datetime.now() # ignore onMinutes if there is a delaySec if delaySec > 0: if int((now-self.lastTime).total_seconds()) < delaySec: return else: # shoul announce? if not str(now.minute) in onMinutes: return # already announced? if now.hour == self.lastTime.hour: if now.minute == self.lastTime.minute: return dateFormat = self.env['runtime']['settingsManager'].getSetting('general', 'dateFormat') dateString = datetime.datetime.strftime(now, dateFormat) presentDate = self.env['runtime']['settingsManager'].getSettingAsBool('time', 'presentDate') and \ self.lastDateString != dateString presentTime = self.env['runtime']['settingsManager'].getSettingAsBool('time', 'presentTime') # no changed value to announce if not (presentDate or presentTime): return timeFormat = self.env['runtime']['settingsManager'].getSetting('general', 'timeFormat') timeString = datetime.datetime.strftime(now, timeFormat) if self.env['runtime']['settingsManager'].getSettingAsBool('time', 'interrupt'): self.env['runtime']['outputManager'].interruptOutput() if self.env['runtime']['settingsManager'].getSettingAsBool('time', 'announce'): self.env['runtime']['outputManager'].playSoundIcon('announce') if presentTime: # present the time self.env['runtime']['outputManager'].presentText(_('Autotime: {0}').format(timeString), soundIcon='', interrupt=False) # and date if changes if presentDate: self.env['runtime']['outputManager'].presentText(dateString , soundIcon='', interrupt=False) self.lastDateString = dateString self.lastTime = datetime.datetime.now() self.lastTimeString = timeString def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onHeartBeat/__init__.py000077500000000000000000000000001317357605400231710ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/commands/onHeartBeat/deactive/000077500000000000000000000000001317357605400226535ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/commands/onHeartBeat/deactive/1.echo.py000077500000000000000000000010331317357605400243020ustar00rootroot00000000000000#!/bin/python import time # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug import time class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return 'No Description found' def run(self): print(time.time()) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onInput/000077500000000000000000000000001317357605400203275ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/commands/onInput/10000-shut_up.py000066400000000000000000000025771317357605400230410ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return '' def run(self): if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'interruptOnKeyPress'): return if self.env['runtime']['inputManager'].noKeyPressed(): return if self.env['runtime']['screenManager'].isScreenChange(): return if len(self.env['input']['currInput']) <= len(self.env['input']['prevInput']): return # if the filter is set if self.env['runtime']['settingsManager'].getSetting('keyboard', 'interruptOnKeyPressFilter').strip() != '': filterList = self.env['runtime']['settingsManager'].getSetting('keyboard', 'interruptOnKeyPressFilter').split(',') for currInput in self.env['input']['currInput']: if not currInput in filterList: return self.env['runtime']['outputManager'].interruptOutput() def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onInput/15000-enable_temp_speech.py000066400000000000000000000020741317357605400251510ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('disables speech until next keypress') def run(self): if self.env['runtime']['inputManager'].noKeyPressed(): return if len(self.env['input']['prevInput']) >0: return if not self.env['commandBuffer']['enableSpeechOnKeypress']: return self.env['runtime']['settingsManager'].setSetting('speech', 'enabled', str(self.env['commandBuffer']['enableSpeechOnKeypress'])) self.env['commandBuffer']['enableSpeechOnKeypress'] = False self.env['runtime']['outputManager'].presentText(_("speech enabled"), soundIcon='SpeechOn', interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onInput/80000-capslock.py000066400000000000000000000014741317357605400231530ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return 'No description found' def run(self): if self.env['input']['oldCapsLock'] == self.env['input']['newCapsLock']: return if self.env['input']['newCapsLock']: self.env['runtime']['outputManager'].presentText(_("Capslock on"), interrupt=True) else: self.env['runtime']['outputManager'].presentText(_("Capslock off"), interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onInput/80300-scrolllock.py000066400000000000000000000015061317357605400235220ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return 'No description found' def run(self): if self.env['input']['oldScrollLock'] == self.env['input']['newScrollLock']: return if self.env['input']['newScrollLock']: self.env['runtime']['outputManager'].presentText(_("Scrolllock on"), interrupt=True) else: self.env['runtime']['outputManager'].presentText(_("Scrolllock off"), interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onInput/80500-numlock.py000066400000000000000000000014671317357605400230330ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return 'No description found' def run(self): if self.env['input']['oldNumLock'] == self.env['input']['newNumLock']: return if self.env['input']['newNumLock']: self.env['runtime']['outputManager'].presentText(_("Numlock on"), interrupt=True) else: self.env['runtime']['outputManager'].presentText(_("Numlock off"), interrupt=True) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onInput/__init__.py000066400000000000000000000000001317357605400224260ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/commands/onPlugInputDevice/000077500000000000000000000000001317357605400222775ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/commands/onPlugInputDevice/50000-UpdateDevices.py000077500000000000000000000010211317357605400260350ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return 'No description found' def run(self): self.env['runtime']['inputManager'].updateInputDevices() def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onPlugInputDevice/__init__.py000077500000000000000000000000001317357605400244010ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/commands/onScreenChanged/000077500000000000000000000000001317357605400217215ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/commands/onScreenChanged/10000-shut_up.py000066400000000000000000000010101317357605400244100ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return '' def run(self): self.env['runtime']['outputManager'].interruptOutput() def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onScreenChanged/80000-screen_change_announcement.py000066400000000000000000000013731317357605400303020ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return 'No Description found' def run(self): self.env['runtime']['outputManager'].presentText(_("screen {0}").format(self.env['screen']['newTTY']),soundIcon='ChangeTTY', interrupt=True, flush=False) self.env['runtime']['outputManager'].presentText(self.env['screen']['newContentText'], interrupt=False, flush=False) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onScreenChanged/85000-reset_marks.py000066400000000000000000000007611317357605400252700ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return 'No Description found' def run(self): self.env['runtime']['cursorManager'].clearMarks() def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onScreenChanged/89000-leave_review_mode.py000066400000000000000000000011721317357605400264330ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return 'No Description found' def run(self): if not self.env['runtime']['settingsManager'].getSettingAsBool('review', 'leaveReviewOnScreenChange'): return self.env['runtime']['cursorManager'].clearReviewCursor() def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onScreenChanged/__init__.py000066400000000000000000000000001317357605400240200ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/commands/onScreenUpdate/000077500000000000000000000000001317357605400216125ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/commands/onScreenUpdate/56000-highlight_tracking.py000066400000000000000000000014121317357605400264630ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return _('enables or disables tracking of highlighted') def run(self): if not self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'highlight'): return self.env['runtime']['outputManager'].presentText(self.env['screen']['newAttribDelta'], soundIcon='', interrupt=True, flush=False) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onScreenUpdate/60000-history.py000066400000000000000000000045171317357605400243370ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return '' def run(self): if self.env['screen']['newAttribDelta'] != '': return if self.env['runtime']['screenManager'].isScreenChange(): return if self.env['runtime']['cursorManager'].isCursorVerticalMove(): return if not (self.env['runtime']['inputManager'].getLastDeepestInput() in [['KEY_UP'],['KEY_DOWN']]): return prevLine = self.env['screen']['oldContentText'].split('\n')[self.env['screen']['newCursor']['y']] currLine = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] if prevLine == currLine: if self.env['screen']['newDelta'] != '': return if not currLine.isspace(): currPrompt = currLine.find('$') rootPrompt = currLine.find('#') if currPrompt <= 0: if rootPrompt > 0: currPrompt = rootPrompt else: announce = currLine if currPrompt > 0: remove_digits = str.maketrans('0123456789', ' ') if prevLine[:currPrompt].translate(remove_digits) == currLine[:currPrompt].translate(remove_digits): announce = currLine[currPrompt+1:] else: announce = currLine if currLine.isspace(): self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True, flush=False) else: self.env['runtime']['outputManager'].presentText(announce, interrupt=True, flush=False) self.env['commandsIgnore']['onScreenUpdate']['CHAR_DELETE_ECHO'] = True self.env['commandsIgnore']['onScreenUpdate']['CHAR_ECHO'] = True self.env['commandsIgnore']['onScreenUpdate']['INCOMING_IGNORE'] = True def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onScreenUpdate/70000-incoming.py000066400000000000000000000026131317357605400244350ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return 'No Description found' def run(self): if not self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'autoReadIncoming'): return # is there something to read? if not self.env['runtime']['screenManager'].isDelta(): return # this must be a keyecho or something if len(self.env['screen']['newDelta'].strip(' \n\t')) <= 1: if abs(self.env['screen']['newCursor']['x'] - self.env['screen']['oldCursor']['x']) >= 1: # if len(self.env['screen']['newDelta'].strip(' \n\t0123456789')) <= 2: return if abs(self.env['screen']['newCursor']['y'] - self.env['screen']['oldCursor']['y']) == 1: # if len(self.env['screen']['newDelta'].strip(' \n\t0123456789')) <= 2: return self.env['runtime']['outputManager'].presentText(self.env['screen']['newDelta'], interrupt=False, flush=False) def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onScreenUpdate/75000-incoming_promote.py000066400000000000000000000025211317357605400262050ustar00rootroot00000000000000#!/bin/python import time # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return 'No Description found' def run(self): if not self.env['runtime']['settingsManager'].getSettingAsBool('promote', 'enabled'): return if self.env['runtime']['settingsManager'].getSetting('promote', 'list').strip(" \t\n") == '': return if int(time.time() - self.env['input']['lastInputTime']) < self.env['runtime']['settingsManager'].getSettingAsInt('promote', 'inactiveTimeoutSec'): return if len(self.env['runtime']['settingsManager'].getSetting('promote', 'list')) == 0: return for promote in self.env['runtime']['settingsManager'].getSetting('promote', 'list').split(','): if promote in self.env['screen']['newDelta']: self.env['runtime']['outputManager'].playSoundIcon('PromotedText') self.env['input']['lastInputTime'] = time.time() return def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onScreenUpdate/__init__.py000077500000000000000000000000001317357605400237140ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/commands/onSwitchApplicationProfile/000077500000000000000000000000001317357605400241765ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/commands/onSwitchApplicationProfile/__init__.py000066400000000000000000000000011317357605400262760ustar00rootroot00000000000000 fenrir-1.5.1/src/fenrir/commands/onSwitchApplicationProfile/default.py000066400000000000000000000015501317357605400261750ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return 'No description found' def load(self): return print('--------------') print('default') print('load new',self.env['screen']['newApplication']) print('--------------') def unload(self): return print('--------------') print('default') print('unload old',self.env['screen']['oldApplication']) print('--------------') def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onSwitchApplicationProfile/inactive/000077500000000000000000000000001317357605400260005ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/commands/onSwitchApplicationProfile/inactive/agetty.py000066400000000000000000000015101317357605400276440ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return 'No description found' def load(self): print('--------------') print('agetty') print('load new',self.env['screen']['newApplication']) print('--------------') def unload(self): print('--------------') print('agetty') print('unload old',self.env['screen']['oldApplication']) print('--------------') def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onSwitchApplicationProfile/inactive/bash.py000066400000000000000000000015021317357605400272650ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return 'No description found' def load(self): print('--------------') print('bash') print('load new',self.env['screen']['newApplication']) print('--------------') def unload(self): print('--------------') print('bash') print('unload old',self.env['screen']['oldApplication']) print('--------------') def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/onSwitchApplicationProfile/inactive/vim.py000066400000000000000000000014761317357605400271550ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return 'No description found' def load(self): print('--------------') print('vim') print('load new',self.env['screen']['newApplication']) print('--------------') def unload(self): print('--------------') print('vim') print('unload old',self.env['screen']['oldApplication']) print('--------------') def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/commands/switchTrigger_template.py000066400000000000000000000007531317357605400237720ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class command(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getDescription(self): return 'No description found' def unload(self): pass def load(self): pass def setCallback(self, callback): pass fenrir-1.5.1/src/fenrir/core/000077500000000000000000000000001317357605400160225ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/core/__init__.py000066400000000000000000000000001317357605400201210ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/core/applicationManager.py000066400000000000000000000016201317357605400221710ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class applicationManager(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def getCurrentApplication(self): currApp = self.env['screen']['newApplication'].upper() if not currApp: currApp == 'DEFAULT' if currApp == '': currApp == 'DEFAULT' return currApp def getPrevApplication(self): prevApp = self.env['screen']['oldApplication'].upper() if not prevApp: prevApp == 'DEFAULT' if prevApp == '': prevApp == 'DEFAULT' return prevApp def isApplicationChange(self): return self.env['screen']['oldApplication'] != self.env['screen']['newApplication'] fenrir-1.5.1/src/fenrir/core/commandData.py000066400000000000000000000011151317357605400206020ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug import time # used as shared memory between commands # use this in your own commands commandBuffer = { 'enableSpeechOnKeypress': False, 'genericList':[], 'genericListSource':'', 'genericListSelection': 0, 'clipboard':[], 'currClipboard': 0, 'Marks':{'1':None, '2':None}, 'bookMarks':{}, 'windowArea':{}, } # used by the commandManager commandInfo = { #'currCommand': '', 'lastCommandExecutionTime': time.time(), 'lastCommandRequestTime': time.time(), } fenrir-1.5.1/src/fenrir/core/commandManager.py000066400000000000000000000312651317357605400213140ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. import glob, os, time, inspect currentdir = os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe())))) fenrirPath = os.path.dirname(currentdir) from core import debug from utils import module_utils class commandManager(): def __init__(self): pass def initialize(self, environment): self.env = environment # commands self.env['commands'] = {} self.env['commandsIgnore'] = {} for commandFolder in self.env['general']['commandFolderList']: self.env['runtime']['commandManager'].loadCommands(commandFolder) if self.env['runtime']['settingsManager'].getSetting('general', 'commandPath') != '': self.env['runtime']['commandManager'].loadCommands(commandFolder, self.env['runtime']['settingsManager'].getSetting('general', 'commandPath')) # scripts for scriptKey self.env['runtime']['commandManager'].loadScriptCommands() def shutdown(self): for commandFolder in self.env['general']['commandFolderList']: self.env['runtime']['commandManager'].shutdownCommands(commandFolder) def loadCommands(self, section='commands',commandPath=''): if commandPath =='': commandPath = fenrirPath+ "/commands/" if not commandPath.endswith('/'): commandPath += '/' commandFolder = commandPath + section +"/" if not os.path.exists(commandFolder): self.env['runtime']['debug'].writeDebugOut("commandFolder not exists:" + commandFolder ,debug.debugLevel.WARNING) return if not os.path.isdir(commandFolder): self.env['runtime']['debug'].writeDebugOut("commandFolder not a directory:" + commandFolder ,debug.debugLevel.ERROR) return if not os.access(commandFolder, os.R_OK): self.env['runtime']['debug'].writeDebugOut("commandFolder not readable:" + commandFolder ,debug.debugLevel.ERROR) return self.env['commands'][section] = {} self.env['commandsIgnore'][section] = {} commandList = glob.glob(commandFolder+'*') for command in commandList: try: fileName, fileExtension = os.path.splitext(command) fileName = fileName.split('/')[-1] if fileName.startswith('__'): continue try: if self.env['commands'][section][fileName.upper()] != None: continue except: pass if fileExtension.lower() == '.py': command_mod = module_utils.importModule(fileName, command) self.env['commands'][section][fileName.upper()] = command_mod.command() self.env['commandsIgnore'][section][fileName.upper()[fileName.upper().find('-')+1:]+'_IGNORE'] = False self.env['commands'][section][fileName.upper()].initialize(self.env) self.env['runtime']['debug'].writeDebugOut("Load command:" + section + "." + fileName.upper() ,debug.debugLevel.INFO, onAnyLevel=True) except Exception as e: self.env['runtime']['debug'].writeDebugOut("Loading command:" + command ,debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) continue def loadScriptCommands(self, section='commands', scriptPath=''): if scriptPath =='': scriptPath = self.env['runtime']['settingsManager'].getSetting('general', 'scriptPath') if not scriptPath.endswith('/'): scriptPath += '/' if not os.path.exists(scriptPath): if os.path.exists(fenrirPath +'/../../config/scripts/'): scriptPath = fenrirPath +'/../../config/scripts/' else: self.env['runtime']['debug'].writeDebugOut("scriptpath not exists:" + scriptPath ,debug.debugLevel.WARNING) return if not os.path.isdir(scriptPath): self.env['runtime']['debug'].writeDebugOut("scriptpath not a directory:" + scriptPath ,debug.debugLevel.ERROR) return if not os.access(scriptPath, os.R_OK): self.env['runtime']['debug'].writeDebugOut("scriptpath not readable:" + scriptPath ,debug.debugLevel.ERROR) return commandList = glob.glob(scriptPath+'*') subCommand = fenrirPath + '/commands/commands/subprocess.py' for command in commandList: invalid = False try: fileName, fileExtension = os.path.splitext(command) fileName = fileName.split('/')[-1] if fileName.startswith('__'): continue if fileName.upper() in self.env['commands'][section]: continue command_mod = module_utils.importModule(fileName ,subCommand) self.env['commands'][section][fileName.upper()] = command_mod.command() self.env['commands'][section][fileName.upper()].initialize(self.env,command) self.env['runtime']['debug'].writeDebugOut("Load script:" + section + "." + fileName.upper() ,debug.debugLevel.INFO, onAnyLevel=True) commSettings = fileName.upper().split('__-__') if len(commSettings) == 1: keys = commSettings[0] elif len(commSettings) == 2: keys = commSettings[1] elif len(commSettings) > 2: continue keys = keys.split('__+__') shortcutKeys = [] shortcut = [] for key in keys: if not self.env['runtime']['settingsManager'].isValidKey(key.upper()): self.env['runtime']['debug'].writeDebugOut("invalid key : "+ key.upper() + ' command:' +commandName ,debug.debugLevel.WARNING) invalid = True break shortcutKeys.append(key.upper()) if invalid: continue if not 'KEY_SCRIPT' in shortcutKeys: shortcutKeys.append('KEY_SCRIPT') shortcut.append(1) shortcut.append(sorted(shortcutKeys)) self.env['bindings'][str(shortcut)] = fileName.upper() except Exception as e: self.env['runtime']['debug'].writeDebugOut("Loading script:" + command ,debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) continue def shutdownCommands(self, section): for command in sorted(self.env['commands'][section]): try: self.env['commands'][section][command].shutdown() del self.env['commands'][section][command] except Exception as e: self.env['runtime']['debug'].writeDebugOut("Shutdown command:" + section + "." + command ,debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) continue def executeSwitchTrigger(self, trigger, unLoadScript, loadScript): if self.env['runtime']['screenManager'].isSuspendingScreen(): return #unload oldScript = unLoadScript if self.commandExists(oldScript, trigger): try: self.env['runtime']['debug'].writeDebugOut("Executing switchtrigger.unload:" + trigger + "." + oldScript ,debug.debugLevel.INFO) self.env['commands'][trigger][oldScript].unload() except Exception as e: self.env['runtime']['debug'].writeDebugOut("Executing trigger:" + trigger + "." + oldScript ,debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) #load newScript = loadScript if self.commandExists(newScript, trigger): try: self.env['runtime']['debug'].writeDebugOut("Executing switchtrigger.load:" + trigger + "." + newScript ,debug.debugLevel.INFO) self.env['commands'][trigger][newScript].load() except Exception as e: self.env['runtime']['debug'].writeDebugOut("Executing trigger:" + trigger + "." + newScript ,debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) def executeDefaultTrigger(self, trigger, force=False): if not force: if self.env['runtime']['screenManager'].isSuspendingScreen(): return for command in sorted(self.env['commands'][trigger]): if self.commandExists(command, trigger): try: if self.env['commandsIgnore'][trigger][command[command.find('-')+1:]+'_IGNORE']: self.env['commandsIgnore'][trigger][command[command.find('-')+1:]+'_IGNORE'] = False self.env['runtime']['debug'].writeDebugOut("Ignore trigger.command:" + trigger + "." + command ,debug.debugLevel.INFO) else: self.env['runtime']['debug'].writeDebugOut("Executing trigger.command:" + trigger + "." + command ,debug.debugLevel.INFO) self.env['commands'][trigger][command].run() except Exception as e: self.env['runtime']['debug'].writeDebugOut("Executing trigger:" + trigger + "." + command + str(e) ,debug.debugLevel.ERROR) def executeCommand(self, command, section = 'commands'): if self.env['runtime']['screenManager'].isSuspendingScreen(): return if self.commandExists(command, section): try: if self.env['runtime']['helpManager'].isTutorialMode() and section != 'help': self.env['runtime']['debug'].writeDebugOut("Tutorial for command:" + section + "." + command ,debug.debugLevel.INFO) description = self.getCommandDescription(command, section) self.env['runtime']['outputManager'].presentText(description, interrupt=True) else: self.env['runtime']['debug'].writeDebugOut("Executing command:" + section + "." + command ,debug.debugLevel.INFO) self.runCommand(command, section) except Exception as e: self.env['runtime']['debug'].writeDebugOut("Executing command:" + section + "." + command +' ' + str(e),debug.debugLevel.ERROR) def runCommand(self, command, section = 'commands'): if self.commandExists(command, section): try: self.env['runtime']['debug'].writeDebugOut("runCommand command:" + section + "." + command ,debug.debugLevel.INFO) self.env['commands'][section][command].run() except Exception as e: self.env['runtime']['debug'].writeDebugOut("runCommand command:" + section + "." + command +' ' + str(e),debug.debugLevel.ERROR) self.env['commandInfo']['lastCommandExecutionTime'] = time.time() def getCommandDescription(self, command, section = 'commands'): if self.commandExists(command, section): try: return self.env['commands'][section][command].getDescription() except Exception as e: self.env['runtime']['debug'].writeDebugOut('commandManager.getCommandDescription:' + str(e),debug.debugLevel.ERROR) self.env['commandInfo']['lastCommandExecutionTime'] = time.time() def commandExists(self, command, section = 'commands'): return( command in self.env['commands'][section]) def getShortcutForCommand(self, command): shortcut = '' try: shortcut = list(self.env['bindings'].keys())[list(self.env['bindings'].values()).index(command)] except: pass return shortcut fenrir-1.5.1/src/fenrir/core/cursorManager.py000066400000000000000000000114771317357605400212160ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class cursorManager(): def __init__(self): pass def initialize(self, environment): self.env = environment def shutdown(self): pass def clearMarks(self): self.env['commandBuffer']['Marks']['1'] = None self.env['commandBuffer']['Marks']['2'] = None def isMarkSet(self): return self.env['commandBuffer']['Marks']['1'] != None def isSingleMark(self): return self.env['commandBuffer']['Marks']['1'] != None and \ self.env['commandBuffer']['Marks']['2'] == None def isMultibleMark(self): return self.env['commandBuffer']['Marks']['1'] != None and \ self.env['commandBuffer']['Marks']['2'] != None def setMark(self): currCursor = None if self.env['screen']['newCursorReview']: currCursor = self.env['screen']['newCursorReview'].copy() else: currCursor = self.env['screen']['newCursor'].copy() if not self.env['commandBuffer']['Marks']['1']: self.env['commandBuffer']['Marks']['1'] = currCursor.copy() return 1 else: self.env['commandBuffer']['Marks']['2'] = currCursor.copy() return 2 return 0 def getReviewOrTextCursor(self): if self.env['screen']['newCursorReview']: return self.env['screen']['newCursorReview'].copy() else: return self.env['screen']['newCursor'].copy() def clearReviewCursor(self): if not self.isReviewMode(): return self.env['screen']['oldCursorReview'] = None self.env['screen']['newCursorReview'] = None def isCursorHorizontalMove(self): return self.env['screen']['newCursor']['x'] != self.env['screen']['oldCursor']['x'] def isCursorVerticalMove(self): return self.env['screen']['newCursor']['y'] != self.env['screen']['oldCursor']['y'] def isReviewMode(self): return self.env['screen']['newCursorReview'] != None def enterReviewModeCurrTextCursor(self, overwrite=False): if self.isReviewMode() and not overwrite: return self.env['screen']['oldCursorReview'] = self.env['screen']['newCursorReview'] if not self.env['screen']['newCursorReview']: self.env['screen']['newCursorReview'] = self.env['screen']['newCursor'].copy() if self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'highlight') and \ self.env['screen']['newCursorAttrib'] != None: if self.env['screen']['newCursorAttrib']['x'] != 0 and \ self.env['screen']['newCursorAttrib']['y'] != 0: self.env['screen']['newCursorReview'] = self.env['screen']['newCursorAttrib'].copy() def setReviewCursorPosition(self, x, y): if not self.isReviewMode(): self.enterReviewModeCurrTextCursor() self.env['screen']['oldCursorReview'] = self.env['screen']['newCursorReview'] self.env['screen']['newCursorReview']['x'] = x self.env['screen']['newCursorReview']['y'] = y def isApplicationWindowSet(self): try: currApp = self.env['runtime']['applicationManager'].getCurrentApplication() if self.env['commandBuffer']['windowArea'][currApp]['1'] != None: return True except: pass return False def setWindowForApplication(self): if not self.env['commandBuffer']['Marks']['1']: return False if not self.env['commandBuffer']['Marks']['2']: return False currApp = self.env['runtime']['applicationManager'].getCurrentApplication() self.env['commandBuffer']['windowArea'][currApp] = {} if self.env['commandBuffer']['Marks']['1']['x'] * self.env['commandBuffer']['Marks']['1']['y'] <= \ self.env['commandBuffer']['Marks']['2']['x'] * self.env['commandBuffer']['Marks']['2']['y']: self.env['commandBuffer']['windowArea'][currApp]['1'] = self.env['commandBuffer']['Marks']['1'].copy() self.env['commandBuffer']['windowArea'][currApp]['2'] = self.env['commandBuffer']['Marks']['2'].copy() else: self.env['commandBuffer']['windowArea'][currApp]['1'] = self.env['commandBuffer']['Marks']['2'].copy() self.env['commandBuffer']['windowArea'][currApp]['2'] = self.env['commandBuffer']['Marks']['1'].copy() return True def clearWindowForApplication(self): currApp = self.env['runtime']['applicationManager'].getCurrentApplication() try: del self.env['commandBuffer']['windowArea'][currApp] except: return False return True fenrir-1.5.1/src/fenrir/core/debug.py000066400000000000000000000003371317357605400174650ustar00rootroot00000000000000#!/usr/bin/python from enum import Enum class debugLevel(Enum): DEACTIVE = 0 ERROR = 1 WARNING = 2 INFO = 3 def __int__(self): return self.value def __str__(self): return self.name fenrir-1.5.1/src/fenrir/core/debugManager.py000066400000000000000000000045171317357605400207640ustar00rootroot00000000000000#!/usr/bin/python # Debugger module for the Fenrir screen reader. from core import debug from datetime import datetime class debugManager(): def __init__(self, fileName='/var/log/fenrir.log'): self._fileName = fileName self._file = None self._fileOpened = False def initialize(self, environment): self.env = environment def shutdown(self): self.closeDebugFile() def __del__(self): try: self.shutdown() except: pass def openDebugFile(self, fileName = ''): self._fileOpened = False if fileName != '': self._fileName = fileName if self._fileName != '': self._file = open(self._fileName,'a') self._fileOpened = True def writeDebugOut(self, text, level = debug.debugLevel.DEACTIVE, onAnyLevel=False): mode = self.env['runtime']['settingsManager'].getSetting('general','debugMode') if mode == '': mode = 'FILE' mode = mode.upper().split(',') fileMode = 'FILE' in mode printMode = 'PRINT' in mode if (self.env['runtime']['settingsManager'].getSettingAsInt('general','debugLevel') < int(level)) and \ not (onAnyLevel and self.env['runtime']['settingsManager'].getSettingAsInt('general','debugLevel') > int(debug.debugLevel.DEACTIVE)) : if self._fileOpened: self.closeDebugFile() return else: if not self._fileOpened and fileMode: self.openDebugFile() if onAnyLevel: msg = 'ANY '+ str(level) + ' ' + str(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')) else: msg = str(level) +' ' + str(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f') ) msg += ': ' + text if printMode: print(msg) if fileMode: self._file.write(msg + '\n') def closeDebugFile(self): if not self._fileOpened: return False if self._file != None: self._file.close() self._fileOpened = False return True def getDebugFile(self): return self._fileName def setDebugFile(self, fileName): self.closeDebugFile() self._fileName = fileName fenrir-1.5.1/src/fenrir/core/environment.py000066400000000000000000000013671317357605400207470ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from core.settingsData import settingsData from core.runtimeData import runtimeData from core.screenData import screenData from core.outputData import outputData from core.generalData import generalData from core import commandData from core.inputData import inputData from core.punctuationData import punctuationData environment = { 'screen': screenData, 'runtime': runtimeData, 'general': generalData, 'settings': settingsData, 'commandInfo': commandData.commandInfo, 'commandBuffer': commandData.commandBuffer, 'input': inputData, 'punctuation': punctuationData, 'output': outputData, 'soundIcons': {}, 'bindings': {}, } fenrir-1.5.1/src/fenrir/core/eventData.py000077500000000000000000000010071317357605400203100ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from enum import Enum class fenrirEventType(Enum): Ignore = 0 StopMainLoop = 1 ScreenUpdate = 2 KeyboardInput = 3 BrailleInput = 4 PlugInputDevice = 5 BrailleFlush = 6 ScreenChanged = 7 HeartBeat = 8 # for time based scheduling ExecuteCommand = 9 def __int__(self): return self.value def __str__(self): return self.name fenrir-1.5.1/src/fenrir/core/eventManager.py000066400000000000000000000064461317357605400210220ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from core.eventData import fenrirEventType from queue import Empty import time from multiprocessing import Queue from multiprocessing.sharedctypes import Value from ctypes import c_bool class eventManager(): def __init__(self): self.running = Value(c_bool, True) self._eventQueue = Queue() # multiprocessing.Queue() self.cleanEventQueue() def initialize(self, environment): self.env = environment def shutdown(self): self.cleanEventQueue() def proceedEventLoop(self): event = self._eventQueue.get() st = time.time() self.eventDispatcher(event) #print('NET loop ' + str(time.time() - st)) def eventDispatcher(self, event): self.env['runtime']['debug'].writeDebugOut('eventManager:eventDispatcher:start: event:' + str(event['Type']) + ' QueueSize:' + str( self._eventQueue.qsize()),debug.debugLevel.INFO) if not event: return if not event['Type']: return if event['Type'] == fenrirEventType.Ignore: return elif event['Type'] == fenrirEventType.StopMainLoop: self.handleStopMainLoop(event) elif event['Type'] == fenrirEventType.ScreenUpdate: self.env['runtime']['fenrirManager'].handleScreenUpdate(event) elif event['Type'] == fenrirEventType.KeyboardInput: self.env['runtime']['fenrirManager'].handleInput(event) elif event['Type'] == fenrirEventType.BrailleInput: pass elif event['Type'] == fenrirEventType.PlugInputDevice: self.env['runtime']['fenrirManager'].handlePlugInputDevice(event) pass elif event['Type'] == fenrirEventType.BrailleFlush: pass elif event['Type'] == fenrirEventType.ScreenChanged: self.env['runtime']['fenrirManager'].handleScreenChange(event) elif event['Type'] == fenrirEventType.HeartBeat: self.env['runtime']['fenrirManager'].handleHeartBeat(event) elif event['Type'] == fenrirEventType.ExecuteCommand: self.env['runtime']['fenrirManager'].handleExecuteCommand(event) def isMainEventLoopRunning(self): return self.running.value == 1 def startMainEventLoop(self): self.running.value = 1 while( self.isMainEventLoopRunning()): self.proceedEventLoop() def handleStopMainLoop(self, event): self.running.value = 0 time.sleep(0.1) def stopMainEventLoop(self): self._eventQueue.put({"Type":fenrirEventType.StopMainLoop,"Data":None}) def cleanEventQueue(self): if self._eventQueue.empty(): return try: while True: self._eventQueue.get_nowait() except Empty: pass def getEventQueue(self): return self._eventQueue def getRunning(self): return self.running def putToEventQueue(self,event, data): if not isinstance(event, fenrirEventType): return False self._eventQueue.put({"Type":event,"Data":data}) return True fenrir-1.5.1/src/fenrir/core/fenrirManager.py000066400000000000000000000231611317357605400211570ustar00rootroot00000000000000#!/bin/env python3 # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. import os, sys, signal, time from core import i18n from core import settingsManager from core import debug from core.eventData import fenrirEventType import argparse class fenrirManager(): def __init__(self): self.initialized = False cliArgs = self.handleArgs() if not cliArgs: return try: self.environment = settingsManager.settingsManager().initFenrirConfig(cliArgs, self) if not self.environment: raise RuntimeError('Cannot Initialize. Maybe the configfile is not available or not parseable') except RuntimeError: raise self.environment['runtime']['outputManager'].presentText(_("Start Fenrir"), soundIcon='ScreenReaderOn', interrupt=True) signal.signal(signal.SIGINT, self.captureSignal) signal.signal(signal.SIGTERM, self.captureSignal) self.initialized = True self.modifierInput = False self.singleKeyCommand = False self.command = '' def handleArgs(self): args = None parser = argparse.ArgumentParser(description="Fenrir Help") parser.add_argument('-s', '--setting', metavar='SETTING-FILE', default='/etc/fenrir/settings/settings.conf', help='Use a specified settingsfile') parser.add_argument('-o', '--options', metavar='SECTION#SETTING=VALUE,..', default='', help='Overwrite options in given settings file') parser.add_argument('-d', '--debug', action='store_true', help='Turns on Debugmode') parser.add_argument('-p', '--print', action='store_true', help='Print debug messages on screen') try: args = parser.parse_args() except Exception as e: parser.print_help() return args def proceed(self): if not self.initialized: return self.environment['runtime']['eventManager'].startMainEventLoop() self.shutdown() def handleInput(self, event): #startTime = time.time() eventReceived = self.environment['runtime']['inputManager'].getInputEvent() if self.environment['runtime']['inputManager'].noKeyPressed(): self.environment['runtime']['inputManager'].clearLastDeepInput() if eventReceived: if self.environment['runtime']['screenManager'].isSuspendingScreen(): self.environment['runtime']['inputManager'].writeEventBuffer() else: if self.environment['runtime']['helpManager'].isTutorialMode(): self.environment['runtime']['inputManager'].clearEventBuffer() self.detectCommand() if self.modifierInput: self.environment['runtime']['inputManager'].clearEventBuffer() if self.singleKeyCommand: if self.environment['runtime']['inputManager'].noKeyPressed(): self.environment['runtime']['inputManager'].clearEventBuffer() else: self.environment['runtime']['inputManager'].writeEventBuffer() if self.environment['runtime']['inputManager'].noKeyPressed(): self.modifierInput = False self.singleKeyCommand = False if self.environment['input']['keyForeward'] > 0: self.environment['input']['keyForeward'] -=1 self.environment['runtime']['screenManager'].update('onInput') self.environment['runtime']['commandManager'].executeDefaultTrigger('onInput') #print('handleInput:',time.time() - startTime) def handleExecuteCommand(self, event): if event['Data'] == '': return command = event['Data'] if self.environment['runtime']['helpManager'].isTutorialMode(): if self.environment['runtime']['commandManager'].commandExists( command, 'help'): self.environment['runtime']['commandManager'].executeCommand( command, 'help') return self.environment['runtime']['commandManager'].executeCommand( command, 'commands') def handleScreenChange(self, event): self.environment['runtime']['screenManager'].update('onScreenChange') ''' if self.environment['runtime']['applicationManager'].isApplicationChange(): self.environment['runtime']['commandManager'].executeDefaultTrigger('onApplicationChange') self.environment['runtime']['commandManager'].executeSwitchTrigger('onSwitchApplicationProfile', \ self.environment['runtime']['applicationManager'].getPrevApplication(), \ self.environment['runtime']['applicationManager'].getCurrentApplication()) ''' self.environment['runtime']['commandManager'].executeDefaultTrigger('onScreenChanged') self.environment['runtime']['screenManager'].update('onScreenChange') def handleScreenUpdate(self, event): #startTime = time.time() self.environment['runtime']['screenManager'].update('onUpdate') ''' if self.environment['runtime']['applicationManager'].isApplicationChange(): self.environment['runtime']['commandManager'].executeDefaultTrigger('onApplicationChange') self.environment['runtime']['commandManager'].executeSwitchTrigger('onSwitchApplicationProfile', \ self.environment['runtime']['applicationManager'].getPrevApplication(), \ self.environment['runtime']['applicationManager'].getCurrentApplication()) ''' # timout for the last keypress if time.time() - self.environment['runtime']['inputManager'].getLastInputTime() >= 0.3: self.environment['runtime']['inputManager'].clearLastDeepInput() # has cursor changed? if self.environment['runtime']['cursorManager'].isCursorVerticalMove() or \ self.environment['runtime']['cursorManager'].isCursorHorizontalMove(): self.environment['runtime']['commandManager'].executeDefaultTrigger('onCursorChange') self.environment['runtime']['commandManager'].executeDefaultTrigger('onScreenUpdate') self.environment['runtime']['inputManager'].clearLastDeepInput() #print('handleScreenUpdate:',time.time() - startTime) def handlePlugInputDevice(self, event): self.environment['runtime']['commandManager'].executeDefaultTrigger('onPlugInputDevice', force=True) def handleHeartBeat(self, event): self.environment['runtime']['commandManager'].executeDefaultTrigger('onHeartBeat',force=True) #self.environment['runtime']['outputManager'].brailleText(flush=False) def detectCommand(self): if self.environment['input']['keyForeward'] > 0: return if self.environment['runtime']['inputManager'].isKeyPress(): self.modifierInput = self.environment['runtime']['inputManager'].currKeyIsModifier() else: if not self.environment['runtime']['inputManager'].noKeyPressed(): if self.singleKeyCommand: self.singleKeyCommand = len( self.environment['runtime']['inputManager'].getLastDeepestInput() ) == 1 # key is already released. we need the old one if not( self.singleKeyCommand and self.environment['runtime']['inputManager'].noKeyPressed()): shortcut = self.environment['runtime']['inputManager'].getCurrShortcut() self.command = self.environment['runtime']['inputManager'].getCommandForShortcut(shortcut) if not self.modifierInput: if self.environment['runtime']['inputManager'].isKeyPress(): if self.command != '': self.singleKeyCommand = True if not (self.singleKeyCommand or self.modifierInput): return # fire event if self.command != '': if self.modifierInput: self.environment['runtime']['eventManager'].putToEventQueue(fenrirEventType.ExecuteCommand, self.command) self.command = '' else: if self.singleKeyCommand: if self.environment['runtime']['inputManager'].noKeyPressed(): self.environment['runtime']['eventManager'].putToEventQueue(fenrirEventType.ExecuteCommand, self.command) self.command = '' def shutdownRequest(self): try: self.environment['runtime']['eventManager'].stopMainEventLoop() except: pass def captureSignal(self, siginit, frame): self.shutdownRequest() def shutdown(self): self.environment['runtime']['eventManager'].stopMainEventLoop() self.environment['runtime']['outputManager'].presentText(_("Quit Fenrir"), soundIcon='ScreenReaderOff', interrupt=True) self.environment['runtime']['eventManager'].cleanEventQueue() time.sleep(1) for currManager in self.environment['general']['managerList']: if self.environment['runtime'][currManager]: self.environment['runtime'][currManager].shutdown() del self.environment['runtime'][currManager] self.environment = None fenrir-1.5.1/src/fenrir/core/generalData.py000066400000000000000000000011431317357605400206020ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug generalData = { 'args': None, 'tutorialMode': False, 'currUser':'', 'prevUser':'', 'managerList':['processManager','punctuationManager','cursorManager','applicationManager','commandManager' ,'screenManager','inputManager','outputManager','helpManager','eventManager','debug'], 'commandFolderList':['commands','onInput', 'onCursorChange', 'onScreenUpdate','onScreenChanged','onHeartBeat', 'onPlugInputDevice' ,'onApplicationChange','onSwitchApplicationProfile','help',], } fenrir-1.5.1/src/fenrir/core/helpManager.py000077500000000000000000000071301317357605400206230ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class helpManager(): def __init__(self): self.helpDict = {} self.tutorialListIndex = None def initialize(self, environment): self.env = environment def shutdown(self): pass def toggleTutorialMode(self): self.setTutorialMode(not self.env['general']['tutorialMode']) def setTutorialMode(self, newTutorialMode): self.env['general']['tutorialMode'] = newTutorialMode if newTutorialMode: self.createHelpDict() self.env['bindings'][str([1, ['KEY_ESC']])] = 'TOGGLE_TUTORIAL_MODE' self.env['bindings'][str([1, ['KEY_UP']])] = 'PREV_HELP' self.env['bindings'][str([1, ['KEY_DOWN']])] = 'NEXT_HELP' self.env['bindings'][str([1, ['KEY_SPACE']])] = 'CURR_HELP' else: try: del(self.env['bindings'][str([1, ['KEY_ESC']])]) del(self.env['bindings'][str([1, ['KEY_UP']])]) del(self.env['bindings'][str([1, ['KEY_DOWN']])]) del(self.env['bindings'][str([1, ['KEY_SPACE']])]) except: pass def isTutorialMode(self): return self.env['general']['tutorialMode'] def getCommandHelpText(self, command, section = 'commands'): commandName = command.lower() commandName = commandName.split('__-__')[0] commandName = commandName.replace('_',' ') commandName = commandName.replace('_',' ') if command == 'TOGGLE_TUTORIAL_MODE': commandDescription = _('toggles the tutorial mode') else: commandDescription = self.env['runtime']['commandManager'].getCommandDescription( command, section = 'commands') if commandDescription == '': commandDescription = 'no Description available' commandShortcut = self.env['runtime']['commandManager'].getShortcutForCommand( command) commandShortcut = commandShortcut.replace('KEY_',' ') commandShortcut = commandShortcut.replace('[','') commandShortcut = commandShortcut.replace(']','') commandShortcut = commandShortcut.replace("'",'') if commandShortcut == '': commandShortcut = 'unbound' helptext = commandName + ', Shortcut ' + commandShortcut + ', Description ' + commandDescription return helptext def createHelpDict(self, section = 'commands'): self.helpDict = {} for command in sorted(self.env['commands'][section].keys()): self.helpDict[len(self.helpDict)] = self.getCommandHelpText(command, section) if len(self.helpDict) > 0: self.tutorialListIndex = 0 else: self.tutorialListIndex = None def getHelpForCurrentIndex(self): if self.tutorialListIndex == None: return '' return self.helpDict[self.tutorialListIndex] def nextIndex(self): if self.tutorialListIndex == None: return self.tutorialListIndex += 1 if self.tutorialListIndex >= len(self.helpDict): self.tutorialListIndex = 0 def prevIndex(self): if self.tutorialListIndex == None: return self.tutorialListIndex -= 1 if self.tutorialListIndex < 0: self.tutorialListIndex = len(self.helpDict) - 1 fenrir-1.5.1/src/fenrir/core/i18n.py000066400000000000000000000004101317357605400171460ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. import gettext import locale # the only function we really need to call here is gettext.install. Python3 has simplified this. gettext.install("fenrir") fenrir-1.5.1/src/fenrir/core/inputData.py000066400000000000000000000215141317357605400203300ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug import time inputData = { 'currInput': [], 'prevDeepestInput': [], 'eventBuffer': [], 'shortcutRepeat': 0, 'fenrirKey': [], 'scriptKey': [], 'keyForeward': 0, 'lastInputTime':time.time(), 'oldNumLock': True, 'newNumLock':True, 'oldScrollLock': True, 'newScrollLock':True, 'oldCapsLock':False, 'newCapsLock':False } inputEvent = { 'EventName': '', 'EventValue': '', 'EventSec': 0, 'EventUsec': 0, 'EventState': 0, } keyNames = ['KEY_RESERVED', 'KEY_ESC', 'KEY_1', 'KEY_2', 'KEY_3', 'KEY_4', 'KEY_5', 'KEY_6', 'KEY_7', 'KEY_8', 'KEY_9', 'KEY_0', 'KEY_MINUS', 'KEY_EQUAL', 'KEY_BACKSPACE', 'KEY_TAB', 'KEY_Q', 'KEY_W', 'KEY_E', 'KEY_R', 'KEY_T', 'KEY_Y', 'KEY_U', 'KEY_I', 'KEY_O', 'KEY_P', 'KEY_LEFTBRACE', 'KEY_RIGHTBRACE', 'KEY_ENTER', 'KEY_LEFTCTRL', 'KEY_A', 'KEY_S', 'KEY_D', 'KEY_F', 'KEY_G', 'KEY_H', 'KEY_J', 'KEY_K', 'KEY_L', 'KEY_SEMICOLON', 'KEY_APOSTROPHE', 'KEY_GRAVE', 'KEY_LEFTSHIFT', 'KEY_BACKSLASH', 'KEY_Z', 'KEY_X', 'KEY_C', 'KEY_V', 'KEY_B', 'KEY_N', 'KEY_M', 'KEY_COMMA', 'KEY_DOT', 'KEY_SLASH', 'KEY_RIGHTSHIFT', 'KEY_KPASTERISK', 'KEY_LEFTALT', 'KEY_SPACE', 'KEY_CAPSLOCK', 'KEY_F1', 'KEY_F2', 'KEY_F3', 'KEY_F4', 'KEY_F5', 'KEY_F6', 'KEY_F7', 'KEY_F8', 'KEY_F9', 'KEY_F10', 'KEY_NUMLOCK', 'KEY_SCROLLLOCK', 'KEY_KP7', 'KEY_KP8', 'KEY_KP9', 'KEY_KPMINUS', 'KEY_KP4', 'KEY_KP5', 'KEY_KP6', 'KEY_KPPLUS', 'KEY_KP1', 'KEY_KP2', 'KEY_KP3', 'KEY_KP0', 'KEY_KPDOT', 'KEY_ZENKAKUHANKAKU', 'KEY_102ND', 'KEY_F11', 'KEY_F12', 'KEY_RO', 'KEY_KATAKANA', 'KEY_HIRAGANA', 'KEY_HENKAN', 'KEY_KATAKANAHIRAGANA', 'KEY_MUHENKAN', 'KEY_KPJPCOMMA', 'KEY_KPENTER', 'KEY_RIGHTCTRL', 'KEY_KPSLASH', 'KEY_SYSRQ', 'KEY_RIGHTALT', 'KEY_LINEFEED', 'KEY_HOME', 'KEY_UP', 'KEY_PAGEUP', 'KEY_LEFT', 'KEY_RIGHT', 'KEY_END', 'KEY_DOWN', 'KEY_PAGEDOWN', 'KEY_INSERT', 'KEY_DELETE', 'KEY_MACRO', 'KEY_MIN_INTERESTING', 'KEY_MUTE', 'KEY_VOLUMEDOWN', 'KEY_VOLUMEUP', 'KEY_POWER', 'KEY_KPEQUAL', 'KEY_KPPLUSMINUS', 'KEY_PAUSE', 'KEY_SCALE', 'KEY_KPCOMMA', 'KEY_HANGEUL', 'KEY_HANGUEL', 'KEY_HANJA', 'KEY_YEN', 'KEY_LEFTMETA', 'KEY_RIGHTMETA', 'KEY_COMPOSE', 'KEY_STOP', 'KEY_AGAIN', 'KEY_PROPS', 'KEY_UNDO', 'KEY_FRONT', 'KEY_COPY', 'KEY_OPEN', 'KEY_PASTE', 'KEY_FIND', 'KEY_CUT', 'KEY_HELP', 'KEY_MENU', 'KEY_CALC', 'KEY_SETUP', 'KEY_SLEEP', 'KEY_WAKEUP', 'KEY_FILE', 'KEY_SENDFILE', 'KEY_DELETEFILE', 'KEY_XFER', 'KEY_PROG1', 'KEY_PROG2', 'KEY_WWW', 'KEY_MSDOS', 'KEY_COFFEE', 'KEY_SCREENLOCK', 'KEY_DIRECTION', 'KEY_ROTATE_DISPLAY', 'KEY_CYCLEWINDOWS', 'KEY_MAIL', 'KEY_BOOKMARKS', 'KEY_COMPUTER', 'KEY_BACK', 'KEY_FORWARD', 'KEY_CLOSECD', 'KEY_EJECTCD', 'KEY_EJECTCLOSECD', 'KEY_NEXTSONG', 'KEY_PLAYPAUSE', 'KEY_PREVIOUSSONG', 'KEY_STOPCD', 'KEY_RECORD', 'KEY_REWIND', 'KEY_PHONE', 'KEY_ISO', 'KEY_CONFIG', 'KEY_HOMEPAGE', 'KEY_REFRESH', 'KEY_EXIT', 'KEY_MOVE', 'KEY_EDIT', 'KEY_SCROLLUP', 'KEY_SCROLLDOWN', 'KEY_KPLEFTPAREN', 'KEY_KPRIGHTPAREN', 'KEY_NEW', 'KEY_REDO', 'KEY_F13', 'KEY_F14', 'KEY_F15', 'KEY_F16', 'KEY_F17', 'KEY_F18', 'KEY_F19', 'KEY_F20', 'KEY_F21', 'KEY_F22', 'KEY_F23', 'KEY_F24', 'KEY_PLAYCD', 'KEY_PAUSECD', 'KEY_PROG3', 'KEY_PROG4', 'KEY_DASHBOARD', 'KEY_SUSPEND', 'KEY_CLOSE', 'KEY_PLAY', 'KEY_FASTFORWARD', 'KEY_BASSBOOST', 'KEY_PRINT', 'KEY_HP', 'KEY_CAMERA', 'KEY_SOUND', 'KEY_QUESTION', 'KEY_EMAIL', 'KEY_CHAT', 'KEY_SEARCH', 'KEY_CONNECT', 'KEY_FINANCE', 'KEY_SPORT', 'KEY_SHOP', 'KEY_ALTERASE', 'KEY_CANCEL', 'KEY_BRIGHTNESSDOWN', 'KEY_BRIGHTNESSUP', 'KEY_MEDIA', 'KEY_SWITCHVIDEOMODE', 'KEY_KBDILLUMTOGGLE', 'KEY_KBDILLUMDOWN', 'KEY_KBDILLUMUP', 'KEY_SEND', 'KEY_REPLY', 'KEY_FORWARDMAIL', 'KEY_SAVE', 'KEY_DOCUMENTS', 'KEY_BATTERY', 'KEY_BLUETOOTH', 'KEY_WLAN', 'KEY_UWB', 'KEY_UNKNOWN', 'KEY_VIDEO_NEXT', 'KEY_VIDEO_PREV', 'KEY_BRIGHTNESS_CYCLE', 'KEY_BRIGHTNESS_AUTO', 'KEY_BRIGHTNESS_ZERO', 'KEY_DISPLAY_OFF', 'KEY_WIMAX', 'KEY_WWAN', 'KEY_RFKILL', 'KEY_MICMUTE', 'BTN_0', 'BTN_MISC', 'BTN_1', 'BTN_2', 'BTN_3', 'BTN_4', 'BTN_5', 'BTN_6', 'BTN_7', 'BTN_8', 'BTN_9', 'BTN_LEFT', 'BTN_MOUSE', 'BTN_RIGHT', 'BTN_MIDDLE', 'BTN_SIDE', 'BTN_EXTRA', 'BTN_FORWARD', 'BTN_BACK', 'BTN_TASK', 'BTN_JOYSTICK', 'BTN_TRIGGER', 'BTN_THUMB', 'BTN_THUMB2', 'BTN_TOP', 'BTN_TOP2', 'BTN_PINKIE', 'BTN_BASE', 'BTN_BASE2', 'BTN_BASE3', 'BTN_BASE4', 'BTN_BASE5', 'BTN_BASE6', 'BTN_DEAD', 'BTN_A', 'BTN_GAMEPAD', 'BTN_SOUTH', 'BTN_B', 'BTN_EAST', 'BTN_C', 'BTN_NORTH', 'BTN_X', 'BTN_WEST', 'BTN_Y', 'BTN_Z', 'BTN_TL', 'BTN_TR', 'BTN_TL2', 'BTN_TR2', 'BTN_SELECT', 'BTN_START', 'BTN_MODE', 'BTN_THUMBL', 'BTN_THUMBR', 'BTN_DIGI', 'BTN_TOOL_PEN', 'BTN_TOOL_RUBBER', 'BTN_TOOL_BRUSH', 'BTN_TOOL_PENCIL', 'BTN_TOOL_AIRBRUSH', 'BTN_TOOL_FINGER', 'BTN_TOOL_MOUSE', 'BTN_TOOL_LENS', 'BTN_TOOL_QUINTTAP', 'BTN_TOUCH', 'BTN_STYLUS', 'BTN_STYLUS2', 'BTN_TOOL_DOUBLETAP', 'BTN_TOOL_TRIPLETAP', 'BTN_TOOL_QUADTAP', 'BTN_GEAR_DOWN', 'BTN_WHEEL', 'BTN_GEAR_UP', 'KEY_OK', 'KEY_SELECT', 'KEY_GOTO', 'KEY_CLEAR', 'KEY_POWER2', 'KEY_OPTION', 'KEY_INFO', 'KEY_TIME', 'KEY_VENDOR', 'KEY_ARCHIVE', 'KEY_PROGRAM', 'KEY_CHANNEL', 'KEY_FAVORITES', 'KEY_EPG', 'KEY_PVR', 'KEY_MHP', 'KEY_LANGUAGE', 'KEY_TITLE', 'KEY_SUBTITLE', 'KEY_ANGLE', 'KEY_ZOOM', 'KEY_MODE', 'KEY_KEYBOARD', 'KEY_SCREEN', 'KEY_PC', 'KEY_TV', 'KEY_TV2', 'KEY_VCR', 'KEY_VCR2', 'KEY_SAT', 'KEY_SAT2', 'KEY_CD', 'KEY_TAPE', 'KEY_RADIO', 'KEY_TUNER', 'KEY_PLAYER', 'KEY_TEXT', 'KEY_DVD', 'KEY_AUX', 'KEY_MP3', 'KEY_AUDIO', 'KEY_VIDEO', 'KEY_DIRECTORY', 'KEY_LIST', 'KEY_MEMO', 'KEY_CALENDAR', 'KEY_RED', 'KEY_GREEN', 'KEY_YELLOW', 'KEY_BLUE', 'KEY_CHANNELUP', 'KEY_CHANNELDOWN', 'KEY_FIRST', 'KEY_LAST', 'KEY_AB', 'KEY_NEXT', 'KEY_RESTART', 'KEY_SLOW', 'KEY_SHUFFLE', 'KEY_BREAK', 'KEY_PREVIOUS', 'KEY_DIGITS', 'KEY_TEEN', 'KEY_TWEN', 'KEY_VIDEOPHONE', 'KEY_GAMES', 'KEY_ZOOMIN', 'KEY_ZOOMOUT', 'KEY_ZOOMRESET', 'KEY_WORDPROCESSOR', 'KEY_EDITOR', 'KEY_SPREADSHEET', 'KEY_GRAPHICSEDITOR', 'KEY_PRESENTATION', 'KEY_DATABASE', 'KEY_NEWS', 'KEY_VOICEMAIL', 'KEY_ADDRESSBOOK', 'KEY_MESSENGER', 'KEY_BRIGHTNESS_TOGGLE', 'KEY_DISPLAYTOGGLE', 'KEY_SPELLCHECK', 'KEY_LOGOFF', 'KEY_DOLLAR', 'KEY_EURO', 'KEY_FRAMEBACK', 'KEY_FRAMEFORWARD', 'KEY_CONTEXT_MENU', 'KEY_MEDIA_REPEAT', 'KEY_10CHANNELSUP', 'KEY_10CHANNELSDOWN', 'KEY_IMAGES', 'KEY_DEL_EOL', 'KEY_DEL_EOS', 'KEY_INS_LINE', 'KEY_DEL_LINE', 'KEY_FN', 'KEY_FN_ESC', 'KEY_FN_F1', 'KEY_FN_F2', 'KEY_FN_F3', 'KEY_FN_F4', 'KEY_FN_F5', 'KEY_FN_F6', 'KEY_FN_F7', 'KEY_FN_F8', 'KEY_FN_F9', 'KEY_FN_F10', 'KEY_FN_F11', 'KEY_FN_F12', 'KEY_FN_1', 'KEY_FN_2', 'KEY_FN_D', 'KEY_FN_E', 'KEY_FN_F', 'KEY_FN_S', 'KEY_FN_B', 'KEY_BRL_DOT1', 'KEY_BRL_DOT2', 'KEY_BRL_DOT3', 'KEY_BRL_DOT4', 'KEY_BRL_DOT5', 'KEY_BRL_DOT6', 'KEY_BRL_DOT7', 'KEY_BRL_DOT8', 'KEY_BRL_DOT9', 'KEY_BRL_DOT10', 'KEY_NUMERIC_0', 'KEY_NUMERIC_1', 'KEY_NUMERIC_2', 'KEY_NUMERIC_3', 'KEY_NUMERIC_4', 'KEY_NUMERIC_5', 'KEY_NUMERIC_6', 'KEY_NUMERIC_7', 'KEY_NUMERIC_8', 'KEY_NUMERIC_9', 'KEY_NUMERIC_STAR', 'KEY_NUMERIC_POUND', 'KEY_NUMERIC_A', 'KEY_NUMERIC_B', 'KEY_NUMERIC_C', 'KEY_NUMERIC_D', 'KEY_CAMERA_FOCUS', 'KEY_WPS_BUTTON', 'KEY_TOUCHPAD_TOGGLE', 'KEY_TOUCHPAD_ON', 'KEY_TOUCHPAD_OFF', 'KEY_CAMERA_ZOOMIN', 'KEY_CAMERA_ZOOMOUT', 'KEY_CAMERA_UP', 'KEY_CAMERA_DOWN', 'KEY_CAMERA_LEFT', 'KEY_CAMERA_RIGHT', 'KEY_ATTENDANT_ON', 'KEY_ATTENDANT_OFF', 'KEY_ATTENDANT_TOGGLE', 'KEY_LIGHTS_TOGGLE', 'BTN_DPAD_UP', 'BTN_DPAD_DOWN', 'BTN_DPAD_LEFT', 'BTN_DPAD_RIGHT', 'KEY_ALS_TOGGLE', 'KEY_BUTTONCONFIG', 'KEY_TASKMANAGER', 'KEY_JOURNAL', 'KEY_CONTROLPANEL', 'KEY_APPSELECT', 'KEY_SCREENSAVER', 'KEY_VOICECOMMAND', 'KEY_BRIGHTNESS_MIN', 'KEY_BRIGHTNESS_MAX', 'KEY_KBDINPUTASSIST_PREV', 'KEY_KBDINPUTASSIST_NEXT', 'KEY_KBDINPUTASSIST_PREVGROUP', 'KEY_KBDINPUTASSIST_NEXTGROUP', 'KEY_KBDINPUTASSIST_ACCEPT', 'KEY_KBDINPUTASSIST_CANCEL', 'KEY_RIGHT_UP', 'KEY_RIGHT_DOWN', 'KEY_LEFT_UP', 'KEY_LEFT_DOWN', 'KEY_ROOT_MENU', 'KEY_MEDIA_TOP_MENU', 'KEY_NUMERIC_11', 'KEY_NUMERIC_12', 'KEY_AUDIO_DESC', 'KEY_3D_MODE', 'KEY_NEXT_FAVORITE', 'KEY_STOP_RECORD', 'KEY_PAUSE_RECORD', 'KEY_VOD', 'KEY_UNMUTE', 'KEY_DATA', 'KEY_FASTREVERSE', 'KEY_SLOWREVERSE', 'BTN_TRIGGER_HAPPY', 'BTN_TRIGGER_HAPPY1', 'BTN_TRIGGER_HAPPY2', 'BTN_TRIGGER_HAPPY3', 'BTN_TRIGGER_HAPPY4', 'BTN_TRIGGER_HAPPY5', 'BTN_TRIGGER_HAPPY6', 'BTN_TRIGGER_HAPPY7', 'BTN_TRIGGER_HAPPY8', 'BTN_TRIGGER_HAPPY9', 'BTN_TRIGGER_HAPPY10', 'BTN_TRIGGER_HAPPY11', 'BTN_TRIGGER_HAPPY12', 'BTN_TRIGGER_HAPPY13', 'BTN_TRIGGER_HAPPY14', 'BTN_TRIGGER_HAPPY15', 'BTN_TRIGGER_HAPPY16', 'BTN_TRIGGER_HAPPY17', 'BTN_TRIGGER_HAPPY18', 'BTN_TRIGGER_HAPPY19', 'BTN_TRIGGER_HAPPY20', 'BTN_TRIGGER_HAPPY21', 'BTN_TRIGGER_HAPPY22', 'BTN_TRIGGER_HAPPY23', 'BTN_TRIGGER_HAPPY24', 'BTN_TRIGGER_HAPPY25', 'BTN_TRIGGER_HAPPY26', 'BTN_TRIGGER_HAPPY27', 'BTN_TRIGGER_HAPPY28', 'BTN_TRIGGER_HAPPY29', 'BTN_TRIGGER_HAPPY30', 'BTN_TRIGGER_HAPPY31', 'BTN_TRIGGER_HAPPY32', 'BTN_TRIGGER_HAPPY33', 'BTN_TRIGGER_HAPPY34', 'BTN_TRIGGER_HAPPY35', 'BTN_TRIGGER_HAPPY36', 'BTN_TRIGGER_HAPPY37', 'BTN_TRIGGER_HAPPY38', 'BTN_TRIGGER_HAPPY39', 'BTN_TRIGGER_HAPPY40', 'KEY_FENRIR', 'KEY_SCRIPT', 'KEY_ALT', 'KEY_CTRL', 'KEY_META', 'KEY_SHIFT'] fenrir-1.5.1/src/fenrir/core/inputManager.py000066400000000000000000000247601317357605400210370ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. import time from core import debug class inputManager(): def __init__(self): self.setLedState = True def initialize(self, environment): self.env = environment self.env['runtime']['settingsManager'].loadDriver(\ self.env['runtime']['settingsManager'].getSetting('keyboard', 'driver'), 'inputDriver') self.updateInputDevices() # init LEDs with current state self.env['input']['newNumLock'] = self.env['runtime']['inputDriver'].getLedState() self.env['input']['oldNumLock'] = self.env['input']['newNumLock'] self.env['input']['newCapsLock'] = self.env['runtime']['inputDriver'].getLedState(1) self.env['input']['oldCapsLock'] = self.env['input']['newCapsLock'] self.env['input']['newScrollLock'] = self.env['runtime']['inputDriver'].getLedState(2) self.env['input']['oldScrollLock'] = self.env['input']['newScrollLock'] self.lastDeepestInput = [] self.lastInputTime = time.time() def shutdown(self): self.removeAllDevices() self.env['runtime']['settingsManager'].shutdownDriver('inputDriver') def getInputEvent(self): eventReceived = False mEvent = self.env['runtime']['inputDriver'].getInputEvent() if mEvent: mEvent['EventName'] = self.convertEventName(mEvent['EventName']) eventReceived = True self.env['input']['prevInput'] = self.env['input']['currInput'].copy() if mEvent['EventState'] == 0: if mEvent['EventName'] in self.env['input']['currInput']: self.env['input']['currInput'].remove(mEvent['EventName']) if len(self.env['input']['currInput']) > 1: self.env['input']['currInput'] = sorted(self.env['input']['currInput']) elif len(self.env['input']['currInput']) == 0: self.env['input']['shortcutRepeat'] = 1 self.setLedState = self.handleLedStates(mEvent) self.lastInputTime = time.time() elif mEvent['EventState'] == 1: if not mEvent['EventName'] in self.env['input']['currInput']: self.env['input']['currInput'].append(mEvent['EventName']) if len(self.env['input']['currInput']) > 1: self.env['input']['currInput'] = sorted(self.env['input']['currInput']) if len(self.lastDeepestInput) < len(self.env['input']['currInput']): self.setLastDeepestInput( self.env['input']['currInput'].copy()) elif self.lastDeepestInput == self.env['input']['currInput']: if time.time() - self.lastInputTime <= self.env['runtime']['settingsManager'].getSettingAsFloat('keyboard','doubleTapTimeout'): self.env['input']['shortcutRepeat'] += 1 else: self.env['input']['shortcutRepeat'] = 1 self.setLedState = self.handleLedStates(mEvent) self.lastInputTime = time.time() elif mEvent['EventState'] == 2: self.lastInputTime = time.time() else: pass self.env['input']['oldNumLock'] = self.env['input']['newNumLock'] self.env['input']['newNumLock'] = self.env['runtime']['inputDriver'].getLedState() self.env['input']['oldCapsLock'] = self.env['input']['newCapsLock'] self.env['input']['newCapsLock'] = self.env['runtime']['inputDriver'].getLedState(1) self.env['input']['oldScrollLock'] = self.env['input']['newScrollLock'] self.env['input']['newScrollLock'] = self.env['runtime']['inputDriver'].getLedState(2) self.env['runtime']['debug'].writeDebugOut("currInput " + str(self.env['input']['currInput'] ) ,debug.debugLevel.INFO) if self.noKeyPressed(): self.env['input']['prevInput'] = [] self.setLedState = True return eventReceived def handleLedStates(self, mEvent): if not self.setLedState: return self.setLedState if mEvent['EventName'] == 'KEY_NUMLOCK': if mEvent['EventState'] == 1 and not self.env['input']['newNumLock'] == 1: self.env['runtime']['inputDriver'].toggleLedState() return False if mEvent['EventState'] == 0 and not self.env['input']['newNumLock'] == 0: self.env['runtime']['inputDriver'].toggleLedState() return False if mEvent['EventName'] == 'KEY_CAPSLOCK': if mEvent['EventState'] == 1 and not self.env['input']['newCapsLock'] == 1: self.env['runtime']['inputDriver'].toggleLedState(1) return False if mEvent['EventState'] == 0 and not self.env['input']['newCapsLock'] == 0: self.env['runtime']['inputDriver'].toggleLedState(1) return False if mEvent['EventName'] == 'KEY_SCROLLLOCK': if mEvent['EventState'] == 1 and not self.env['input']['newScrollLock'] == 1: self.env['runtime']['inputDriver'].toggleLedState(2) return False if mEvent['EventState'] == 0 and not self.env['input']['newScrollLock'] == 0: self.env['runtime']['inputDriver'].toggleLedState(2) return False return self.setLedState def grabAllDevices(self): if self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'): self.env['runtime']['inputDriver'].grabAllDevices() def updateInputDevices(self): try: self.env['runtime']['inputDriver'].updateInputDevices() except: pass def removeAllDevices(self): try: self.env['runtime']['inputDriver'].removeAllDevices() except: pass def convertEventName(self, eventName): if not eventName: return '' if eventName == '': return '' eventName = eventName.upper() if eventName == 'KEY_LEFTCTRL': eventName = 'KEY_CTRL' elif eventName == 'KEY_RIGHTCTRL': eventName = 'KEY_CTRL' elif eventName == 'KEY_LEFTSHIFT': eventName = 'KEY_SHIFT' elif eventName == 'KEY_RIGHTSHIFT': eventName = 'KEY_SHIFT' elif eventName == 'KEY_LEFTALT': eventName = 'KEY_ALT' elif eventName == 'KEY_RIGHTALT': eventName = 'KEY_ALT' elif eventName == 'KEY_LEFTMETA': eventName = 'KEY_META' elif eventName == 'KEY_RIGHTMETA': eventName = 'KEY_META' if self.isFenrirKey(eventName): eventName = 'KEY_FENRIR' if self.isScriptKey(eventName): eventName = 'KEY_SCRIPT' return eventName def clearEventBuffer(self): self.env['runtime']['inputDriver'].clearEventBuffer() def setLastDeepestInput(self, currentDeepestInput): self.lastDeepestInput = currentDeepestInput def clearLastDeepInput(self): self.lastDeepestInput = [] def getLastInputTime(self): return self.lastInputTime def getLastDeepestInput(self): return self.lastDeepestInput def writeEventBuffer(self): try: if self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'): self.env['runtime']['inputDriver'].writeEventBuffer() self.clearEventBuffer() except Exception as e: self.env['runtime']['debug'].writeDebugOut("Error while writeUInput",debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) def noKeyPressed(self): return self.env['input']['currInput'] == [] def isKeyPress(self): return (self.env['input']['prevInput'] == []) and (self.env['input']['currInput'] != []) def getPrevDeepestShortcut(self): shortcut = [] shortcut.append(self.env['input']['shortcutRepeat']) shortcut.append(self.getLastDeepestInput()) return str(shortcut) def getPrevShortcut(self): shortcut = [] shortcut.append(self.env['input']['shortcutRepeat']) shortcut.append(self.env['input']['prevInput']) return str(shortcut) def getCurrShortcut(self, inputSequence = None): shortcut = [] shortcut.append(self.env['input']['shortcutRepeat']) if inputSequence: shortcut.append(inputSequence) else: shortcut.append(self.env['input']['currInput']) if len(self.env['input']['prevInput']) < len(self.env['input']['currInput']): if self.env['input']['shortcutRepeat'] > 1 and not self.shortcutExists(str(shortcut)): shortcut = [] self.env['input']['shortcutRepeat'] = 1 shortcut.append(self.env['input']['shortcutRepeat']) shortcut.append(self.env['input']['currInput']) self.env['runtime']['debug'].writeDebugOut("currShortcut " + str(shortcut) ,debug.debugLevel.INFO) return str(shortcut) def currKeyIsModifier(self): if len(self.getLastDeepestInput()) != 1: return False return (self.env['input']['currInput'][0] =='KEY_FENRIR') or (self.env['input']['currInput'][0] == 'KEY_SCRIPT') def isFenrirKey(self, eventName): return eventName in self.env['input']['fenrirKey'] def isScriptKey(self, eventName): return eventName in self.env['input']['scriptKey'] def getCommandForShortcut(self, shortcut): if not self.shortcutExists(shortcut): return '' return self.env['bindings'][shortcut] def shortcutExists(self, shortcut): return(shortcut in self.env['bindings']) fenrir-1.5.1/src/fenrir/core/outputData.py000066400000000000000000000003761317357605400205340ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. import time from core import debug outputData = { 'nextFlush': time.time(), 'messageText': '', 'messageOffset': None, 'cursorOffset': None, } fenrir-1.5.1/src/fenrir/core/outputManager.py000066400000000000000000000355271317357605400212430ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from utils import line_utils import string, time class outputManager(): def __init__(self): pass def initialize(self, environment): self.env = environment self.env['runtime']['settingsManager'].loadDriver(\ self.env['runtime']['settingsManager'].getSetting('speech', 'driver'), 'speechDriver') self.env['runtime']['settingsManager'].loadDriver(\ self.env['runtime']['settingsManager'].getSetting('sound', 'driver'), 'soundDriver') self.env['runtime']['settingsManager'].loadDriver(\ self.env['runtime']['settingsManager'].getSetting('braille', 'driver'), 'brailleDriver') def shutdown(self): self.env['runtime']['settingsManager'].shutdownDriver('soundDriver') self.env['runtime']['settingsManager'].shutdownDriver('speechDriver') self.env['runtime']['settingsManager'].shutdownDriver('brailleDriver') def presentText(self, text, interrupt=True, soundIcon = '', ignorePunctuation=False, announceCapital=False, flush=True): if text == '': return self.env['runtime']['debug'].writeDebugOut("presentText:\nsoundIcon:'"+soundIcon+"'\nText:\n" + text ,debug.debugLevel.INFO) if self.playSoundIcon(soundIcon, interrupt): self.env['runtime']['debug'].writeDebugOut("soundIcon found" ,debug.debugLevel.INFO) return if (len(text) > 1) and (text.strip(string.whitespace) == ''): return toAnnounceCapital = announceCapital and text[0].isupper() if toAnnounceCapital: if self.playSoundIcon('capital', False): toAnnounceCapital = False self.speakText(text, interrupt, ignorePunctuation,toAnnounceCapital) if flush: self.brailleText(text, flush) def speakText(self, text, interrupt=True, ignorePunctuation=False, announceCapital=False): if not self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled'): self.env['runtime']['debug'].writeDebugOut("Speech disabled in outputManager.speakText",debug.debugLevel.INFO) return if self.env['runtime']['speechDriver'] == None: self.env['runtime']['debug'].writeDebugOut("No speechDriver in outputManager.speakText",debug.debugLevel.ERROR) return if interrupt: self.interruptOutput() try: self.env['runtime']['speechDriver'].setLanguage(self.env['runtime']['settingsManager'].getSetting('speech', 'language')) except Exception as e: self.env['runtime']['debug'].writeDebugOut("setting speech language in outputManager.speakText",debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) try: self.env['runtime']['speechDriver'].setVoice(self.env['runtime']['settingsManager'].getSetting('speech', 'voice')) except Exception as e: self.env['runtime']['debug'].writeDebugOut("Error while setting speech voice in outputManager.speakText",debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) try: if announceCapital: self.env['runtime']['speechDriver'].setPitch(self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'capitalPitch')) else: self.env['runtime']['speechDriver'].setPitch(self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'pitch')) except Exception as e: self.env['runtime']['debug'].writeDebugOut("setting speech pitch in outputManager.speakText",debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) try: self.env['runtime']['speechDriver'].setRate(self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'rate')) except Exception as e: self.env['runtime']['debug'].writeDebugOut("setting speech rate in outputManager.speakText",debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) try: self.env['runtime']['speechDriver'].setModule(self.env['runtime']['settingsManager'].getSetting('speech', 'module')) except Exception as e: self.env['runtime']['debug'].writeDebugOut("setting speech module in outputManager.speakText",debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) try: self.env['runtime']['speechDriver'].setVolume(self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'volume')) except Exception as e: self.env['runtime']['debug'].writeDebugOut("setting speech volume in outputManager.speakText ",debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) try: text = self.env['runtime']['punctuationManager'].proceedPunctuation(text,ignorePunctuation) text = text.replace('\n',' , ') self.env['runtime']['speechDriver'].speak(text) self.env['runtime']['debug'].writeDebugOut("Speak: "+ text,debug.debugLevel.INFO) except Exception as e: self.env['runtime']['debug'].writeDebugOut("\"speak\" in outputManager.speakText ",debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) def brailleText(self, text='', flush=True): if not self.env['runtime']['settingsManager'].getSettingAsBool('braille', 'enabled'): return if self.env['runtime']['brailleDriver'] == None: return if flush: self.env['output']['nextFlush'] = time.time() + self.getFlushTime(text) self.env['output']['messageOffset'] = {'x':0,'y':0} self.env['output']['messageText'] = text displayText = self.getBrailleTextWithOffset(self.env['output']['messageText'], self.env['output']['messageOffset']) self.env['runtime']['brailleDriver'].writeText('flush'+displayText) else: if self.env['output']['nextFlush'] < time.time(): if self.env['output']['messageText'] != '': self.env['output']['messageText'] = '' if self.env['output']['messageOffset'] != None: self.env['output']['messageOffset'] = None cursor = self.getBrailleCursor() x, y, self.env['output']['brlText'] = \ line_utils.getCurrentLine(cursor['x'], cursor['y'], self.env['screen']['newContentText']) displayText = self.getBrailleTextWithOffset(self.env['screen']['newContentText'], self.env['output']['cursorOffset'], cursor) self.env['runtime']['brailleDriver'].writeText('notflush'+displayText) else: displayText = self.getBrailleTextWithOffset(self.env['output']['messageText'], self.env['output']['messageOffset']) self.env['runtime']['brailleDriver'].writeText('flush'+displayText) def getBrailleCursor(self): if self.env['runtime']['settingsManager'].getSetting('braille', 'cursorFollowMode').upper() == 'REVIEW': return self.env['runtime']['cursorManager'].getReviewOrTextCursor() if self.env['runtime']['settingsManager'].getSetting('braille', 'cursorFollowMode').upper() == 'MANUAL': return self.env['runtime']['cursorManager'].getReviewOrTextCursor() if self.env['runtime']['settingsManager'].getSetting('braille', 'cursorFollowMode').upper() == 'LAST': return self.env['runtime']['cursorManager'].getReviewOrTextCursor() return self.env['runtime']['cursorManager'].getReviewOrTextCursor() def getFixCursorCell(self): size = self.env['runtime']['brailleDriver'].getDeviceSize()[0] fixCell = self.env['runtime']['settingsManager'].getSettingAsInt('braille', 'fixCursorOnCell') if fixCell <= -1: return size[0] if fixCell >= size[0]: return size[0] return fixCell def getActiveOffsetAndText(self): if self.env['output']['messageOffset']: return self.env['output']['messageOffset'], self.env['output']['messageText'] if not self.env['output']['cursorOffset']: return self.getBrailleCursor(), self.env['screen']['newContentText'] return self.env['output']['cursorOffset'], self.env['screen']['newContentText'] def getHorizontalPanSize(self): size = self.env['runtime']['brailleDriver'].getDeviceSize() if self.env['runtime']['settingsManager'].getSettingAsInt('braille', 'panSizeHorizontal') <= 0: return size[0] if self.env['runtime']['settingsManager'].getSettingAsInt('braille', 'panSizeHorizontal') >= size[0]: return size[0] return self.env['runtime']['settingsManager'].getSettingAsInt('braille', 'panSizeHorizontal') def getHorizontalPanLevel(self,offsetChange = 0): panned = True panSize = self.getHorizontalPanSize() offset, text = self.getActiveOffsetAndText() currline = text.split('\n')[offset['y']] newOffsetStart = (int(offset['x'] / panSize) + offsetChange) * panSize if newOffsetStart < 0: newOffsetStart = 0 panned = False if newOffsetStart >= len(text): newOffsetStart = int((len(text) - panSize - 1) / panSize) panned = False return newOffsetStart, panned def setPanLeft(self): newPan, panned = self.getHorizontalPanLevel(-1) if self.env['output']['messageOffset']: self.env['output']['messageOffset'] = newPan.copy() else: self.env['output']['cursorOffset'] = newPan.copy() return panned def setPanRight(self): newPan, panned = self.getHorizontalPanLevel(1) if self.env['output']['messageOffset']: self.env['output']['messageOffset'] = newPan.copy() else: self.env['output']['cursorOffset'] = newPan.copy() return panned def removePanning(self): if self.env['output']['messageOffset']: self.env['output']['messageOffset'] = None else: self.env['output']['cursorOffset'] = None def getBrailleTextWithOffset(self, text, offset = None, cursor = None): if text == '': return '' size = self.env['runtime']['brailleDriver'].getDeviceSize() offsetText = text if cursor and not offset: if self.env['runtime']['settingsManager'].getSetting('braille', 'cursorFollowMode').upper() == 'FIXCELL': #fix cell cursorCell = self.getFixCursorCell() offsetStart = cursor['x'] if offsetStart < size[0]: if offsetStart <= cursorCell: return offsetText[0: size[0]] offsetStart -= cursorCell if offsetStart >= len(offsetText): offsetStart = len(offsetText) - 1 else: # page and fallback offsetStart = int(cursor['x'] / size[0]) * size[0] else: if not offset: offset = {'x':0,'y':0} offsetStart = offset['x'] if offsetStart >= len(offsetText): offsetStart = len(offsetText) - size[0] if offsetStart < 0: offsetStart = 0 offsetEnd = offsetStart + size[0] offsetText = offsetText[offsetStart: offsetEnd] return offsetText def interruptOutput(self): self.env['runtime']['speechDriver'].cancel() self.env['runtime']['debug'].writeDebugOut("Interrupt speech",debug.debugLevel.INFO) def clearFlushTime(self): self.setFlushTime(0.0) def setFlushTime(self,newTime): self.env['output']['nextFlush'] = newTime def getFlushTime(self,text=''): if self.env['runtime']['settingsManager'].getSettingAsFloat('braille', 'flushTimeout') < 0 or \ self.env['runtime']['settingsManager'].getSetting('braille', 'flushMode').upper() == 'NONE': return 999999999999 if self.env['runtime']['settingsManager'].getSetting('braille', 'flushMode').upper() == 'FIX': return self.env['runtime']['settingsManager'].getSettingAsFloat('braille', 'flushTimeout') if self.env['runtime']['settingsManager'].getSetting('braille', 'flushMode').upper() == 'CHAR': return self.env['runtime']['settingsManager'].getSettingAsFloat('braille', 'flushTimeout') * len(text) if self.env['runtime']['settingsManager'].getSetting('braille', 'flushMode').upper() == 'WORD': wordsList = text.split(' ') return self.env['runtime']['settingsManager'].getSettingAsFloat('braille', 'flushTimeout') * len( list( filter(None, wordsList) ) ) def playSoundIcon(self, soundIcon = '', interrupt=True): if soundIcon == '': return False soundIcon = soundIcon.upper() if not self.env['runtime']['settingsManager'].getSettingAsBool('sound', 'enabled'): self.env['runtime']['debug'].writeDebugOut("Sound disabled in outputManager.speakText",debug.debugLevel.INFO) return False if self.env['runtime']['soundDriver'] == None: self.env['runtime']['debug'].writeDebugOut("No speechDriver in outputManager.speakText",debug.debugLevel.ERROR) return False try: self.env['runtime']['soundDriver'].setVolume(self.env['runtime']['settingsManager'].getSettingAsFloat('sound', 'volume')) self.env['runtime']['soundDriver'].playSoundFile(self.env['soundIcons'][soundIcon], interrupt) return True except Exception as e: self.env['runtime']['debug'].writeDebugOut("\"playSoundIcon\" in outputManager.speakText ",debug.debugLevel.ERROR) self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) return False def announceActiveCursor(self, interrupt_p=False): if self.env['runtime']['cursorManager'].isReviewMode(): self.presentText(' review cursor ', interrupt=interrupt_p) else: self.presentText(' text cursor ', interrupt=interrupt_p) fenrir-1.5.1/src/fenrir/core/processManager.py000066400000000000000000000070221317357605400213460ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from core.eventData import fenrirEventType import time from threading import Thread from multiprocessing import Process class processManager(): def __init__(self): self._Processes = [] self._Threads = [] def initialize(self, environment): self.env = environment self.running = self.env['runtime']['eventManager'].getRunning() self.addSimpleEventThread(fenrirEventType.HeartBeat, self.heartBeatTimer, multiprocess=True) def shutdown(self): self.terminateAllProcesses() def terminateAllProcesses(self): for proc in self._Processes: try: proc.terminate() except Exception as e: print(e) def heartBeatTimer(self, active): try: time.sleep(0.5) except: pass return time.time() def addCustomEventThread(self, function, pargs = None, multiprocess = False, runOnce = False): eventQueue = self.env['runtime']['eventManager'].getEventQueue() if multiprocess: t = Process(target=self.customEventWorkerThread, args=(eventQueue, function, pargs, runOnce)) self._Processes.append(t) else:# thread not implemented yet t = Thread(target=self.customEventWorkerThread, args=(eventQueue, function, pargs, runOnce)) self._Threads.append(t) t.start() def addSimpleEventThread(self, event, function, pargs = None, multiprocess = False, runOnce = False): if multiprocess: t = Process(target=self.simpleEventWorkerThread, args=(event, function, pargs, runOnce)) self._Processes.append(t) else: t = Thread(target=self.simpleEventWorkerThread, args=(event, function, pargs, runOnce)) self._Threads.append(t) t.start() def customEventWorkerThread(self, eventQueue, function, pargs = None, runOnce = False): #if not isinstance(eventQueue, Queue): # return if not callable(function): return while self.running.value: try: if pargs: function(self.running, eventQueue, pargs) else: function(self.running, eventQueue) except Exception as e: self.env['runtime']['debug'].writeDebugOut('processManager:customEventWorkerThread:function():' + str(e),debug.debugLevel.ERROR) if runOnce: break def simpleEventWorkerThread(self, event, function, pargs = None, runOnce = False): if not isinstance(event, fenrirEventType): return if not callable(function): return while self.running.value: Data = None try: if pargs: Data = function(self.running, pargs) else: Data = function(self.running) except Exception as e: self.env['runtime']['debug'].writeDebugOut('processManager:simpleEventWorkerThread:function():' + str(e),debug.debugLevel.ERROR) self.env['runtime']['eventManager'].putToEventQueue(event, Data) if runOnce: break fenrir-1.5.1/src/fenrir/core/punctuationData.py000066400000000000000000000017661317357605400215510ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug import string punctuationData = { 'LEVELDICT':{ 'none': '', 'some': '#-$~+*-/\\@', 'most': '.,:-$~ +*-/\\@!#%^&*()[]}{<>;', 'all': string.punctuation + ' §', }, 'PUNCTDICT':{ ' ':'space', '&':'and', "'":"apostrophe", '@':'at', '\\':'backslash', '|':'bar', '!':'bang', '^':'carrot', ':':'colon', ',':'comma', '-':'dash', '$':'dollar', '.':'dot', '>':'greater', '`':'grave', '#':'hash', '{':'left brace', '[':'left bracket', '(':'left paren', '<':'less', '%':'percent', '+':'plus', '?':'question', '"':'quote', ')':'right paren', '}':'right brace', ']':'right bracket', ';':'semicolon', '/':'slash', '*':'star', '~':'tilde', '_':'line', '=':'equals', }, 'CUSTOMDICT':{ }, 'EMOTICONDICT':{ ':)':'smiley', ';)':'winking face', 'XD':'loool', ':@':'angry face', ':D':'lought' }, } fenrir-1.5.1/src/fenrir/core/punctuationManager.py000066400000000000000000000074011317357605400222420ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. import string from core import debug class punctuationManager(): def __init__(self): pass def initialize(self, environment): self.env = environment self.allPunctNone = dict.fromkeys(map(ord, string.punctuation +"§ "), ' ') # replace with None: # dot, comma, grave, apostrophe #for char in [ord('`'),ord("'")]: # self.allPunctNone[char] = None # dont restore the following (for announce correct pause) for char in [ord('.'), ord(','), ord(';'), ord(':'), ord('?'), ord('!'), ord('-')]: self.allPunctNone[char] = chr(char) def shutdown(self): pass def removeUnused(self, text, currLevel = ''): # dont translate dot and comma because they create a pause currAllPunctNone = self.allPunctNone.copy() for char in currLevel: try: del currAllPunctNone[ord(char)] except: pass return text.translate(currAllPunctNone) def useCustomDict(self, text, customDict, seperator=''): resultText = str(text) if customDict: for key,item in customDict.items(): resultText = resultText.replace(str(key),seperator + str(item) + seperator) return resultText def usePunctuationDict(self, text, punctuationDict, punctuation): resultText = str(text) if punctuationDict and punctuation and punctuation != '': if ' ' in punctuation: resultText = resultText.replace(' ',' ' + punctuationDict[' '] + ' ') for key,item in punctuationDict.items(): if key in punctuation and key not in ' ': if self.env['runtime']['settingsManager'].getSetting('general', 'respectPunctuationPause') and \ len(key) == 1 and \ key in ",.;:?!-": resultText = resultText.replace(str(key),' ' +str(item) + str(key) + ' ') else: resultText = resultText.replace(str(key),' ' +str(item) + ' ') return resultText def proceedPunctuation(self, text, ignorePunctuation=False): resultText = text resultText = self.useCustomDict(resultText, self.env['punctuation']['CUSTOMDICT']) if self.env['runtime']['settingsManager'].getSettingAsBool('general', 'emoticons'): resultText = self.useCustomDict(resultText, self.env['punctuation']['EMOTICONDICT'], ' ') currPunctLevel = '' if not ignorePunctuation and self.env['runtime']['settingsManager'].getSetting('general', 'punctuationLevel').lower() in self.env['punctuation']['LEVELDICT']: currPunctLevel = self.env['punctuation']['LEVELDICT'][self.env['runtime']['settingsManager'].getSetting('general', 'punctuationLevel').lower()] else: currPunctLevel = string.punctuation +' §' resultText = self.usePunctuationDict(resultText, self.env['punctuation']['PUNCTDICT'], currPunctLevel) #resultText = self.removeUnused(resultText, currPunctLevel) return resultText def cyclePunctuation(self): punctList = list(self.env['punctuation']['LEVELDICT'].keys()) try: currIndex = punctList.index(self.env['runtime']['settingsManager'].getSetting('general', 'punctuationLevel').lower()) # curr punctuation except: return False currIndex += 1 if currIndex >= len(punctList): currIndex = 0 currLevel = punctList[currIndex] self.env['runtime']['settingsManager'].setSetting('general', 'punctuationLevel', currLevel.lower()) return True fenrir-1.5.1/src/fenrir/core/runtimeData.py000066400000000000000000000005601317357605400206520ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug runtimeData = { 'speechDriver': None, 'screenDriver': None, 'soundDriver': None, 'inputDriver': None, 'brailleDriver': None, 'inputManager': None, 'commandManager': None, 'screenManager': None, 'outputManager': None, 'debug':None, } fenrir-1.5.1/src/fenrir/core/screenData.py000066400000000000000000000020611317357605400204440ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug import time screenData = { 'columns': 0, 'lines': 0, 'oldDelta': '', 'oldAttribDelta': '', 'oldNegativeDelta': '', 'oldCursorReview':None, 'oldCursorAttrib':None, 'oldCursor':{'x':0,'y':0}, 'oldContentBytes': b'', 'oldContentText': '', 'oldContentAttrib': None, 'oldApplication': '', 'oldTTY':None, 'newDelta': '', 'newNegativeDelta': '', 'newAttribDelta': '', 'newCursorReview':None, 'newCursorAttrib':None, 'newCursor':{'x':0,'y':0}, 'newContentBytes': b'', 'newContentText': '', 'newContentAttrib': None, 'newTTY':'0', 'newApplication': '', 'lastScreenUpdate': time.time(), 'autoIgnoreScreens':[], } ''' screenData = { 'columns': 0, 'lines': 0, 'textDelta': '', 'negativeDelta': '', 'attribDelta': '', 'reviewCursor':None, #{'x':0,'y':0} 'attribCursor':None, #{'x':0,'y':0} 'textCursor':None, #{'x':0,'y':0} 'content': None, #{'x':0,'y':0} 'Text': '', 'Attrib': None, 'screen': None, 'application': '', 'timestamp': time.time(), } ''' fenrir-1.5.1/src/fenrir/core/screenManager.py000066400000000000000000000136461317357605400211600ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug import time class screenManager(): def __init__(self): pass def initialize(self, environment): self.env = environment self.env['runtime']['settingsManager'].loadDriver(\ self.env['runtime']['settingsManager'].getSetting('screen', 'driver'), 'screenDriver') self.env['runtime']['screenDriver'].getCurrScreen() self.env['runtime']['screenDriver'].getSessionInformation() def shutdown(self): self.env['runtime']['settingsManager'].shutdownDriver('screenDriver') def update(self, trigger='onUpdate'): self.env['runtime']['screenDriver'].getCurrScreen() if trigger == 'onScreenChange': self.env['runtime']['screenDriver'].getSessionInformation() self.env['screen']['oldApplication'] = self.env['screen']['newApplication'] if self.isScreenChange(): self.changeBrailleScreen() if not self.isSuspendingScreen(self.env['screen']['newTTY']): self.env['runtime']['screenDriver'].update(trigger) #if trigger == 'onUpdate' or self.isScreenChange() \ # or len(self.env['screen']['newDelta']) > 6: # self.env['runtime']['screenDriver'].getCurrApplication() self.env['screen']['lastScreenUpdate'] = time.time() def formatAttributes(self, attribute, attributeFormatString = None): if not attributeFormatString: attributeFormatString = self.env['runtime']['settingsManager'].getSetting('general', 'attributeFormatString') if not attributeFormatString: return '' if attributeFormatString == '': return '' attributeFormatString = attributeFormatString.replace('fenrirBGColor', self.env['runtime']['screenDriver'].getFenrirBGColor(attribute)) attributeFormatString = attributeFormatString.replace('fenrirFGColor', self.env['runtime']['screenDriver'].getFenrirFGColor(attribute)) attributeFormatString = attributeFormatString.replace('fenrirUnderline', self.env['runtime']['screenDriver'].getFenrirUnderline(attribute)) attributeFormatString = attributeFormatString.replace('fenrirBold', self.env['runtime']['screenDriver'].getFenrirBold(attribute)) attributeFormatString = attributeFormatString.replace('fenrirBlink', self.env['runtime']['screenDriver'].getFenrirBlink(attribute)) attributeFormatString = attributeFormatString.replace('fenrirFontSize', self.env['runtime']['screenDriver'].getFenrirFontSize(attribute)) attributeFormatString = attributeFormatString.replace('fenrirFont', self.env['runtime']['screenDriver'].getFenrirFont(attribute)) return attributeFormatString def isSuspendingScreen(self, screen = None): if screen == None: screen = self.env['screen']['newTTY'] ignoreScreens = [] fixIgnoreScreens = self.env['runtime']['settingsManager'].getSetting('screen', 'suspendingScreen') if fixIgnoreScreens != '': ignoreScreens.extend(fixIgnoreScreens.split(',')) if self.env['runtime']['settingsManager'].getSettingAsBool('screen', 'autodetectSuspendingScreen'): ignoreScreens.extend(self.env['screen']['autoIgnoreScreens']) self.env['runtime']['debug'].writeDebugOut('screenManager:isSuspendingScreen ' + str(ignoreScreens) + ' '+ str(self.env['screen']['newTTY']),debug.debugLevel.INFO) return (screen in ignoreScreens) def isScreenChange(self): if not self.env['screen']['oldTTY']: return False return self.env['screen']['newTTY'] != self.env['screen']['oldTTY'] def isDelta(self): return self.env['screen']['newDelta'] != '' def isNegativeDelta(self): return self.env['screen']['newNegativeDelta'] != '' def getWindowAreaInText(self, text): if not self.env['runtime']['cursorManager'].isApplicationWindowSet(): return text windowText = '' windowList = text.split('\n') currApp = self.env['runtime']['applicationManager'].getCurrentApplication() windowList = windowList[self.env['commandBuffer']['windowArea'][currApp]['1']['y']:self.env['commandBuffer']['windowArea'][currApp]['2']['y'] + 1] for line in windowList: windowText += line[self.env['commandBuffer']['windowArea'][currApp]['1']['x']:self.env['commandBuffer']['windowArea'][currApp]['2']['x'] + 1] + '\n' return windowText def injectTextToScreen(self, text, screen = None): try: self.env['runtime']['screenDriver'].injectTextToScreen(text, screen) except Exception as e: self.env['runtime']['debug'].writeDebugOut('screenManager:injectTextToScreen ' + str(e),debug.debugLevel.ERROR) def changeBrailleScreen(self): if not self.env['runtime']['settingsManager'].getSettingAsBool('braille', 'enabled'): return if not self.env['runtime']['brailleDriver']: return if self.env['screen']['oldTTY']: if not self.isSuspendingScreen(self.env['screen']['oldTTY']): try: self.env['runtime']['brailleDriver'].leveScreen() except Exception as e: self.env['runtime']['debug'].writeDebugOut('screenManager:changeBrailleScreen:leveScreen ' + str(e),debug.debugLevel.ERROR) if not self.isSuspendingScreen(): try: self.env['runtime']['brailleDriver'].enterScreen(self.env['screen']['newTTY']) except Exception as e: self.env['runtime']['debug'].writeDebugOut('screenManager:changeBrailleScreen:enterScreen ' + str(e),debug.debugLevel.ERROR) fenrir-1.5.1/src/fenrir/core/settingsData.py000066400000000000000000000054171317357605400210350ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug settingsData = { 'sound': { 'enabled': True, 'driver': 'genericDriver', 'theme': 'default', 'volume': 1.0, 'genericPlayFileCommand': 'play -q -v fenrirVolume fenrirSoundFile', 'genericFrequencyCommand': 'play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence' }, 'speech':{ 'enabled': True, 'driver': 'speechdDriver', 'serverPath': '', 'rate': 0.75, 'pitch': 0.5, 'capitalPitch':0.8, 'volume': 1.0, 'module': 'espeak', 'voice': '', 'language': 'english-us', 'autoReadIncoming': True, 'genericSpeechCommand':'espeak -a fenrirVolume -s fenrirRate -p fenrirPitch -v fenrirVoice "fenrirText"', 'fenrirMinVolume':0, 'fenrirMaxVolume':200, 'fenrirMinPitch':0, 'fenrirMaxPitch':99, 'fenrirMinRate':80, 'fenrirMaxRate':450, }, 'braille':{ 'enabled': False, 'driver':'brlapiDriver', 'layout': 'en', 'flushMode': 'word', #NONE,FIX,CHAR,WORD 'flushTimeout': 3, 'cursorFocusMode':'page', # page,fixCell 'fixCursorOnCell': -1, 'cursorFollowMode': 'review', # none, review, last, text 'panSizeHorizontal': 0 # 0 = display size }, 'screen':{ 'driver': 'vcsaDriver', 'encoding': 'cp850', 'screenUpdateDelay': 0.1, 'suspendingScreen': '', 'autodetectSuspendingScreen': False, }, 'general':{ 'debugLevel': debug.debugLevel.DEACTIVE, 'debugMode': 'FILE', 'punctuationProfile':'default', 'punctuationLevel': 'some', 'respectPunctuationPause':True, 'newLinePause':True, 'numberOfClipboards': 10, 'emoticons': True, 'fenrirKeys': 'KEY_KP0,KEY_META', 'scriptKeys': 'KEY_COMPOSE', 'timeFormat': '%I:%M%P', 'dateFormat': '%A, %B %d, %Y', 'autoSpellCheck': False, 'spellCheckLanguage': 'en_US', 'scriptPath': '/usr/share/fenrir/scripts', 'commandPath': '/usr/share/fenrir/commands', 'attributeFormatString': 'Background fenrirBGColor,Foreground fenrirFGColor,fenrirUnderline,fenrirBold,fenrirBlink, Font fenrirFont,Fontsize fenrirFontSize' }, 'focus':{ 'cursor': True, 'highlight': False, }, 'review':{ 'lineBreak': True, 'endOfScreen': True, 'leaveReviewOnCursorChange': True, 'leaveReviewOnScreenChange': True, }, 'promote':{ 'enabled': True, 'inactiveTimeoutSec': 120, 'list': '', }, 'time':{ 'enabled': False, 'presentTime': True, 'presentDate': True, 'delaySec': 0, 'onMinutes': '00,30', 'announce': True, 'interrupt': False, }, 'keyboard':{ 'driver': 'evdev', 'device': 'all', 'grabDevices': True, 'ignoreShortcuts': False, 'keyboardLayout': "desktop", 'charEcho': False, 'charDeleteEcho': True, 'wordEcho': True, 'interruptOnKeyPress': True, 'interruptOnKeyPressFilter': '', 'doubleTapTimeout': 0.2, } } fenrir-1.5.1/src/fenrir/core/settingsManager.py000066400000000000000000000421101317357605400215250ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. import os, inspect currentdir = os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe())))) fenrirPath = os.path.dirname(currentdir) from configparser import ConfigParser from core import debugManager from core import processManager from core import eventManager from core import inputManager from core import outputManager from core import commandManager from core import screenManager from core import punctuationManager from core import cursorManager from core import applicationManager from core import helpManager from core import environment from core import inputData from core.settingsData import settingsData from core import debug from utils import module_utils class settingsManager(): def __init__(self): self.settings = settingsData self.settingArgDict = {} def initialize(self, environment): self.env = environment def shutdown(self): pass def loadShortcuts(self, kbConfigPath=fenrirPath + '/../../config/keyboard/desktop.conf'): kbConfig = open(kbConfigPath,"r") while(True): invalid = False line = kbConfig.readline() if not line: break line = line.replace('\n','') if line.replace(" ","") == '': continue if line.replace(" ","").startswith("#"): continue if line.count("=") != 1: continue sepLine = line.split('=') commandName = sepLine[1].upper() sepLine[0] = sepLine[0].replace(" ","") sepLine[0] = sepLine[0].replace("'","") sepLine[0] = sepLine[0].replace('"',"") keys = sepLine[0].split(',') shortcutKeys = [] shortcutRepeat = 1 shortcut = [] for key in keys: try: shortcutRepeat = int(key) except: if not self.isValidKey(key.upper()): self.env['runtime']['debug'].writeDebugOut("invalid key : "+ key.upper() + ' command:' +commandName ,debug.debugLevel.WARNING) invalid = True break shortcutKeys.append(key.upper()) if invalid: continue shortcut.append(shortcutRepeat) shortcut.append(sorted(shortcutKeys)) if len(shortcutKeys) != 1 and not 'KEY_FENRIR' in shortcutKeys: self.env['runtime']['debug'].writeDebugOut("invalid shortcut (missing KEY_FENRIR): "+ str(shortcut) + ' command:' +commandName ,debug.debugLevel.ERROR) continue self.env['runtime']['debug'].writeDebugOut("Shortcut: "+ str(shortcut) + ' command:' +commandName ,debug.debugLevel.INFO, onAnyLevel=True) self.env['bindings'][str(shortcut)] = commandName kbConfig.close() # fix bindings self.env['bindings'][str([1, ['KEY_F1', 'KEY_FENRIR']])] = 'TOGGLE_TUTORIAL_MODE' def loadSoundIcons(self, soundIconPath): siConfig = open(soundIconPath + '/soundicons.conf',"r") while(True): line = siConfig.readline() if not line: break line = line.replace('\n','') if line.replace(" ","") == '': continue if line.replace(" ","").startswith("#"): continue if line.count("=") != 1: continue Values = line.split('=') soundIcon = Values[0].upper() Values[1] = Values[1].replace("'","") Values[1] = Values[1].replace('"',"") soundIconFile = '' if os.path.exists(Values[1]): soundIconFile = Values[1] else: if not soundIconPath.endswith("/"): soundIconPath += '/' if os.path.exists(soundIconPath + Values[1]): soundIconFile = soundIconPath + Values[1] self.env['soundIcons'][soundIcon] = soundIconFile self.env['runtime']['debug'].writeDebugOut("SoundIcon: " + soundIcon + '.' + soundIconFile, debug.debugLevel.INFO, onAnyLevel=True) siConfig.close() def isValidKey(self, key): return key in inputData.keyNames def loadDicts(self, dictConfigPath=fenrirPath + '/../../config/punctuation/default.conf'): dictConfig = open(dictConfigPath,"r") currDictName = '' while(True): line = dictConfig.readline() if not line: break line = line.replace('\n','') if line.replace(" ","") == '': continue if line.replace(" ","").startswith("#"): continue if line.replace(" ","").upper().startswith("[") and \ line.replace(" ","").upper().endswith("DICT]"): currDictName = line[line.find('[') + 1 :line.upper().find('DICT]') + 4].upper() else: if currDictName == '': continue if not ":===:" in line: continue sepLine = line.split(':===:') if len(sepLine) == 1: sepLine.append('') elif len(sepLine) < 1: continue elif len(sepLine) > 2: sepLine[1] = ':===:' self.env['punctuation'][currDictName][sepLine[0]] = sepLine[1] self.env['runtime']['debug'].writeDebugOut("Punctuation: " + currDictName + '.' + str(sepLine[0]) + ' :' + sepLine[1] ,debug.debugLevel.INFO, onAnyLevel=True) dictConfig.close() def loadSettings(self, settingConfigPath): if not os.path.exists(settingConfigPath): return False self.env['settings'] = ConfigParser() self.env['settings'].read(settingConfigPath) return True def setSetting(self, section, setting, value): self.env['settings'].set(section, setting, value) def getSetting(self, section, setting): value = '' try: value = self.settingArgDict[section.lower()][setting.lower()] return value except: pass try: value = self.env['settings'].get(section, setting) except: value = str(self.settings[section][setting]) return value def getSettingAsInt(self, section, setting): value = 0 try: value = int(self.settingArgDict[section.lower()][setting.lower()]) return value except Exception as e: pass try: value = self.env['settings'].getint(section, setting) except: value = self.settings[section][setting] return value def getSettingAsFloat(self, section, setting): value = 0.0 try: value = float(self.settingArgDict[section.lower()][setting.lower()]) return value except Exception as e: pass try: value = self.env['settings'].getfloat(section, setting) except: value = self.settings[section][setting] return value def getSettingAsBool(self, section, setting): value = False try: value = self.settingArgDict[section.lower()][setting.lower()].upper() in ['1','YES','JA','TRUE'] return value except Exception as e: pass try: value = self.env['settings'].getboolean(section, setting) except: value = self.settings[section][setting] return value def loadDriver(self, driverName, driverType): try: if self.env['runtime'][driverType] != None: self.env['runtime'][driverType].shutdown(self.env) driver_mod = module_utils.importModule(driverName, fenrirPath + "/" + driverType + '/' + driverName + '.py') self.env['runtime'][driverType] = driver_mod.driver() self.env['runtime'][driverType].initialize(self.env) self.env['runtime']['debug'].writeDebugOut('Loading Driver ' + driverType + ' (' + driverName +") OK",debug.debugLevel.INFO, onAnyLevel=True) except Exception as e: self.env['runtime'][driverType] = None self.env['runtime']['debug'].writeDebugOut('Loading Driver ' + driverType + ' (' + driverName +") FAILED:"+ str(e), debug.debugLevel.ERROR) def shutdownDriver(self, driverType): if self.env['runtime'][driverType] == None: return self.env['runtime'][driverType].shutdown() del self.env['runtime'][driverType] def setFenrirKeys(self, keys): keys = keys.upper() keyList = keys.split(',') for key in keyList: if not key in self.env['input']['fenrirKey']: self.env['input']['fenrirKey'].append(key) def setScriptKeys(self, keys): keys = keys.upper() keyList = keys.split(',') for key in keyList: if not key in self.env['input']['scriptKey']: self.env['input']['scriptKey'].append(key) def setOptionArgDict(self, section, option, value): section = section.lower() option = option.lower() try: e = self.settingArgDict[section] except KeyError: self.settingArgDict[section] = {} self.settingArgDict[section][option] = str(value) def parseSettingArgs(self, settingArgs): for optionElem in settingArgs.split(';'): if len(optionElem.split('#',1)) != 2: continue if len(optionElem.split('#',1)[1].split('=',1)) != 2: continue section = str(optionElem.split('#',1)[0]).lower() option = str(optionElem.split('#',1)[1].split('=',1)[0]).lower() value = optionElem.split('#',1)[1].split('=',1)[1] self.setOptionArgDict(section, option, value) def initFenrirConfig(self, cliArgs, fenrirManager = None, environment = environment.environment): settingsRoot = '/etc/fenrir/' settingsFile = cliArgs.setting soundRoot = '/usr/share/sounds/fenrir/' environment['runtime']['debug'] = debugManager.debugManager() environment['runtime']['debug'].initialize(environment) # get fenrir settings root if not os.path.exists(settingsRoot): if os.path.exists(fenrirPath +'/../../config/'): settingsRoot = fenrirPath +'/../../config/' else: return None # get settings file if not os.path.exists(settingsFile): if os.path.exists(settingsRoot + '/settings/settings.conf'): settingsFile = settingsRoot + '/settings/settings.conf' else: return None # get sound themes root if not os.path.exists(soundRoot): if os.path.exists(fenrirPath + '/../../config/sound/'): soundRoot = fenrirPath + '/../../config/sound/' environment['runtime']['settingsManager'] = self environment['runtime']['settingsManager'].initialize(environment) validConfig = environment['runtime']['settingsManager'].loadSettings(settingsFile) if not validConfig: return None if cliArgs.options != '': self.parseSettingArgs(cliArgs.options) if cliArgs.debug: self.setOptionArgDict('general', 'debugLevel', 3) if cliArgs.print: self.setOptionArgDict('general', 'debugLevel', 3) self.setOptionArgDict('general', 'debugMode', 'PRINT') self.setFenrirKeys(self.getSetting('general','fenrirKeys')) self.setScriptKeys(self.getSetting('general','scriptKeys')) if not os.path.exists(self.getSetting('keyboard','keyboardLayout')): if os.path.exists(settingsRoot + 'keyboard/' + self.getSetting('keyboard','keyboardLayout')): self.setSetting('keyboard', 'keyboardLayout', settingsRoot + 'keyboard/' + self.getSetting('keyboard','keyboardLayout')) environment['runtime']['settingsManager'].loadShortcuts(self.getSetting('keyboard','keyboardLayout')) if os.path.exists(settingsRoot + 'keyboard/' + self.getSetting('keyboard','keyboardLayout') + '.conf'): self.setSetting('keyboard', 'keyboardLayout', settingsRoot + 'keyboard/' + self.getSetting('keyboard','keyboardLayout') + '.conf') environment['runtime']['settingsManager'].loadShortcuts(self.getSetting('keyboard','keyboardLayout')) else: environment['runtime']['settingsManager'].loadShortcuts(self.getSetting('keyboard','keyboardLayout')) if not os.path.exists(self.getSetting('sound','theme') + '/soundicons.conf'): if os.path.exists(soundRoot + self.getSetting('sound','theme')): self.setSetting('sound', 'theme', soundRoot + self.getSetting('sound','theme')) if os.path.exists(self.getSetting('sound','theme') + '/soundicons.conf'): environment['runtime']['settingsManager'].loadSoundIcons(self.getSetting('sound','theme')) else: environment['runtime']['settingsManager'].loadSoundIcons(self.getSetting('sound','theme')) if not os.path.exists(self.getSetting('general','punctuationProfile')): if os.path.exists(settingsRoot + 'punctuation/' + self.getSetting('general','punctuationProfile')): self.setSetting('general', 'punctuationProfile', settingsRoot + 'punctuation/' + self.getSetting('general','punctuationProfile')) environment['runtime']['settingsManager'].loadDicts(self.getSetting('general','punctuationProfile')) if os.path.exists(settingsRoot + 'punctuation/' + self.getSetting('general','punctuationProfile') + '.conf'): self.setSetting('general', 'punctuationProfile', settingsRoot + 'punctuation/' + self.getSetting('general','punctuationProfile') + '.conf') environment['runtime']['settingsManager'].loadDicts(self.getSetting('general','punctuationProfile')) else: environment['runtime']['settingsManager'].loadDicts(self.getSetting('general','punctuationProfile')) if fenrirManager: environment['runtime']['fenrirManager'] = fenrirManager environment['runtime']['eventManager'] = eventManager.eventManager() environment['runtime']['eventManager'].initialize(environment) environment['runtime']['processManager'] = processManager.processManager() environment['runtime']['processManager'].initialize(environment) environment['runtime']['outputManager'] = outputManager.outputManager() environment['runtime']['outputManager'].initialize(environment) environment['runtime']['commandManager'] = commandManager.commandManager() environment['runtime']['commandManager'].initialize(environment) environment['runtime']['inputManager'] = inputManager.inputManager() environment['runtime']['inputManager'].initialize(environment) environment['runtime']['punctuationManager'] = punctuationManager.punctuationManager() environment['runtime']['punctuationManager'].initialize(environment) environment['runtime']['cursorManager'] = cursorManager.cursorManager() environment['runtime']['cursorManager'].initialize(environment) environment['runtime']['applicationManager'] = applicationManager.applicationManager() environment['runtime']['applicationManager'].initialize(environment) environment['runtime']['helpManager'] = helpManager.helpManager() environment['runtime']['helpManager'].initialize(environment) if environment['runtime']['screenManager'] == None: environment['runtime']['screenManager'] = screenManager.screenManager() environment['runtime']['screenManager'].initialize(environment) environment['runtime']['debug'].writeDebugOut('\/-------environment-------\/',debug.debugLevel.INFO, onAnyLevel=True) environment['runtime']['debug'].writeDebugOut(str(environment), debug.debugLevel.INFO, onAnyLevel=True) environment['runtime']['debug'].writeDebugOut('\/-------settings.conf-------\/', debug.debugLevel.INFO, onAnyLevel=True) environment['runtime']['debug'].writeDebugOut(str(environment['settings']._sections) , debug.debugLevel.INFO, onAnyLevel=True) environment['runtime']['debug'].writeDebugOut('\/-------self.settingArgDict-------\/',debug.debugLevel.INFO, onAnyLevel=True) environment['runtime']['debug'].writeDebugOut(str( self.settingArgDict) ,debug.debugLevel.INFO, onAnyLevel=True) return environment fenrir-1.5.1/src/fenrir/fenrir000077500000000000000000000007301317357605400163050ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. import os, sys, inspect fenrirPath = os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe())))) if not fenrirPath in sys.path: sys.path.append(fenrirPath) from core import fenrirManager def main(): app = fenrirManager.fenrirManager() app.proceed() del app if __name__ == "__main__": main() fenrir-1.5.1/src/fenrir/fenrir-daemon000077500000000000000000000014471317357605400175540ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. import os, sys, inspect fenrirPath = os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe())))) if not fenrirPath in sys.path: sys.path.append(fenrirPath) from core import fenrirManager from daemonize import Daemonize pidFile = "/run/fenrir.pid" def main(): app = fenrirManager.fenrirManager() app.proceed() del app if __name__ == "__main__": # for debug in foreground #daemon = Daemonize(app="fenrir-daemon", pid=pidFile, action=main, foreground=True,chdir=os.path.dirname(os.path.realpath(fenrirVersion.__file__))) daemon = Daemonize(app="fenrir-daemon", pid=pidFile, action=main, chdir=fenrirPath) daemon.start() fenrir-1.5.1/src/fenrir/fenrirVersion.py000066400000000000000000000002731317357605400203010ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. import os, sys import __main__ version = 1.5 codename = 'gampert' fenrir-1.5.1/src/fenrir/inputDriver/000077500000000000000000000000001317357605400174055ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/inputDriver/__init__.py000066400000000000000000000000001317357605400215040ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/inputDriver/dummyDriver.py000066400000000000000000000025351317357605400222730ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. import time from core import debug class driver(): def __init__(self): self._initialized = False def initialize(self, environment): self.env = environment def shutdown(self): pass def getInputEvent(self): time.sleep(0.05) if not self._initialized: return None def writeEventBuffer(self): if not self._initialized: return def clearEventBuffer(self): if not self._initialized: return del self.env['input']['eventBuffer'][:] def updateInputDevices(self, force = False, init = False): if not self._initialized: return def getLedState(self, led = 0): if not self._initialized: return False return False def toggleLedState(self, led = 0): if not self._initialized: return None def grabDevices(self): if not self._initialized: return None def releaseDevices(self): if not self._initialized: return None def __del__(self): if not self._initialized: return None self.releaseDevices() fenrir-1.5.1/src/fenrir/inputDriver/evdevDriver.py000066400000000000000000000326771317357605400222630ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. _evdevAvailable = False _udevAvailable = False _evdevAvailableError = '' _udevAvailableError = '' try: import evdev from evdev import InputDevice, UInput _evdevAvailable = True except Exception as e: _evdevAvailableError = str(e) try: import pyudev _udevAvailable = True except Exception as e: _udevAvailableError = str(e) import time from select import select import multiprocessing from multiprocessing.sharedctypes import Value from ctypes import c_bool from core.eventData import fenrirEventType from core import inputData from core import debug class driver(): def __init__(self): self._manager = multiprocessing.Manager() self.iDevices = {} self.iDevicesFD = self._manager.list() self.uDevices = {} self.iDeviceNo = 0 self._initialized = False self.watchDog = Value(c_bool, True) def initialize(self, environment): self.env = environment global _evdevAvailable global _udevAvailable self._initialized = _evdevAvailable if not self._initialized: global _evdevAvailableError self.env['runtime']['debug'].writeDebugOut('InputDriver: ' + _evdevAvailableError,debug.debugLevel.ERROR) return if _udevAvailable: self.env['runtime']['processManager'].addCustomEventThread(self.plugInputDeviceWatchdogUdev) else: self.env['runtime']['processManager'].addSimpleEventThread(fenrirEventType.PlugInputDevice, self.plugInputDeviceWatchdogTimer) self.env['runtime']['processManager'].addSimpleEventThread(fenrirEventType.KeyboardInput, self.inputWatchdog, {'dev':self.iDevicesFD}) def plugInputDeviceWatchdogUdev(self,active , eventQueue): context = pyudev.Context() monitor = pyudev.Monitor.from_netlink(context) monitor.filter_by(subsystem='input') monitor.start() while active.value: devices = monitor.poll(2) if devices: while monitor.poll(0.5): time.sleep(0.2) eventQueue.put({"Type":fenrirEventType.PlugInputDevice,"Data":None}) return time.time() def plugInputDeviceWatchdogTimer(self, active): time.sleep(2.5) return time.time() def shutdown(self): if not self._initialized: return def inputWatchdog(self,active , params): try: deviceFd = [] while self.watchDog.value == 0: if active.value == 0: return r = [] while r == []: if active.value == 0: return r, w, x = select(list(params['dev']), [], [], 0.3) self.watchDog.value = 0 except: pass def getInputEvent(self): if not self.hasIDevices(): self.watchDog.value = 1 return None event = None r, w, x = select(self.iDevices, [], [], 0.00001) if r != []: for fd in r: try: event = self.iDevices[fd].read_one() except: self.removeDevice(fd) self.watchDog.value = 1 return None foreward = False while(event): self.env['input']['eventBuffer'].append( [self.iDevices[fd], self.uDevices[fd], event]) if event.type == evdev.events.EV_KEY: if event.code != 0: currMapEvent = self.mapEvent(event) if not currMapEvent: foreward = True event = self.iDevices[fd].read_one() continue if not isinstance(currMapEvent['EventName'], str): foreward = True event = self.iDevices[fd].read_one() continue if not foreward: if currMapEvent['EventState'] in [0,1,2]: self.watchDog.value = 1 return currMapEvent else: if not event.type in [0,1,4]: foreward = True event = self.iDevices[fd].read_one() if foreward: self.writeEventBuffer() self.clearEventBuffer() self.watchDog.value = 1 return None def writeEventBuffer(self): if not self._initialized: return for iDevice, uDevice, event in self.env['input']['eventBuffer']: self.writeUInput(uDevice, event) def clearEventBuffer(self): if not self._initialized: return del self.env['input']['eventBuffer'][:] def writeUInput(self, uDevice, event): if not self._initialized: return uDevice.write_event(event) uDevice.syn() time.sleep(0.00001) def updateInputDevices(self, force = False, init = False): if init: self.removeAllDevices() deviceFileList = evdev.list_devices() if not force and False: if len(deviceFileList) == self.iDeviceNo: return mode = self.env['runtime']['settingsManager'].getSetting('keyboard', 'device').upper() iDevicesFiles = [] for device in self.iDevices: iDevicesFiles.append(self.iDevices[device].fn) if len(iDevicesFiles) == len(deviceFileList): return eventType = evdev.events for deviceFile in deviceFileList: try: if deviceFile in iDevicesFiles: continue try: open(deviceFile) except Exception as e: self.env['runtime']['debug'].writeDebugOut("Not readable Inputdevice : " + deviceFile +' ' + str(e),debug.debugLevel.ERROR) continue # 3 pos absolute # 2 pos relative # 1 Keys currDevice = evdev.InputDevice(deviceFile) if currDevice.name.upper() in ['','SPEAKUP','PY-EVDEV-UINPUT']: continue if 'BRLTTY' in currDevice.name.upper(): continue cap = currDevice.capabilities() if mode in ['ALL','NOMICE']: if eventType.EV_KEY in cap: if 116 in cap[eventType.EV_KEY] and len(cap[eventType.EV_KEY]) < 10: self.env['runtime']['debug'].writeDebugOut('Device Skipped (has 116):' + currDevice.name,debug.debugLevel.INFO) continue if len(cap[eventType.EV_KEY]) < 30: self.env['runtime']['debug'].writeDebugOut('Device Skipped (< 30 keys):' + currDevice.name,debug.debugLevel.INFO) continue if mode == 'ALL': self.iDevices[currDevice.fd] = currDevice self.grabDevice(currDevice.fd) self.env['runtime']['debug'].writeDebugOut('Device added (ALL):' + self.iDevices[currDevice.fd].name, debug.debugLevel.INFO) elif mode == 'NOMICE': if not ((eventType.EV_REL in cap) or (eventType.EV_ABS in cap)): self.iDevices[currDevice.fd] = currDevice self.grabDevice(currDevice.fd) self.env['runtime']['debug'].writeDebugOut('Device added (NOMICE):' + self.iDevices[currDevice.fd].name,debug.debugLevel.INFO) else: self.env['runtime']['debug'].writeDebugOut('Device Skipped (NOMICE):' + currDevice.name,debug.debugLevel.INFO) elif currDevice.name.upper() in mode.split(','): self.iDevices[currDevice.fd] = currDevice self.grabDevice(currDevice.fd) self.env['runtime']['debug'].writeDebugOut('Device added (Name):' + self.iDevices[currDevice.fd].name,debug.debugLevel.INFO) except Exception as e: print(e) self.env['runtime']['debug'].writeDebugOut("Device Skipped (Exception): " + deviceFile +' ' + currDevice.name +' '+ str(e),debug.debugLevel.INFO) self.iDeviceNo = len(evdev.list_devices()) self.updateMPiDevicesFD() def updateMPiDevicesFD(self): for fd in self.iDevices: if not fd in self.iDevicesFD: self.iDevicesFD.append(fd) for fd in self.iDevicesFD: if not fd in self.iDevices: self.iDevicesFD.remove(fd) def mapEvent(self, event): if not self._initialized: return None if not event: return None mEvent = inputData.inputEvent try: mEvent['EventName'] = evdev.ecodes.keys[event.code] mEvent['EventValue'] = event.code mEvent['EventSec'] = event.sec mEvent['EventUsec'] = event.usec mEvent['EventState'] = event.value return mEvent except Exception as e: return None def getLedState(self, led = 0): if not self.hasIDevices(): return False # 0 = Numlock # 1 = Capslock # 2 = Rollen for fd, dev in self.iDevices.items(): if led in dev.leds(): return True return False def toggleLedState(self, led = 0): if not self.hasIDevices(): return False ledState = self.getLedState(led) for i in self.iDevices: # 17 LEDs if 17 in self.iDevices[i].capabilities(): if ledState == 1: self.iDevices[i].set_led(led , 0) else: self.iDevices[i].set_led(led , 1) def grabAllDevices(self): if not self._initialized: return for fd in self.iDevices: self.grabDevice(fd) def grabDevice(self, fd): if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'): self.uDevices[fd] = None return try: self.uDevices[fd] = UInput.from_device(self.iDevices[fd].fn) except Exception as e: try: self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: compat fallback: ' + str(e),debug.debugLevel.WARNING) dev = self.iDevices[fd] cap = dev.capabilities() del cap[0] self.uDevices[fd] = UInput( cap, dev.name, ) except Exception as e: self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: init Uinput not possible: ' + str(e),debug.debugLevel.ERROR) return try: self.iDevices[fd].grab() except Exception as e: self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: grabing not possible: ' + str(e),debug.debugLevel.ERROR) def removeDevice(self,fd): self.clearEventBuffer() try: self.iDevices[fd].ungrab() except: pass try: self.iDevices[fd].close() except: pass try: self.uDevices[fd].close() except: pass try: del(self.iDevices[fd]) except: pass try: del(self.uDevices[fd]) except: pass self.updateMPiDevicesFD() def hasIDevices(self): if not self._initialized: return False if not self.iDevices: return False if len(self.iDevices) == 0: return False return True def removeAllDevices(self): if not self.hasIDevices(): return devices = self.iDevices.copy() for fd in devices: self.removeDevice(fd) self.iDevices.clear() self.uDevices.clear() self.iDeviceNo = 0 def __del__(self): if not self._initialized: return fenrir-1.5.1/src/fenrir/screenDriver/000077500000000000000000000000001317357605400175255ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/screenDriver/__init__.py000077500000000000000000000000001317357605400216270ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/screenDriver/vcsaDriver.py000066400000000000000000000454201317357605400222140ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. #attrib: #http://rampex.ihep.su/Linux/linux_howto/html/tutorials/mini/Colour-ls-6.html #0 = black, 1 = blue, 2 = green, 3 = cyan, 4 = red, 5 = purple, 6 = brown/yellow, 7 = white. #https://github.com/jwilk/vcsapeek/blob/master/linuxvt.py #blink = 5 if attr & 1 else 0 #bold = 1 if attr & 16 else 0 import difflib import re import subprocess import glob, os import termios import time import select import dbus import fcntl from array import array import errno import sys from utils import screen_utils from fcntl import ioctl from struct import unpack_from, unpack, pack from core import debug from core.eventData import fenrirEventType class driver(): def __init__(self): self.vcsaDevicePath = '/dev/vcsa' self.ListSessions = None self.charmap = {} self.bgColorNames = {0: _('black'), 1: _('blue'), 2: _('green'), 3: _('cyan'), 4: _('red'), 5: _('Magenta'), 6: _('brown/yellow'), 7: _('white')} self.fgColorNames = {0: _('Black'), 1: _('Blue'), 2: _('Green'), 3: _('Cyan'), 4: _('Red'), 5: _('Magenta'), 6: _('brown/yellow'), 7: _('Light gray'), 8: _('Dark gray'), 9: _('Light blue'), 10: ('Light green'), 11: _('Light cyan'), 12: _('Light red'), 13: _('Light magenta'), 14: _('Light yellow'), 15: _('White')} self.hichar = None def initialize(self, environment): self.env = environment self.env['runtime']['processManager'].addCustomEventThread(self.updateWatchdog) def shutdown(self): pass def getCurrScreen(self): self.env['screen']['oldTTY'] = self.env['screen']['newTTY'] try: currScreenFile = open('/sys/devices/virtual/tty/tty0/active','r') self.env['screen']['newTTY'] = str(currScreenFile.read()[3:-1]) currScreenFile.close() except Exception as e: self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) def injectTextToScreen(self, text, screen = None): useScreen = "/dev/tty" + self.env['screen']['newTTY'] if screen != None: useScreen = screen with open(useScreen, 'w') as fd: for c in text: fcntl.ioctl(fd, termios.TIOCSTI, c) def getCurrApplication(self): apps = [] try: currScreen = self.env['screen']['newTTY'] apps = subprocess.Popen('ps -t tty' + currScreen + ' -o comm,tty,stat', shell=True, stdout=subprocess.PIPE).stdout.read().decode()[:-1].split('\n') except Exception as e: self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) return try: for i in apps: i = i.upper() i = i.split() i[0] = i[0] i[1] = i[1] if '+' in i[2]: if i[0] != '': if not "GREP" == i[0] and \ not "SH" == i[0] and \ not "PS" == i[0]: if "TTY"+currScreen in i[1]: if self.env['screen']['newApplication'] != i[0]: self.env['screen']['newApplication'] = i[0] return except Exception as e: self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) def getSessionInformation(self): try: bus = dbus.SystemBus() if not self.ListSessions: obj = bus.get_object('org.freedesktop.login1', '/org/freedesktop/login1') inf = dbus.Interface(obj, 'org.freedesktop.login1.Manager') self.ListSessions = inf.get_dbus_method('ListSessions') sessions = self.ListSessions() self.env['screen']['autoIgnoreScreens'] = [] for session in sessions: obj = bus.get_object('org.freedesktop.login1', session[4]) inf = dbus.Interface(obj, 'org.freedesktop.DBus.Properties') sessionType = inf.Get('org.freedesktop.login1.Session', 'Type') screen = str(inf.Get('org.freedesktop.login1.Session', 'VTNr')) if screen == '': screen = str(inf.Get('org.freedesktop.login1.Session', 'TTY')) screen = screen[screen.upper().find('TTY') + 3:] if screen == '': self.env['runtime']['debug'].writeDebugOut('No TTY found for session:' + session[4],debug.debugLevel.ERROR) return if sessionType.upper() == 'X11': self.env['screen']['autoIgnoreScreens'].append(screen) if screen == self.env['screen']['newTTY'] : if self.env['general']['currUser'] != session[2]: self.env['general']['prevUser'] = self.env['general']['currUser'] self.env['general']['currUser'] = session[2] except Exception as e: self.env['runtime']['debug'].writeDebugOut('getSessionInformation: Maybe no LoginD:' + str(e),debug.debugLevel.ERROR) self.env['screen']['autoIgnoreScreens'] = [] self.env['runtime']['debug'].writeDebugOut('getSessionInformation:' + str(self.env['screen']['autoIgnoreScreens']) + ' ' + str(self.env['general']) ,debug.debugLevel.INFO) def updateWatchdog(self,active , eventQueue): try: vcsa = {} vcsaDevices = glob.glob('/dev/vcsa*') for vcsaDev in vcsaDevices: index = vcsaDev[9:] vcsa[str(index)] = open(vcsaDev,'rb') tty = open('/sys/devices/virtual/tty/tty0/active','r') currScreen = str(tty.read()[3:-1]) oldScreen = currScreen watchdog = select.epoll() watchdog.register(vcsa[currScreen], select.POLLPRI | select.POLLERR) watchdog.register(tty, select.POLLPRI | select.POLLERR) while active.value == 1: changes = watchdog.poll(2) for change in changes: fileno = change[0] event = change[1] if fileno == tty.fileno(): self.env['runtime']['debug'].writeDebugOut('ScreenChange',debug.debugLevel.INFO) tty.seek(0) currScreen = str(tty.read()[3:-1]) if currScreen != oldScreen: try: watchdog.unregister(vcsa[ oldScreen ]) except: pass try: watchdog.register(vcsa[ currScreen ], select.POLLPRI | select.POLLERR) except: pass oldScreen = currScreen eventQueue.put({"Type":fenrirEventType.ScreenChanged,"Data":''}) try: vcsa[currScreen].seek(0) lastScreenContent = vcsa[currScreen].read() except: pass else: self.env['runtime']['debug'].writeDebugOut('ScreenUpdate',debug.debugLevel.INFO) vcsa[currScreen].seek(0) dirtyContent = vcsa[currScreen].read() screenContent = b'' timeout = time.time() while screenContent != dirtyContent: screenContent = dirtyContent if time.time() - timeout >= 0.4: break time.sleep(0.007) vcsa[currScreen].seek(0) dirtyContent = vcsa[currScreen].read() eventQueue.put({"Type":fenrirEventType.ScreenUpdate,"Data":None}) except Exception as e: self.env['runtime']['debug'].writeDebugOut('VCSA:updateWatchdog:' + str(e),debug.debugLevel.ERROR) def updateCharMap(self, screen): self.charmap = {} try: tty = open('/dev/tty' + screen, 'rb') except Exception as e: self.env['runtime']['debug'].writeDebugOut('VCSA:updateCharMap:' + str(e),debug.debugLevel.ERROR) return GIO_UNIMAP = 0x4B66 VT_GETHIFONTMASK = 0x560D himask = array("H", (0,)) ioctl(tty, VT_GETHIFONTMASK, himask) self.hichar, = unpack_from("@H", himask) sz = 512 line = '' while True: try: unipairs = array("H", [0]*(2*sz)) unimapdesc = array("B", pack("@HP", sz, unipairs.buffer_info()[0])) ioctl(tty.fileno(), GIO_UNIMAP, unimapdesc) break except Exception as e: self.env['runtime']['debug'].writeDebugOut('VCSA:updateCharMap:scaling up sz=' + str(sz) + ' ' + str(e),debug.debugLevel.WARNING) sz *= 2 tty.close() ncodes, = unpack_from("@H", unimapdesc) utable = unpack_from("@%dH" % (2*ncodes), unipairs) for u, b in zip(utable[::2], utable[1::2]): if self.charmap.get(b) is None: self.charmap[b] = chr(u) def autoDecodeVCSA(self, allData, rows, cols): allText = '' allAttrib = [] i = 0 for y in range(rows): lineText = '' lineAttrib = [] for x in range(cols): data = allData[i: i + 2] i += 2 if data == b' \x07': #attr = 7 #ink = 7 #paper = 0 #ch = ' ' lineAttrib.append((7,15,0,0,0,0)) # attribute, ink, paper, blink, bold, underline lineText += ' ' continue (sh,) = unpack("=H", data) attr = (sh >> 8) & 0xFF ch = sh & 0xFF if self.hichar == 0x100: attr >>= 1 ink = attr & 0x0F paper = (attr>>4) & 0x0F blink = 0 #if attr & 1: # blink = 1 bold = 0 #if attr & 16: # bold = 1 #if (ink != 7) or (paper != 0): # print(ink,paper) if sh & self.hichar: ch |= 0x100 try: lineText += self.charmap[ch] except KeyError: lineText += '?' lineAttrib.append((attr,ink, paper,blink,bold,0)) # attribute, ink, paper, blink, bold, underline allText += lineText + '\n' allAttrib += lineAttrib return str(allText), allAttrib def getFenrirBGColor(self, attribute): try: return self.bgColorNames[attribute[2]] except Exception as e: print(e) return '' def getFenrirFGColor(self, attribute): try: return self.fgColorNames[attribute[1]] except Exception as e: print(e) return '' def getFenrirUnderline(self, attribute): if attribute[5] == 1: return _('underlined') return '' def getFenrirBold(self, attribute): if attribute[4] == 1: return _('bold') return '' def getFenrirBlink(self, attribute): if attribute[3] == 1: return _('blink') return '' def getFenrirFont(self, attribute): return _('Default') def getFenrirFontSize(self, attribute): return _('Default') def update(self, trigger='onUpdate'): if trigger == 'onInput': # no need for an update on input for VCSA return newContentBytes = b'' try: # read screen vcsa = open(self.vcsaDevicePath + self.env['screen']['newTTY'],'rb',0) newContentBytes = vcsa.read() vcsa.close() if len(newContentBytes) < 5: return except Exception as e: self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) return # set new "old" values self.env['screen']['oldContentBytes'] = self.env['screen']['newContentBytes'] self.env['screen']['oldContentText'] = self.env['screen']['newContentText'] self.env['screen']['oldContentAttrib'] = self.env['screen']['newContentAttrib'] self.env['screen']['oldCursor'] = self.env['screen']['newCursor'].copy() if self.env['screen']['newCursorAttrib']: self.env['screen']['oldCursorAttrib'] = self.env['screen']['newCursorAttrib'].copy() self.env['screen']['oldDelta'] = self.env['screen']['newDelta'] self.env['screen']['oldAttribDelta'] = self.env['screen']['newAttribDelta'] self.env['screen']['oldNegativeDelta'] = self.env['screen']['newNegativeDelta'] self.env['screen']['newContentBytes'] = newContentBytes # get metadata like cursor or screensize self.env['screen']['lines'] = int( self.env['screen']['newContentBytes'][0]) self.env['screen']['columns'] = int( self.env['screen']['newContentBytes'][1]) self.env['screen']['newCursor']['x'] = int( self.env['screen']['newContentBytes'][2]) self.env['screen']['newCursor']['y'] = int( self.env['screen']['newContentBytes'][3]) # analyze content self.updateCharMap(str(self.env['screen']['newTTY'])) self.env['screen']['newContentText'], \ self.env['screen']['newContentAttrib'] =\ self.autoDecodeVCSA(self.env['screen']['newContentBytes'][4:], self.env['screen']['lines'], self.env['screen']['columns']) if self.env['screen']['newTTY'] != self.env['screen']['oldTTY']: self.env['screen']['oldContentBytes'] = b'' self.env['screen']['oldContentAttrib'] = None self.env['screen']['oldContentText'] = '' self.env['screen']['oldCursor']['x'] = 0 self.env['screen']['oldCursor']['y'] = 0 self.env['screen']['oldDelta'] = '' self.env['screen']['oldAttribDelta'] = '' self.env['screen']['oldCursorAttrib'] = None self.env['screen']['newCursorAttrib'] = None self.env['screen']['oldNegativeDelta'] = '' # initialize current deltas self.env['screen']['newNegativeDelta'] = '' self.env['screen']['newDelta'] = '' self.env['screen']['newAttribDelta'] = '' # changes on the screen oldScreenText = re.sub(' +',' ',self.env['runtime']['screenManager'].getWindowAreaInText(self.env['screen']['oldContentText'])) newScreenText = re.sub(' +',' ',self.env['runtime']['screenManager'].getWindowAreaInText(self.env['screen']['newContentText'])) typing = False if (self.env['screen']['oldContentText'] != self.env['screen']['newContentText']): if self.env['screen']['newContentText'] != '' and self.env['screen']['oldContentText'] == '': if oldScreenText == '' and\ newScreenText != '': self.env['screen']['newDelta'] = newScreenText else: cursorLineStart = self.env['screen']['newCursor']['y'] * self.env['screen']['columns'] + self.env['screen']['newCursor']['y'] cursorLineEnd = cursorLineStart + self.env['screen']['columns'] if abs(self.env['screen']['oldCursor']['x'] - self.env['screen']['newCursor']['x']) == 1 and \ self.env['screen']['oldCursor']['y'] == self.env['screen']['newCursor']['y'] and \ self.env['screen']['newContentText'][:cursorLineStart] == self.env['screen']['oldContentText'][:cursorLineStart] and \ self.env['screen']['newContentText'][cursorLineEnd:] == self.env['screen']['oldContentText'][cursorLineEnd:]: cursorLineStartOffset = cursorLineStart cursorLineEndOffset = cursorLineEnd #if cursorLineStart < cursorLineStart + self.env['screen']['newCursor']['x'] - 4: # cursorLineStartOffset = cursorLineStart + self.env['screen']['newCursor']['x'] - 4 if cursorLineEnd > cursorLineStart + self.env['screen']['newCursor']['x'] + 3: cursorLineEndOffset = cursorLineStart + self.env['screen']['newCursor']['x'] + 3 oldScreenText = self.env['screen']['oldContentText'][cursorLineStartOffset:cursorLineEndOffset] oldScreenText = re.sub(' +',' ',oldScreenText) newScreenText = self.env['screen']['newContentText'][cursorLineStartOffset:cursorLineEndOffset] newScreenText = re.sub(' +',' ',newScreenText) diff = difflib.ndiff(oldScreenText, newScreenText) typing = True else: diff = difflib.ndiff( oldScreenText.split('\n'),\ newScreenText.split('\n')) diffList = list(diff) if self.env['runtime']['settingsManager'].getSetting('general', 'newLinePause') and not typing: self.env['screen']['newDelta'] = '\n'.join(x[2:] for x in diffList if x[0] == '+') else: self.env['screen']['newDelta'] = ''.join(x[2:] for x in diffList if x[0] == '+') self.env['screen']['newNegativeDelta'] = ''.join(x[2:] for x in diffList if x[0] == '-') # track highlighted if self.env['screen']['oldContentAttrib'] != self.env['screen']['newContentAttrib']: if self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'highlight'): self.env['screen']['newAttribDelta'], self.env['screen']['newCursorAttrib'] = screen_utils.trackHighlights(self.env['screen']['oldContentAttrib'], self.env['screen']['newContentAttrib'], self.env['screen']['newContentText'], self.env['screen']['columns']) fenrir-1.5.1/src/fenrir/soundDriver/000077500000000000000000000000001317357605400173765ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/soundDriver/__init__.py000077500000000000000000000000001317357605400215000ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/soundDriver/dummyDriver.py000066400000000000000000000032621317357605400222620ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug class driver(): def __init__(self): self.volume = None self._initialized = False def initialize(self, environment): self.env = environment self._initialized = True print('SoundDummyDriver: Initialize') def shutdown(self): if not self._initialized: return self.cancel() print('SoundDummyDriver: Shutdown') def playFrequence(self, frequence = 1000, duration = 0.3, adjustVolume = 0): if not self._initialized: return if interrupt: self.cancel() print('SoundDummyDriver: playFrequence:' + ' freq:' + str(frequence) + ' duration:' + str(duration) + ' adjustVolume:' + str(adjustVolume) ) print('SoundDummyDriver: -----------------------------------') def playSoundFile(self, filePath, interrupt = True): if not self._initialized: return if interrupt: self.cancel() print('SoundDummyDriver: playSoundFile:' + str(filePath)) print('SoundDummyDriver: -----------------------------------') def cancel(self): if not self._initialized: return print('SoundDummyDriver: Cancel') def setCallback(self, callback): if not self._initialized: return print('SoundDummyDriver: setCallback') def setVolume(self, volume): if not self._initialized: return self.volume = volume print('SoundDummyDriver: setVolume:' + str(self.volume)) fenrir-1.5.1/src/fenrir/soundDriver/genericDriver.py000066400000000000000000000051741317357605400225470ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug import subprocess class driver(): def __init__(self): self.proc = None self.volume = 1.0 self.soundType = '' self.soundFileCommand = '' self.frequenceCommand = '' self._initialized = False def initialize(self, environment): self.env = environment self.soundFileCommand = self.env['runtime']['settingsManager'].getSetting('sound', 'genericPlayFileCommand') self.frequenceCommand = self.env['runtime']['settingsManager'].getSetting('sound', 'genericFrequencyCommand') if self.soundFileCommand == '': self.soundFileCommand = 'play -q -v fenrirVolume fenrirSoundFile' if self.frequenceCommand == '': self.frequenceCommand = 'play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence' self._initialized = True def shutdown(self): if not self._initialized: return self.cancel() def playFrequence(self, frequence = 1000, duration = 0.3, adjustVolume = 0): if not self._initialized: return if interrupt: self.cancel() popenFrequenceCommand = self.frequenceCommand.replace('fenrirVolume', str(self.volume + adjustVolume )) popenFrequenceCommand = popenFrequenceCommand.replace('fenrirFreqDuration', str(duration)) popenFrequenceCommand = popenFrequenceCommand.replace('fenrirFrequence', str(frequence)) self.proc = subprocess.Popen(popenFrequenceCommand, shell=True) self.soundType = 'frequence' def playSoundFile(self, filePath, interrupt = True): if not self._initialized: return if interrupt: self.cancel() popenSoundFileCommand = self.soundFileCommand.replace('fenrirVolume', str(self.volume )) popenSoundFileCommand = popenSoundFileCommand.replace('fenrirSoundFile', filePath) self.proc = subprocess.Popen(popenSoundFileCommand, shell=True) self.soundType = 'file' def cancel(self): if not self._initialized: return if self.soundType == '': return if self.soundType == 'file': self.proc.kill() if self.soundType == 'frequence': self.proc.kill() self.soundType = '' def setCallback(self, callback): if not self._initialized: return def setVolume(self, volume): if not self._initialized: return self.volume = volume fenrir-1.5.1/src/fenrir/soundDriver/gstreamerDriver.py000066400000000000000000000103121317357605400231120ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug import time, threading _gstreamerAvailable = False try: import gi from gi.repository import GLib gi.require_version('Gst', '1.0') from gi.repository import Gst _gstreamerAvailable, args = Gst.init_check(None) except Exception as e: _gstreamerAvailable = False _availableError = str(e) class driver: def __init__(self): self._source = None self._sink = None self.volume = 1 self._initialized = False def initialize(self, environment): self.env = environment global _gstreamerAvailable self._initialized = _gstreamerAvailable if not self._initialized: global _availableError self.environment['runtime']['debug'].writeDebugOut('Gstreamer not available ' + _availableError,debug.debugLevel.ERROR) return self._player = Gst.ElementFactory.make('playbin', 'player') bus = self._player.get_bus() bus.add_signal_watch() bus.connect("message", self._onPlayerMessage) self._pipeline = Gst.Pipeline(name='fenrir-pipeline') bus = self._pipeline.get_bus() bus.add_signal_watch() bus.connect("message", self._onPipelineMessage) self._source = Gst.ElementFactory.make('audiotestsrc', 'src') self._sink = Gst.ElementFactory.make('autoaudiosink', 'output') self._pipeline.add(self._source) self._pipeline.add(self._sink) self._source.link(self._sink) self.mainloop = GLib.MainLoop() self.thread = threading.Thread(target=self.mainloop.run) self.thread.start() def shutdown(self): if not self._initialized: return self.cancel() self.mainloop.quit() def _onPlayerMessage(self, bus, message): if not self._initialized: return if message.type == Gst.MessageType.EOS: self._player.set_state(Gst.State.NULL) elif message.type == Gst.MessageType.ERROR: self._player.set_state(Gst.State.NULL) error, info = message.parse_error() self.env['runtime']['debug'].writeDebugOut('GSTREAMER: _onPlayerMessage'+ str(error) + str(info),debug.debugLevel.WARNING) def _onPipelineMessage(self, bus, message): if not self._initialized: return if message.type == Gst.MessageType.EOS: self._pipeline.set_state(Gst.State.NULL) elif message.type == Gst.MessageType.ERROR: self._pipeline.set_state(Gst.State.NULL) error, info = message.parse_error() self.env['runtime']['debug'].writeDebugOut('GSTREAMER: _onPipelineMessage'+ str(error) + str(info),debug.debugLevel.WARNING) def _onTimeout(self, element): if not self._initialized: return element.set_state(Gst.State.NULL) def playSoundFile(self, fileName, interrupt=True): if not self._initialized: return if interrupt: self.cancel() self._player.set_property('uri', 'file://%s' % fileName) self._player.set_state(Gst.State.PLAYING) def playFrequence(self, frequence, duration, adjustVolume, interrupt=True): if not self._initialized: return if interrupt: self.cancel() self._source.set_property('volume', tone.volume) self._source.set_property('freq', tone.frequency) self._source.set_property('wave', tone.wave) self._pipeline.set_state(Gst.State.PLAYING) duration = int(1000 * tone.duration) GLib.timeout_add(duration, self._onTimeout, self._pipeline) def cancel(self, element=None): if not self._initialized: return if element: element.set_state(Gst.State.NULL) return self._player.set_state(Gst.State.NULL) self._pipeline.set_state(Gst.State.NULL) def setVolume(self, volume): if not self._initialized: return self.volume = volume fenrir-1.5.1/src/fenrir/speechDriver/000077500000000000000000000000001317357605400175155ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/speechDriver/Readme.md000066400000000000000000000001401317357605400212270ustar00rootroot00000000000000espeak = espeak driver speechd = speech-dispatcher driver generic = generic driver via /bin/say fenrir-1.5.1/src/fenrir/speechDriver/__init__.py000077500000000000000000000000001317357605400216170ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/speechDriver/dummyDriver.py000066400000000000000000000037001317357605400223760ustar00rootroot00000000000000#!/usr/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. # generic driver from core import debug class driver(): def __init__(self): pass def initialize(self, environment): self._isInitialized = True self.env = environment print('SpeechDummyDriver: Iitialize') def shutdown(self): print('SpeechDummyDriver: Shutdown') def speak(self,text, queueable=True): if not self._isInitialized: return if not queueable: self.cancel() print('SpeechDummyDriver: Speak:'+text) print('SpeechDummyDriver: -----------------------------------') def cancel(self): if not self._isInitialized: return print('SpeechDummyDriver: Cancel') def setCallback(self, callback): print('SpeechDummyDriver: setCallback') def clear_buffer(self): if not self._isInitialized: return print('SpeechDummyDriver: clear_buffer') def setVoice(self, voice): if not self._isInitialized: return print('SpeechDummyDriver: setVoice:' + str(voice)) def setPitch(self, pitch): if not self._isInitialized: return print('SpeechDummyDriver: setPitch:' + str(pitch)) def setRate(self, rate): if not self._isInitialized: return print('SpeechDummyDriver: setRate:' + str(rate)) def setModule(self, module): if not self._isInitialized: return print('SpeechDummyDriver: setModule:' + str(module)) def setLanguage(self, language): if not self._isInitialized: return print('SpeechDummyDriver: setLanguage:' + str(language)) def setVolume(self, volume): if not self._isInitialized: return print('SpeechDummyDriver: setVolume:' + str(volume)) fenrir-1.5.1/src/fenrir/speechDriver/emacspeakDriver.py000066400000000000000000000057431317357605400232050ustar00rootroot00000000000000#!/usr/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. # generic driver from core import debug from subprocess import Popen, PIPE import pexpect import sys import time class driver(): def __init__(self): pass def initialize(self, environment): self._isInitialized = False self.env = environment try: self.server = pexpect.spawnu('tclsh ' + self.env['runtime']['settingsManager'].getSetting('speech', 'serverPath')) except Exception as e: self.env['runtime']['debug'].writeDebugOut('speechDriver:initialize:' + str(e),debug.debugLevel.ERROR) self._isInitialized = True def shutdown(self): if self.server: try: self.server.terminate() except Exception as e: self.env['runtime']['debug'].writeDebugOut('speechDriver:shutdown:self.server.terminate():' + str(e),debug.debugLevel.ERROR) def speak(self,text, queueable=True): if not self._isInitialized: return if not queueable: self.cancel() try: cleanText = text.replace('}', '\}') cleanText = cleanText.replace('{', '\{') cleanText = cleanText.replace('*', '\*') cleanText = cleanText.replace('"', '\"') cleanText = cleanText.replace('\n', ' ') cleanText = cleanText.replace('[', '\[') #print(text.replace('"', '\\\"')) self.server.sendline('tts_say ' + '"' + cleanText +'"') except Exception as e: self.env['runtime']['debug'].writeDebugOut('speechDriver:speak:self.server.sendline():' + str(e),debug.debugLevel.ERROR) def cancel(self): if not self._isInitialized: return try: self.server.sendline('s') except Exception as e: self.env['runtime']['debug'].writeDebugOut('speechDriver:cancel:self.server.sendline():' + str(e),debug.debugLevel.ERROR) def setCallback(self, callback): pass def clear_buffer(self): if not self._isInitialized: return def setVoice(self, voice): if not self._isInitialized: return def setPitch(self, pitch): pass def setRate(self, rate): if not self._isInitialized: return try: self.server.sendline('tts_set_speech_rate ' + str(int(rate * 400)) + '') except Exception as e: self.env['runtime']['debug'].writeDebugOut('speechDriver:setRate:self.server.sendline():' + str(e),debug.debugLevel.ERROR) def setModule(self, module): pass def setLanguage(self, language): if not self._isInitialized: return self.server.sendline('set_lang ' + language + '') def setVolume(self, volume): pass fenrir-1.5.1/src/fenrir/speechDriver/espeakDriver.py000066400000000000000000000040731317357605400225170ustar00rootroot00000000000000#!/usr/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. # Espeak driver from core import debug class driver(): def __init__(self): self._es = None self._isInitialized = False def initialize(self, environment): self.env = environment try: from espeak import espeak self._es = espeak self._isInitialized = True except Exception as e: self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) self._initialized = False def shutdown(self): pass def speak(self,text, interrupt=True): if not self._isInitialized: return if not interrupt: self.cancel() self._es.synth(text) def cancel(self): if not self._isInitialized: return False self._es.cancel() return True def setCallback(self, callback): pass def clear_buffer(self): if not self._isInitialized: return def setVoice(self, voice): if not self._isInitialized: return if voice =='': return return self._es.set_voice(voice) def setPitch(self, pitch): if not self._isInitialized: return return self._es.set_parameter(self._es.Parameter().Pitch, int(pitch * 99)) def setRate(self, rate): if not self._isInitialized: return return self._es.set_parameter(self._es.Parameter().Rate, int(rate * 500 + 100)) def setModule(self, module): if not self._isInitialized: return def setLanguage(self, language): if not self._isInitialized: return if language =='': return return self._es.set_voice(language) def setVolume(self, volume): if not self._isInitialized: return return self._es.set_parameter(self._es.Parameter().Volume, int(volume * 200)) fenrir-1.5.1/src/fenrir/speechDriver/genericDriver.py000066400000000000000000000150571317357605400226670ustar00rootroot00000000000000#!/usr/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. # generic driver from core import debug from threading import Thread, Lock from queue import Queue, Empty from subprocess import Popen class speakQueue(Queue): def clear(self): try: while True: self.get_nowait() except Empty: pass class driver(): def __init__(self): self.proc = None self.speechThread = Thread(target=self.worker) self.lock = Lock() self.textQueue = speakQueue() self.volume = '' self.rate = '' self.pitch = '' self.module = '' self.language = '' self.voice = '' def initialize(self, environment): self.env = environment self.minVolume = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMinVolume') self.maxVolume = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMaxVolume') self.minPitch = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMinPitch') self.maxPitch = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMaxPitch') self.minRate = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMinRate') self.maxRate = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMaxRate') self.speechCommand = self.env['runtime']['settingsManager'].getSetting('speech', 'genericSpeechCommand') if self.speechCommand == '': self.speechCommand = 'espeak -a fenrirVolume -s fenrirRate -p fenrirPitch -v fenrirVoice "fenrirText"' if False: #for debugging overwrite here #self.speechCommand = 'spd-say --wait -r 100 -i 100 "fenrirText"' self.speechCommand = 'flite -t "fenrirText"' self._isInitialized = True if self._isInitialized: self.speechThread.start() def shutdown(self): if not self._isInitialized: return self.cancel() self.textQueue.put(-1) def speak(self,text, queueable=True): if not self._isInitialized: return if not queueable: self.cancel() utterance = { 'text': text, 'volume': self.volume, 'rate': self.rate, 'pitch': self.pitch, 'module': self.module, 'language': self.language, 'voice': self.voice, } self.textQueue.put(utterance.copy()) def cancel(self): if not self._isInitialized: return self.clear_buffer() self.lock.acquire(True) if self.proc: try: self.proc.terminate() except Exception as e: self.env['runtime']['debug'].writeDebugOut('speechDriver:Cancel:self.proc.terminate():' + str(e),debug.debugLevel.WARNING) try: self.proc.kill() except Exception as e: self.env['runtime']['debug'].writeDebugOut('speechDriver:Cancel:self.proc.kill():' + str(e),debug.debugLevel.WARNING) self.proc = None self.lock.release() def setCallback(self, callback): print('SpeechDummyDriver: setCallback') def clear_buffer(self): if not self._isInitialized: return self.textQueue.clear() def setVoice(self, voice): if not self._isInitialized: return self.voice = str(voice) def setPitch(self, pitch): if not self._isInitialized: return self.pitch = str(self.minPitch + pitch * (self.maxPitch - self.minPitch )) def setRate(self, rate): if not self._isInitialized: return self.rate = str(self.minRate + rate * (self.maxRate - self.minRate )) def setModule(self, module): if not self._isInitialized: return self.module = str(module) def setLanguage(self, language): if not self._isInitialized: return self.language = str(language) def setVolume(self, volume): if not self._isInitialized: return self.volume = str(self.minVolume + volume * (self.maxVolume - self.minVolume )) def worker(self): while True: utterance = self.textQueue.get() if isinstance(utterance, int): if utterance == -1: return elif not isinstance(utterance, dict): continue for key in ['volume','module','language','voice','pitch','rate','text']: if not key in utterance: utterance[key] = '' if not isinstance(utterance[key],str): utterance[key] = '' if key == 'text': if utterance[key] == '': continue popenSpeechCommand = self.speechCommand popenSpeechCommand = popenSpeechCommand.replace('fenrirVolume', str(utterance['volume'] ).replace('"','')) popenSpeechCommand = popenSpeechCommand.replace('fenrirModule', str(utterance['module']).replace('"','')) popenSpeechCommand = popenSpeechCommand.replace('fenrirLanguage', str(utterance['language']).replace('"','')) popenSpeechCommand = popenSpeechCommand.replace('fenrirVoice', str(utterance['voice']).replace('"','')) popenSpeechCommand = popenSpeechCommand.replace('fenrirPitch', str(utterance['pitch']).replace('"','')) popenSpeechCommand = popenSpeechCommand.replace('fenrirRate', str(utterance['rate']).replace('"','')) popenSpeechCommand = popenSpeechCommand.replace('fenrirText', str(utterance['text']).replace('"','').replace('\n','')) try: self.env['runtime']['debug'].writeDebugOut('speechDriver:worker:' + popenSpeechCommand,debug.debugLevel.INFO) self.lock.acquire(True) self.proc = Popen(popenSpeechCommand, shell=True) self.lock.release() self.proc.wait() except Exception as e: self.env['runtime']['debug'].writeDebugOut('speechDriver:worker:' + str(e),debug.debugLevel.ERROR) self.lock.acquire(True) self.proc = None self.lock.release() fenrir-1.5.1/src/fenrir/speechDriver/speechdDriver.py000066400000000000000000000076551317357605400226730ustar00rootroot00000000000000#!/usr/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. # speech-dispatcher driver from core import debug class driver(): def __init__(self): self._sd = None self._isInitialized = False self._language = '' def initialize(self, environment): self.env = environment try: import speechd self._sd = speechd.SSIPClient('fenrir') self._punct = speechd.PunctuationMode() self._isInitialized = True except Exception as e: self.env['runtime']['debug'].writeDebugOut('speechDriver initialize:' + str(e),debug.debugLevel.ERROR) self._initialized = False def shutdown(self): if not self._isInitialized: return self.cancel() try: self._sd.close() except: pass self._isInitialized = False def speak(self,text, queueable=True): if not queueable: self.cancel() if not self._isInitialized: self.initialize(self.env) if not self._isInitialized: return try: self._sd.set_synthesis_voice(self._language) self._sd.set_punctuation(self._punct.NONE) self._sd.speak(text) except Exception as e: self.env['runtime']['debug'].writeDebugOut('speechDriver speak:' + str(e),debug.debugLevel.ERROR) self._isInitialized = False def cancel(self): if not self._isInitialized: return try: self._sd.cancel() except Exception as e: self.env['runtime']['debug'].writeDebugOut('speechDriver cancel:' + str(e),debug.debugLevel.ERROR) self._isInitialized = False def setCallback(self, callback): pass def clear_buffer(self): if not self._isInitialized: return def setVoice(self, voice): if not self._isInitialized: return try: if voice != '': self._sd.set_voice(voice) except Exception as e: self.env['runtime']['debug'].writeDebugOut('speechDriver setVoice:' + str(e),debug.debugLevel.ERROR) def setPitch(self, pitch): if not self._isInitialized: return try: self._sd.set_pitch(int(-100 + pitch * 200)) except Exception as e: self.env['runtime']['debug'].writeDebugOut('speechDriver setPitch:' + str(e),debug.debugLevel.ERROR) def setRate(self, rate): if not self._isInitialized: return try: self._sd.set_rate(int(-100 + rate * 200)) except Exception as e: self.env['runtime']['debug'].writeDebugOut('speechDriver setRate:' + str(e),debug.debugLevel.ERROR) def setModule(self, module): if not self._isInitialized: return try: self._sd.set_output_module(module) except Exception as e: self.env['runtime']['debug'].writeDebugOut('speechDriver setModule:' + str(e),debug.debugLevel.ERROR) def setLanguage(self, language): if not self._isInitialized: return self._language = language def setVolume(self, volume): if not self._isInitialized: return try: self._sd.set_volume(int(-100 + volume * 200)) except Exception as e: self.env['runtime']['debug'].writeDebugOut('speechDriver setVolume:' + str(e),debug.debugLevel.ERROR) fenrir-1.5.1/src/fenrir/utils/000077500000000000000000000000001317357605400162325ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/utils/__init__.py000077500000000000000000000000001317357605400203340ustar00rootroot00000000000000fenrir-1.5.1/src/fenrir/utils/char_utils.py000066400000000000000000000066521317357605400207520ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug def getPrevChar(currX,currY, currText): lineBreak = False endOfScreen = False if currText == '': return -1, -1, '', endOfScreen, lineBreak wrappedLines = currText.split('\n') x = currX y = currY if x - 1 < 0: if y - 1 >= 0: y -= 1 x = len(wrappedLines[y]) - 1 lineBreak = True else: lineBreak = False endOfScreen = True else: x -= 1 currChar = '' if not endOfScreen: currChar = wrappedLines[y][x] return x, y, currChar, endOfScreen, lineBreak def getCurrentChar(currX,currY, currText): if currText == '': return -1, -1, '' wrappedLines = currText.split('\n') currChar = wrappedLines[currY][currX] return currX, currY, currChar def getUpChar(currX,currY, currText): endOfScreen = False if currText == '': return -1, -1, '', endOfScreen wrappedLines = currText.split('\n') currY -= 1 if currY < 0: currY = 0 else: endOfScreen = True currChar = '' if not endOfScreen: currChar = wrappedLines[currY][currX] return currX, currY, currChar, endOfScreen def getDownChar(currX,currY, currText): endOfScreen = False if currText == '': return -1, -1, '', endOfScreen wrappedLines = currText.split('\n') currY += 1 if currY >= len(wrappedLines): currY = len(wrappedLines) -1 else: endOfScreen = True currChar = '' if not endOfScreen: currChar = wrappedLines[currY][currX] return currX, currY, currChar, endOfScreen def getLastCharInLine(currY, currText): endOfScreen = False if currText == '': return -1, -1, '' wrappedLines = currText.split('\n') currX = len(wrappedLines[currY].rstrip())-1 if currX < 0: currX = 0 currChar = wrappedLines[currY][currX] return currX, currY, currChar def getNextChar(currX,currY, currText): lineBreak = False endOfScreen = False if currText == '': return -1, -1, '', endOfScreen, lineBreak wrappedLines = currText.split('\n') x = currX y = currY if x + 1 == len(wrappedLines[y]): if y + 1 < len(wrappedLines) - 1: y += 1 x = 0 lineBreak = True else: lineBreak = False endOfScreen = True else: x += 1 currChar = '' if not endOfScreen: currChar = wrappedLines[y][x] return x, y, currChar, endOfScreen, lineBreak def getPhonetic(currChar): if len(currChar) != 1: return currChar phoneticsDict = { "A":"alpha", "B":"bravo", "C":"charlie", "D":"delta", "E":"echo", "F":"foxtrot", "G":"golf", "H":"hotel", "I":"india", "J":"juliet", "K":"kilo", "L":"lima", "M":"mike", "N":"november", "O":"oscar", "P":"papa", "Q":"quebec", "R":"romeo", "S":"sierra", "T":"tango", "U":"uniform", "V":"victor", "W":"whisky", "X":"x ray", "Y":"yankee", "Z":"zulu" } try: phonChar = phoneticsDict[currChar.upper()] if currChar.isupper(): phonChar = phonChar[0].upper() + phonChar[1:] return phonChar except: return currChar fenrir-1.5.1/src/fenrir/utils/fenrir-config.py000066400000000000000000000010451317357605400213340ustar00rootroot00000000000000#!/usr/bin/python import configparser import os import sys from os import listdir from os.path import isfile, join from inspect import isfunction from xdg import BaseDirectory # Get configuration directory if len(sys.argv) > 1: configPath = sys.argv[1] elif os.geteuid() == 0: # Save settings system wide configPath = "/etc/fenrir.conf" else: # Use local settings configPath = BaseDirectory.xdg_data_home + "/fenrir" if not os.path.exists(configPath): os.makedirs(configPath) configPath = configPath + "/fenrir.conf" fenrir-1.5.1/src/fenrir/utils/line_utils.py000066400000000000000000000023451317357605400207570ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from collections import Counter def getPrevLine(currX,currY, currText): endOfScreen = False if currText == '': return -1, -1, '', endOfScreen wrappedLines = currText.split('\n') x = currX y = currY if y - 1 >= 0: y -= 1 else: endOfScreen = True x = 0 currLine = '' if not endOfScreen: currLine = wrappedLines[y] return x, y, currLine, endOfScreen def getCurrentLine(currX,currY, currText): if currText == '': return -1, -1, '' wrappedLines = currText.split('\n') x = currX y = currY x = 0 currLine = wrappedLines[y] return x, y, currLine def getNextLine(currX,currY, currText): endOfScreen = False if currText == '': return -1, -1, '', endOfScreen wrappedLines = currText.split('\n') x = currX y = currY if y + 1 < len(wrappedLines): y += 1 else: endOfScreen = True x = 0 currLine = '' if not endOfScreen: currLine = wrappedLines[y] return x, y, currLine, endOfScreen fenrir-1.5.1/src/fenrir/utils/mark_utils.py000066400000000000000000000036151317357605400207630ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug def getTextBetweenMarks(firstMark, secondMark, inText): if inText == None: return '' if not isinstance(inText, list): inText = inText.split('\n') if len(inText) < 1: return '' if firstMark == None: return '' if secondMark == None: return '' if (firstMark['y'] + 1) * (firstMark['x'] + 1) <= (secondMark['y'] + 1) * (secondMark['x'] + 1): startMark = firstMark.copy() endMark = secondMark.copy() else: endMark = firstMark.copy() startMark = secondMark.copy() textPart = '' if startMark['y'] == endMark['y']: textPart += inText[startMark['y']][startMark['x']:endMark['x'] + 1] else: currY = startMark['y'] while currY <= endMark['y']: if currY < endMark['y']: if currY == startMark['y']: textPart += inText[currY][startMark['x']:] else: textPart += inText[currY] if len(inText[currY].strip()) != 0: if len(textPart) - len(textPart.rstrip()) > 0: textPart = textPart[:len(textPart.rstrip())] + "\n" else: textPart += '\n' else: textPart += inText[currY][:endMark['x'] + 1] currY += 1 return textPart def getTextBeforeMark(mark, inText): if inText == None: return '' if mark == None: return '' return getTextBetweenMarks({'x':0,'y':0}, mark, inText) def getTextAfterMark(mark, inText): if inText == None: return '' if mark == None: return '' inText = inText.split('\n') return getTextBetweenMarks(mark, {'x':len(inText[0])-1,'y':len(inText)-1}, inText) fenrir-1.5.1/src/fenrir/utils/module_utils.py000066400000000000000000000013131317357605400213070ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. import sys version = sys.version[:3] # we only need major.minor version. if version in ["3.3","3.4"]: from importlib.machinery import SourceFileLoader else: # Python 3.5+, no support for python < 3.3. import importlib.util def importModule(moduleName, moduleLocation): if version in ["3.3","3.4"]: return SourceFileLoader(moduleName, moduleLocation).load_module() else: spec = importlib.util.spec_from_file_location(moduleName, moduleLocation) driver_mod = importlib.util.module_from_spec(spec) spec.loader.exec_module(driver_mod) return driver_mod fenrir-1.5.1/src/fenrir/utils/review_utils.py000066400000000000000000000002071317357605400213240ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug fenrir-1.5.1/src/fenrir/utils/screen_utils.py000066400000000000000000000053161317357605400213100ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug from collections import Counter import string from select import select from select import epoll import select def removeNonprintable(text): # Get the difference of all ASCII characters from the set of printable characters nonprintable = set([chr(i) for i in range(128)]).difference(string.printable) # Use translate to remove all non-printable characters return text.translate({ord(character):None for character in nonprintable}) def insertNewlines(string, every=64): return '\n'.join(string[i:i+every] for i in range(0, len(string), every)) def splitEvery(toSplit, every=64): return list(toSplit[i:i+every] for i in range(0, len(toSplit), every)) def hasMoreRead(fd): r, w, e = select([fd], [], [], 0) return (fd in r) def hasMorePollPri(fd): p = epoll() p.register(fd, select.POLLPRI | select.POLLERR) r = p.poll(0) return (fd in r) def trackHighlights(oldAttr, newAttr, text, lenght): result = '' currCursor = None if oldAttr == newAttr: return result, currCursor if len(newAttr) == 0: return result, currCursor if len(oldAttr) != len(newAttr): return result, currCursor old = splitEvery(oldAttr,lenght) new = splitEvery(newAttr,lenght) textLines = text.split('\n') background = [] if len(textLines) - 1 != len(new): return result, currCursor try: bgStat = Counter(newAttr).most_common(3) background.append(bgStat[0][0]) # if there is a third color add a secondary background (for dialogs for example) if len(bgStat) > 2: if bgStat[1][1] > 40: background.append(bgStat[1][0]) except Exception as e: background.append((7,7,0,0,0,0)) for line in range(len(new)): if old[line] != new[line]: for column in range(len(new[line])): print(new[line][column]) if old[line][column] != new[line][column]: if not new[line][column] in background: if not currCursor: currCursor = {} currCursor['x'] = column currCursor['y'] = line result += textLines[line][column] result += ' ' return result, currCursor ''' t = 'hallo\nwelt!' old = ((1,1,0,0),(1,1,0,0),(1,1,0,0),(1,1,0,0),(1,1,0,0),(1,1,0,0),(1,1,0,0),(1,1,0,0),(1,1,0,0),(1,1,0,0)) new = ((0,1,1,1),(1,1,1,1),(1,1,1,1),(1,1,1,1),(1,1,1,1),(1,1,0,0),(1,1,0,0),(1,1,0,0),(1,1,0,0),(1,1,0,0)) trackHighlights(old,new,t,5) ''' fenrir-1.5.1/src/fenrir/utils/word_utils.py000066400000000000000000000077611317357605400210120ustar00rootroot00000000000000#!/bin/python # -*- coding: utf-8 -*- # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. from core import debug import string def getCurrentWord(currX,currY, currText): lineBreak = False endOfScreen = False if currText == '': return -1, -1, '', endOfScreen, lineBreak if currText.strip( string.whitespace) == '': return currX, currY, '', endOfScreen, lineBreak x = currX y = currY currWord = '' wrappedLines = currText.split('\n') currLine = wrappedLines[y] Found = False while(not Found): if not currLine[x] in string.whitespace: if x == 0: Found = True else: if currLine[x - 1] in string.whitespace: Found = True if not Found: if x - 1 < 0: if y - 1 < 0: lineBreak = False endOfScreen = True return currX, currY, '', endOfScreen, lineBreak else: y -= 1 currLine = wrappedLines[y] x = len( currLine) - 1 lineBreak = True else: x -= 1 if Found: currWord = currLine[x:] for d in string.whitespace: delimiterPos = currWord.find(d) if delimiterPos != -1: currWord = currWord[:delimiterPos] return x, y, currWord, endOfScreen, lineBreak return currX, currY, '', False, False def getPrevWord(currX,currY, currText): lineBreak = False endOfScreen = False if currText == '': return -1, -1, '', endOfScreen, lineBreak if currText.strip( string.whitespace) == '': return currX, currY, '', endOfScreen, lineBreak x, y, currWord, endOfScreen, lineBreakCurrWord = getCurrentWord(currX,currY,currText) if endOfScreen: return x, y, currWord, endOfScreen, lineBreak wrappedLines = currText.split('\n') currLine = wrappedLines[y] if x - 1 < 0: if y - 1 < 0: lineBreak = False endOfScreen = True return currX, currY, '', endOfScreen, lineBreak else: y -= 1 currLine = wrappedLines[y] x = len( currLine) - 1 lineBreak = True else: x -= 1 lineBreakCurrWord = lineBreak or lineBreakCurrWord x, y, currWord, endOfScreen, lineBreak = getCurrentWord(x,y,currText) lineBreak = lineBreak or lineBreakCurrWord return x, y, currWord, endOfScreen, lineBreak def getNextWord(currX,currY, currText): lineBreak = False endOfScreen = False if currText == '': return -1, -1, '', endOfScreen, lineBreak if currText.strip( string.whitespace) == '': return currX, currY, '', endOfScreen, lineBreak x = currX y = currY currWord = '' wrappedLines = currText.split('\n') currLine = wrappedLines[y] Found = False while(not Found): if not Found: if x + 1 > len( currLine ) - 1: if y + 1 > len( wrappedLines ) - 1: lineBreak = False endOfScreen = True return currX, currY, '', endOfScreen, lineBreak else: y += 1 currLine = wrappedLines[y] x = 0 lineBreak = True else: x += 1 if not currLine[x] in string.whitespace: if x == 0: Found = True else: if currLine[x - 1] in string.whitespace: Found = True if Found: currWord = currLine[x:] for d in string.whitespace: delimiterPos = currWord.find(d) if delimiterPos != -1: currWord = currWord[:delimiterPos] return x, y, currWord, endOfScreen, lineBreak return currX, currY, '', False, False fenrir-1.5.1/tools/000077500000000000000000000000001317357605400141565ustar00rootroot00000000000000fenrir-1.5.1/tools/configure_pulse.sh000077500000000000000000000054171317357605400177150ustar00rootroot00000000000000#!/bin/bash # This script configures Pulse to work both in the graphical environment and in the console with root apps. if [[ $(whoami) != "root" ]]; then # Get the current user's XDG_HOME xdgPath="${XDG_CONFIG_HOME:-$HOME/.config}" # Warn user if we are going to overwrite an existing default.pa if [ -f "$xdgPath/pulse/default.pa" ]; then read -p "This will replace the current file located at $xdgPath/pulse/default.pa, press enter to continue or control+c to abort. " continue fi echo '.include /etc/pulse/default.pa load-module module-switch-on-connect load-module module-native-protocol-unix auth-anonymous=1 socket=/tmp/pulse.sock' > $xdgPath/pulse/default.pa echo "If you have not yet done so, please run this script as root to write the client.conf file." else # This section does the root part: xdgPath="/root/.config" mkdir -p "$xdgPath/pulse" # Warn user if we are going to overwrite an existing default.pa if [ -f "$xdgPath/pulse/default.pa" ]; then read -p "This will replace the current file located at $xdgPath/pulse/default.pa, press enter to continue or control+c to abort. " continue fi cat << EOF > "$xdgPath/pulse/client.conf" # This file is part of PulseAudio. # # PulseAudio is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # PulseAudio is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with PulseAudio; if not, see . ## Configuration file for PulseAudio clients. See pulse-client.conf(5) for ## more information. Default values are commented out. Use either ; or # for ## commenting. ; default-sink = ; default-source = default-server = unix:/tmp/pulse.sock ; default-dbus-server = autospawn = no ; autospawn = yes ; daemon-binary = /usr/bin/pulseaudio ; extra-arguments = --log-target=syslog ; cookie-file = ; enable-shm = yes ; shm-size-bytes = 0 # setting this 0 will use the system-default, usually 64 MiB ; auto-connect-localhost = no ; auto-connect-display = no EOF echo "If you have not yet done so, run this script as your normal user to write the user default.pa" fi # If there were no errors tell user to restart, else warn them errors happened. if [ $? -eq 0 ]; then echo "Configuration created successfully, please restart Pulseaudio or your system, for changes to take affect." else echo "Errors were encountered whilst writing the configuration, please correct them manually." fi exit 0 fenrir-1.5.1/tools/fenrir-conf000066400000000000000000000133521317357605400163150ustar00rootroot00000000000000#!/bin/bash # Get user input args are return variable, question, options get_input() { # Variable names are long, because we want absolutely no name conflicts. local __get_input_input=$1 shift local __get_input_question="$1" shift local __get_input_answer="" local __get_input_i="" local __get_input_continue=false for __get_input_i in $@; do if [ "${__get_input_i:0:1}" = "-" ]; then local __get_input_default="${__get_input_i:1}" fi done while [ $__get_input_continue = false ]; do echo -n "$__get_input_question (${@/#-/}) " if [ -n "$__get_input_default" ]; then read -e -i "$__get_input_default" __get_input_answer else read -e __get_input_answer fi for __get_input_i in $@; do if [ "$__get_input_answer" = "${__get_input_i/#-/}" ]; then __get_input_continue=true break fi done done __get_input_answer="${__get_input_answer//no/False}" __get_input_answer="${__get_input_answer//yes/True}" eval $__get_input_input="'$__get_input_answer'" } configFile="/etc/fenrir/settings/settings.conf" if [ "$(whoami)" != "root" ]; then echo "Please run $0 as root." exit 1 fi if [ -f "$configFile" ]; then read -p "This will replace your current settings, press enter to continue or control+C to abort." continue fi get_input sound "Enable sound?" -yes no if [ "$sound" = "true" ]; then get_input soundDriver "Select sound driver:" -generic gstreamer else soundDriver="generic" fi get_input speech "Enable speech?" -yes no if [ "$speech" = "true" ]; then get_input speechDriver "Select speech driver:" espeak -speechd else speechDriver="speechd" fi get_input charEcho "enable character echo?" -yes no get_input wordEcho "enable word echo?" yes -no cat << EOF > "$configFile" [sound] # Turn sound on or off: enabled=$sound # Select the driver used to play sounds, choices are generic and gstreamer. # Sox is the default. driver=$soundDriver # Sound themes. These are the pack of sounds used for sound alerts. # Sound packs may be located at /usr/share/sounds # For system wide availability, or ~/.local/share/fenrir/sounds # For the current user. theme=default # Sound volume controls how loud the sounds for your chosen soundpack are. # 0 is quietest, 1.0 is loudest. volume=1.0 # shell commands for generic sound driver # the folowing variables are substituted # fenrirVolume = the current volume setting # fenrirSoundFile = the soundfile for an soundicon # fenrirFrequence = the frequence to play # fenrirDuration = the duration of the frequency # the following command is used for play a soundfile genericPlayFileCommand=play -q -v fenrirVolume fenrirSoundFile #the following command is used for generating a frequency beep genericFrequencyCommand=play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence [speech] # Turn speech on or off: enabled=$speech # Select speech driver, options are speechd (default) or espeak: driver=$speechDriver # The rate selects how fast Fenrir will speak. Options range from 0, slowest, to 1.0, fastest. rate=0.45 # Pitch controls the pitch of the voice, select from 0, lowest, to 1.0, highest. pitch=0.5 # Pitch for capital letters capitalPitch=0.9 # Volume controls the loudness of the voice, select from 0, quietest, to 1.0, loudest. volume=1.0 # Module is used for Speech-dispatcher, to select the speech module you want to use. # Consult Speech-dispatcher's configuration and help to find out which modules are available. # The default is Espeak. module=espeak # Voice selects the varient you want to use, for example, f5 will use the female voice #5 in espeak, # or if using the espeak module in Speech-dispatcher. To find out which voices are available, consult the documentation provided with your selected synthesizer. voice= # Select the language you want Fenrir to use. language=english-us # Read new text as it happens? autoReadIncoming=True [braille] #Braille is not implemented yet enabled=False driver=brlapi layout=en [screen] driver=vcsa encoding=auto autodetectSuspendingScreen=True [keyboard] driver=evdev # filter input devices NOMICE, ALL or a DEVICE NAME device=ALL # gives Fenrir exclusive access to the keyboard and lets it absorb keystrokes. grabDevices=True ignoreShortcuts=False # the current shortcut layout located in /etc/fenrir/keyboard keyboardLayout=$keyboard # echo chars while typing. charEcho=$charEcho # echo deleted chars charDeleteEcho=True # echo word after pressing space wordEcho=$wordEcho # interrupt speech on any keypress interruptOnKeyPress=$enterupt # you can filter the keys that the speech should interrupt (empty = all keys, otherwise the given keys) interruptOnKeyPressFilter= # timeout for double tap in sec doubleTapTimeout=0.2 [general] debugLevel=0 # debugMode sets where the debug output should send to: # debugMode=File writes to /var/log/fenrir.log # debugMode=Print just prints on the screen debugMode=File punctuationProfile=default punctuationLevel=some respectPunctuationPause=True newLinePause=True numberOfClipboards=10 emoticons=True # define the current Fenrir key fenrirKeys=KEY_KP0,KEY_META,KEY_INSERT scriptKey=KEY_COMPOSE timeFormat=%H:%M:%P dateFormat=%A, %B %d, %Y autoSpellCheck=True spellCheckLanguage=en_US scriptPath=/usr/share/fenrir/scripts [focus] #follow the text cursor cursor=True #follow highlighted text changes highlight=False [review] lineBreak=True endOfScreen=True [promote] enabled=True inactiveTimeoutSec=120 list= [time] # automatic time anouncement enabled=False # present time presentTime=True # present date (on change) presentDate=True # present time after a given period of seconds delaySec=0 # present time after to given minutes example every 15 minutes: 00,15,30,45 # if delaySec is >0 onMinutes is ignored onMinutes=00,30 # announce via soundicon (not interrupting) announce=True # interrupt current speech for time announcement interrupt=False EOF echo "Settings saved to $configFile." exit 0 fenrir-1.5.1/tools/fenrir.pot000066400000000000000000000646241317357605400162030ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR ORGANIZATION # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2017-02-26 22:19+UTC\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: pygettext.py 1.5\n" #: ../src/fenrir/commands/commands/add_word_to_spell_check.py:27 msgid "adds the current word to the exceptions dictionary" msgstr "" #: ../src/fenrir/commands/commands/add_word_to_spell_check.py:34 #: ../src/fenrir/commands/commands/remove_word_from_spell_check.py:34 #: ../src/fenrir/commands/commands/spell_check.py:29 #: ../src/fenrir/commands/commands/spell_check.py:36 msgid "pyenchant is not installed" msgstr "" #: ../src/fenrir/commands/commands/add_word_to_spell_check.py:49 msgid "{0} is already in dict" msgstr "" #: ../src/fenrir/commands/commands/add_word_to_spell_check.py:52 msgid "{0} added" msgstr "" #: ../src/fenrir/commands/commands/bookmark_1.py:19 #: ../src/fenrir/commands/commands/bookmark_10.py:19 #: ../src/fenrir/commands/commands/bookmark_2.py:19 #: ../src/fenrir/commands/commands/bookmark_3.py:19 #: ../src/fenrir/commands/commands/bookmark_4.py:19 #: ../src/fenrir/commands/commands/bookmark_5.py:19 #: ../src/fenrir/commands/commands/bookmark_6.py:19 #: ../src/fenrir/commands/commands/bookmark_7.py:19 #: ../src/fenrir/commands/commands/bookmark_8.py:19 #: ../src/fenrir/commands/commands/bookmark_9.py:19 msgid "read Bookmark {0}" msgstr "" #: ../src/fenrir/commands/commands/bookmark_1.py:24 #: ../src/fenrir/commands/commands/bookmark_10.py:24 #: ../src/fenrir/commands/commands/bookmark_2.py:24 #: ../src/fenrir/commands/commands/bookmark_3.py:24 #: ../src/fenrir/commands/commands/bookmark_4.py:24 #: ../src/fenrir/commands/commands/bookmark_5.py:24 #: ../src/fenrir/commands/commands/bookmark_6.py:24 #: ../src/fenrir/commands/commands/bookmark_7.py:24 #: ../src/fenrir/commands/commands/bookmark_8.py:24 #: ../src/fenrir/commands/commands/bookmark_9.py:24 msgid "Bookmark {0} not set" msgstr "" #: ../src/fenrir/commands/commands/bookmark_1.py:27 #: ../src/fenrir/commands/commands/bookmark_1.py:30 #: ../src/fenrir/commands/commands/bookmark_10.py:27 #: ../src/fenrir/commands/commands/bookmark_10.py:30 #: ../src/fenrir/commands/commands/bookmark_2.py:27 #: ../src/fenrir/commands/commands/bookmark_2.py:30 #: ../src/fenrir/commands/commands/bookmark_3.py:27 #: ../src/fenrir/commands/commands/bookmark_3.py:30 #: ../src/fenrir/commands/commands/bookmark_4.py:27 #: ../src/fenrir/commands/commands/bookmark_4.py:30 #: ../src/fenrir/commands/commands/bookmark_5.py:27 #: ../src/fenrir/commands/commands/bookmark_5.py:30 #: ../src/fenrir/commands/commands/bookmark_6.py:27 #: ../src/fenrir/commands/commands/bookmark_6.py:30 #: ../src/fenrir/commands/commands/bookmark_7.py:27 #: ../src/fenrir/commands/commands/bookmark_7.py:30 #: ../src/fenrir/commands/commands/bookmark_8.py:27 #: ../src/fenrir/commands/commands/bookmark_8.py:30 #: ../src/fenrir/commands/commands/bookmark_9.py:27 #: ../src/fenrir/commands/commands/bookmark_9.py:30 msgid "Bookmark for application {0} not set" msgstr "" #: ../src/fenrir/commands/commands/bookmark_1.py:43 #: ../src/fenrir/commands/commands/bookmark_10.py:43 #: ../src/fenrir/commands/commands/bookmark_2.py:43 #: ../src/fenrir/commands/commands/bookmark_3.py:43 #: ../src/fenrir/commands/commands/bookmark_4.py:43 #: ../src/fenrir/commands/commands/bookmark_5.py:43 #: ../src/fenrir/commands/commands/bookmark_6.py:43 #: ../src/fenrir/commands/commands/bookmark_7.py:43 #: ../src/fenrir/commands/commands/bookmark_8.py:43 #: ../src/fenrir/commands/commands/bookmark_9.py:43 #: ../src/fenrir/commands/commands/curr_screen_after_cursor.py:27 #: ../src/fenrir/commands/commands/curr_screen_before_cursor.py:30 #: ../src/fenrir/commands/commands/cursor_read_to_end_of_line.py:27 #: ../src/fenrir/commands/commands/indent_curr_line.py:31 #: ../src/fenrir/commands/commands/marked_text.py:33 #: ../src/fenrir/commands/commands/present_first_line.py:25 #: ../src/fenrir/commands/commands/present_last_line.py:25 #: ../src/fenrir/commands/commands/review_curr_char_phonetic.py:27 #: ../src/fenrir/commands/commands/review_curr_line.py:27 #: ../src/fenrir/commands/commands/review_curr_word.py:27 #: ../src/fenrir/commands/commands/review_curr_word_phonetic.py:27 #: ../src/fenrir/commands/commands/review_line_begin.py:27 #: ../src/fenrir/commands/commands/review_next_line.py:29 #: ../src/fenrir/commands/commands/review_next_word.py:29 #: ../src/fenrir/commands/commands/review_next_word_phonetic.py:27 #: ../src/fenrir/commands/commands/review_prev_line.py:27 #: ../src/fenrir/commands/commands/review_prev_word.py:27 #: ../src/fenrir/commands/commands/review_prev_word_phonetic.py:27 #: ../src/fenrir/commands/onInput/55000-present_line_if_cursor_change_vertical.py:38 #: ../src/fenrir/commands/onInput/72000-history.py:50 msgid "blank" msgstr "" #: ../src/fenrir/commands/commands/braille_flush.py:17 msgid "flush the braille device if a message is written on" msgstr "" #: ../src/fenrir/commands/commands/braille_pan_left.py:17 msgid "Move braille view to the left." msgstr "" #: ../src/fenrir/commands/commands/braille_pan_right.py:17 msgid "Move braille view to the right." msgstr "" #: ../src/fenrir/commands/commands/braille_return_to_cursor.py:17 msgid "Set the braille view back to cursor." msgstr "" #: ../src/fenrir/commands/commands/clear_bookmark_1.py:17 #: ../src/fenrir/commands/commands/clear_bookmark_10.py:17 #: ../src/fenrir/commands/commands/clear_bookmark_2.py:17 #: ../src/fenrir/commands/commands/clear_bookmark_3.py:17 #: ../src/fenrir/commands/commands/clear_bookmark_4.py:17 #: ../src/fenrir/commands/commands/clear_bookmark_5.py:17 #: ../src/fenrir/commands/commands/clear_bookmark_6.py:17 #: ../src/fenrir/commands/commands/clear_bookmark_7.py:17 #: ../src/fenrir/commands/commands/clear_bookmark_8.py:17 #: ../src/fenrir/commands/commands/clear_bookmark_9.py:17 msgid "remove Bookmark {0}" msgstr "" #: ../src/fenrir/commands/commands/clear_bookmark_1.py:24 #: ../src/fenrir/commands/commands/clear_bookmark_10.py:24 #: ../src/fenrir/commands/commands/clear_bookmark_2.py:24 #: ../src/fenrir/commands/commands/clear_bookmark_3.py:24 #: ../src/fenrir/commands/commands/clear_bookmark_4.py:24 #: ../src/fenrir/commands/commands/clear_bookmark_5.py:24 #: ../src/fenrir/commands/commands/clear_bookmark_6.py:24 #: ../src/fenrir/commands/commands/clear_bookmark_7.py:24 #: ../src/fenrir/commands/commands/clear_bookmark_8.py:24 #: ../src/fenrir/commands/commands/clear_bookmark_9.py:24 msgid "Bookmark {0} removed for application {1}" msgstr "" #: ../src/fenrir/commands/commands/clear_clipboard.py:17 msgid "clears the currently selected clipboard" msgstr "" #: ../src/fenrir/commands/commands/clear_clipboard.py:22 msgid "clipboard cleared" msgstr "" #: ../src/fenrir/commands/commands/clear_window_application.py:17 msgid "Turn off window mode for application" msgstr "" #: ../src/fenrir/commands/commands/clear_window_application.py:22 msgid "Window Mode off for application {0}" msgstr "" #: ../src/fenrir/commands/commands/clear_window_application.py:24 msgid "Not in window Mode" msgstr "" #: ../src/fenrir/commands/commands/copy_marked_to_clipboard.py:18 msgid "copies marked text to the currently selected clipboard" msgstr "" #: ../src/fenrir/commands/commands/copy_marked_to_clipboard.py:22 msgid "one or two marks needed" msgstr "" #: ../src/fenrir/commands/commands/curr_clipboard.py:17 msgid "speaks the contents of the currently selected clipboard" msgstr "" #: ../src/fenrir/commands/commands/curr_clipboard.py:21 #: ../src/fenrir/commands/commands/export_clipboard_to_x.py:29 #: ../src/fenrir/commands/commands/export_clipboard_to_x.py:32 #: ../src/fenrir/commands/commands/export_clipboard_to_x.py:35 #: ../src/fenrir/commands/commands/export_clipboard_to_x.py:38 #: ../src/fenrir/commands/commands/first_clipboard.py:21 #: ../src/fenrir/commands/commands/last_clipboard.py:21 #: ../src/fenrir/commands/commands/next_clipboard.py:21 #: ../src/fenrir/commands/commands/paste_clipboard.py:23 #: ../src/fenrir/commands/commands/paste_clipboard.py:26 #: ../src/fenrir/commands/commands/paste_clipboard.py:29 #: ../src/fenrir/commands/commands/paste_clipboard.py:32 #: ../src/fenrir/commands/commands/prev_clipboard.py:21 msgid "clipboard empty" msgstr "" #: ../src/fenrir/commands/commands/curr_screen.py:17 msgid "reads the contents of the current screen" msgstr "" #: ../src/fenrir/commands/commands/curr_screen.py:21 msgid "screen is empty" msgstr "" #: ../src/fenrir/commands/commands/curr_screen_after_cursor.py:18 msgid "reads from the cursor to the bottom of the screen" msgstr "" #: ../src/fenrir/commands/commands/curr_screen_before_cursor.py:18 msgid "Reads from the top of the screen to the cursor position" msgstr "" #: ../src/fenrir/commands/commands/cursor_column.py:17 msgid "presents the current column number for review cursor in review mode or the text cursor if not. Starts with 1" msgstr "" #: ../src/fenrir/commands/commands/cursor_lineno.py:17 msgid "presents the current line number for review cursor in review mode or the text cursor if not. Starts with 1" msgstr "" #: ../src/fenrir/commands/commands/cursor_position.py:17 msgid "displays the position of the review cursor" msgstr "" #: ../src/fenrir/commands/commands/cursor_position.py:23 msgid "line {0}, column {1}" msgstr "" #: ../src/fenrir/commands/commands/cursor_read_to_end_of_line.py:18 msgid "read to end of line, use review cursor if you are in review mode, otherwhise use text cursor" msgstr "" #: ../src/fenrir/commands/commands/date.py:18 msgid "presents the date" msgstr "" #: ../src/fenrir/commands/commands/dec_sound_volume.py:18 msgid "decrease sound volume" msgstr "" #: ../src/fenrir/commands/commands/dec_sound_volume.py:29 #: ../src/fenrir/commands/commands/inc_sound_volume.py:29 msgid "{0} percent sound volume" msgstr "" #: ../src/fenrir/commands/commands/dec_speech_pitch.py:18 msgid "decreases the pitch of the speech" msgstr "" #: ../src/fenrir/commands/commands/dec_speech_pitch.py:27 #: ../src/fenrir/commands/commands/inc_speech_pitch.py:27 msgid "{0} percent speech pitch" msgstr "" #: ../src/fenrir/commands/commands/dec_speech_rate.py:18 msgid "decreases the rate of the speech" msgstr "" #: ../src/fenrir/commands/commands/dec_speech_rate.py:27 #: ../src/fenrir/commands/commands/inc_speech_rate.py:27 msgid "{0} percent speech rate" msgstr "" #: ../src/fenrir/commands/commands/dec_speech_volume.py:18 msgid "decreases the volume of the speech" msgstr "" #: ../src/fenrir/commands/commands/dec_speech_volume.py:27 #: ../src/fenrir/commands/commands/inc_speech_volume.py:27 msgid "{0} percent speech volume" msgstr "" #: ../src/fenrir/commands/commands/exit_review.py:17 msgid "exits review mode" msgstr "" #: ../src/fenrir/commands/commands/exit_review.py:21 msgid "Not in review mode" msgstr "" #: ../src/fenrir/commands/commands/exit_review.py:25 msgid "leave review mode" msgstr "" #: ../src/fenrir/commands/commands/export_clipboard_to_x.py:21 msgid "export the current fenrir clipboard to X clipboard" msgstr "" #: ../src/fenrir/commands/commands/first_clipboard.py:17 msgid "selects the first clipboard" msgstr "" #: ../src/fenrir/commands/commands/forward_keypress.py:17 msgid "sends the following keypress to the terminal" msgstr "" #: ../src/fenrir/commands/commands/forward_keypress.py:21 msgid "Forward next keypress" msgstr "" #: ../src/fenrir/commands/commands/inc_sound_volume.py:18 msgid "adjusts the volume for in coming sounds" msgstr "" #: ../src/fenrir/commands/commands/inc_speech_pitch.py:18 msgid "increases the pitch of the speech" msgstr "" #: ../src/fenrir/commands/commands/inc_speech_rate.py:18 msgid "increase the speech rate" msgstr "" #: ../src/fenrir/commands/commands/inc_speech_volume.py:18 msgid "increase the speech volume" msgstr "" #: ../src/fenrir/commands/commands/indent_curr_line.py:18 msgid "shows the indention level for the current line" msgstr "" #: ../src/fenrir/commands/commands/indent_curr_line.py:33 msgid "indent {0}" msgstr "" #: ../src/fenrir/commands/commands/last_clipboard.py:17 msgid "selects the last clipboard" msgstr "" #: ../src/fenrir/commands/commands/last_incoming.py:17 msgid "displays the last received text" msgstr "" #: ../src/fenrir/commands/commands/marked_text.py:18 msgid "speaks the currently selected text that will be copied to the clipboard" msgstr "" #: ../src/fenrir/commands/commands/marked_text.py:23 msgid "please set begin and endmark" msgstr "" #: ../src/fenrir/commands/commands/next_clipboard.py:17 msgid "selects the next clipboard" msgstr "" #: ../src/fenrir/commands/commands/next_clipboard.py:26 msgid "First clipboard " msgstr "" #: ../src/fenrir/commands/commands/paste_clipboard.py:18 msgid "pastes the text from the currently selected clipboard" msgstr "" #: ../src/fenrir/commands/commands/present_first_line.py:18 msgid "present first line" msgstr "" #: ../src/fenrir/commands/commands/present_last_line.py:18 #: ../src/fenrir/commands/commands/review_curr_line.py:18 msgid "current line" msgstr "" #: ../src/fenrir/commands/commands/prev_clipboard.py:17 msgid "selects the previous clipboard" msgstr "" #: ../src/fenrir/commands/commands/prev_clipboard.py:26 msgid "Last clipboard " msgstr "" #: ../src/fenrir/commands/commands/quit_fenrir.py:17 msgid "exits Fenrir" msgstr "" #: ../src/fenrir/commands/commands/remove_marks.py:17 msgid "removes marks from selected text" msgstr "" #: ../src/fenrir/commands/commands/remove_marks.py:21 msgid "Remove marks" msgstr "" #: ../src/fenrir/commands/commands/remove_word_from_spell_check.py:27 msgid "removes the current word from the exceptions dictionary" msgstr "" #: ../src/fenrir/commands/commands/remove_word_from_spell_check.py:50 msgid "{0} is already removed from dict" msgstr "" #: ../src/fenrir/commands/commands/remove_word_from_spell_check.py:53 msgid "{0} removed" msgstr "" #: ../src/fenrir/commands/commands/review_bottom.py:17 msgid "move review to bottom of screen" msgstr "" #: ../src/fenrir/commands/commands/review_bottom.py:21 msgid "Bottom" msgstr "" #: ../src/fenrir/commands/commands/review_curr_char.py:18 msgid "presents the current character." msgstr "" #: ../src/fenrir/commands/commands/review_curr_char_phonetic.py:18 msgid "set review and phonetically presents the current character" msgstr "" #: ../src/fenrir/commands/commands/review_curr_word.py:18 msgid "current word." msgstr "" #: ../src/fenrir/commands/commands/review_curr_word.py:32 #: ../src/fenrir/commands/commands/review_curr_word_phonetic.py:36 #: ../src/fenrir/commands/commands/review_down.py:27 #: ../src/fenrir/commands/commands/review_next_char.py:28 #: ../src/fenrir/commands/commands/review_next_char_phonetic.py:30 #: ../src/fenrir/commands/commands/review_next_line.py:34 #: ../src/fenrir/commands/commands/review_next_word.py:34 #: ../src/fenrir/commands/commands/review_next_word_phonetic.py:36 #: ../src/fenrir/commands/commands/review_prev_char.py:31 #: ../src/fenrir/commands/commands/review_prev_char_phonetic.py:30 #: ../src/fenrir/commands/commands/review_prev_line.py:32 #: ../src/fenrir/commands/commands/review_prev_word.py:32 #: ../src/fenrir/commands/commands/review_prev_word_phonetic.py:36 #: ../src/fenrir/commands/commands/review_up.py:27 msgid "end of screen" msgstr "" #: ../src/fenrir/commands/commands/review_curr_word.py:35 #: ../src/fenrir/commands/commands/review_curr_word_phonetic.py:39 #: ../src/fenrir/commands/commands/review_next_char.py:31 #: ../src/fenrir/commands/commands/review_next_char_phonetic.py:33 #: ../src/fenrir/commands/commands/review_next_word.py:37 #: ../src/fenrir/commands/commands/review_next_word_phonetic.py:39 #: ../src/fenrir/commands/commands/review_prev_char.py:34 #: ../src/fenrir/commands/commands/review_prev_char_phonetic.py:33 #: ../src/fenrir/commands/commands/review_prev_word.py:35 #: ../src/fenrir/commands/commands/review_prev_word_phonetic.py:39 #: ../src/fenrir/commands/commands/review_up.py:30 msgid "line break" msgstr "" #: ../src/fenrir/commands/commands/review_curr_word_phonetic.py:19 #: ../src/fenrir/commands/commands/review_next_word_phonetic.py:19 #: ../src/fenrir/commands/commands/review_prev_word_phonetic.py:19 msgid "phonetically spells the current word and set review to it" msgstr "" #: ../src/fenrir/commands/commands/review_down.py:18 msgid "set review cursor to char below the current char and present it." msgstr "" #: ../src/fenrir/commands/commands/review_line_begin.py:18 msgid "set review cursor to begin of current line and display the content" msgstr "" #: ../src/fenrir/commands/commands/review_line_begin.py:30 msgid "beginning of line" msgstr "" #: ../src/fenrir/commands/commands/review_line_end.py:18 #: ../src/fenrir/commands/commands/review_line_first_char.py:19 #: ../src/fenrir/commands/commands/review_line_last_char.py:18 msgid "set review cursor to end of current line and display the content" msgstr "" #: ../src/fenrir/commands/commands/review_line_end.py:27 msgid "end of line" msgstr "" #: ../src/fenrir/commands/commands/review_line_first_char.py:26 msgid "line is empty" msgstr "" #: ../src/fenrir/commands/commands/review_line_first_char.py:33 msgid "first char in line indent {0}" msgstr "" #: ../src/fenrir/commands/commands/review_line_last_char.py:27 msgid "last char in line" msgstr "" #: ../src/fenrir/commands/commands/review_next_char.py:18 msgid "moves review to the next character and presents it" msgstr "" #: ../src/fenrir/commands/commands/review_next_char_phonetic.py:18 msgid "phonetically presents the next character and set review to it" msgstr "" #: ../src/fenrir/commands/commands/review_next_line.py:18 msgid "moves review to the next line and presents it" msgstr "" #: ../src/fenrir/commands/commands/review_next_word.py:18 msgid "moves review to the next word and presents it" msgstr "" #: ../src/fenrir/commands/commands/review_prev_char.py:18 msgid "moves review to the previous character and presents it" msgstr "" #: ../src/fenrir/commands/commands/review_prev_char_phonetic.py:18 msgid "phonetically presents the previous character and set review to it" msgstr "" #: ../src/fenrir/commands/commands/review_prev_line.py:18 msgid "moves review to the previous line and presents it" msgstr "" #: ../src/fenrir/commands/commands/review_prev_word.py:18 msgid "moves review focus to the previous word and presents it" msgstr "" #: ../src/fenrir/commands/commands/review_top.py:18 msgid "move review to top of screen" msgstr "" #: ../src/fenrir/commands/commands/review_top.py:22 msgid "Top" msgstr "" #: ../src/fenrir/commands/commands/review_up.py:18 msgid "set review cursor to the char in the line below and present it" msgstr "" #: ../src/fenrir/commands/commands/set_bookmark_1.py:18 #: ../src/fenrir/commands/commands/set_bookmark_10.py:18 #: ../src/fenrir/commands/commands/set_bookmark_2.py:18 #: ../src/fenrir/commands/commands/set_bookmark_3.py:18 #: ../src/fenrir/commands/commands/set_bookmark_4.py:18 #: ../src/fenrir/commands/commands/set_bookmark_5.py:18 #: ../src/fenrir/commands/commands/set_bookmark_6.py:18 #: ../src/fenrir/commands/commands/set_bookmark_7.py:18 #: ../src/fenrir/commands/commands/set_bookmark_8.py:18 #: ../src/fenrir/commands/commands/set_bookmark_9.py:18 msgid "set Bookmark {0}" msgstr "" #: ../src/fenrir/commands/commands/set_bookmark_1.py:22 #: ../src/fenrir/commands/commands/set_bookmark_10.py:22 #: ../src/fenrir/commands/commands/set_bookmark_2.py:22 #: ../src/fenrir/commands/commands/set_bookmark_3.py:22 #: ../src/fenrir/commands/commands/set_bookmark_4.py:22 #: ../src/fenrir/commands/commands/set_bookmark_5.py:22 #: ../src/fenrir/commands/commands/set_bookmark_6.py:22 #: ../src/fenrir/commands/commands/set_bookmark_7.py:22 #: ../src/fenrir/commands/commands/set_bookmark_8.py:22 #: ../src/fenrir/commands/commands/set_bookmark_9.py:22 msgid "No Mark found" msgstr "" #: ../src/fenrir/commands/commands/set_bookmark_1.py:32 #: ../src/fenrir/commands/commands/set_bookmark_10.py:32 #: ../src/fenrir/commands/commands/set_bookmark_2.py:32 #: ../src/fenrir/commands/commands/set_bookmark_3.py:32 #: ../src/fenrir/commands/commands/set_bookmark_4.py:32 #: ../src/fenrir/commands/commands/set_bookmark_5.py:32 #: ../src/fenrir/commands/commands/set_bookmark_6.py:32 #: ../src/fenrir/commands/commands/set_bookmark_7.py:32 #: ../src/fenrir/commands/commands/set_bookmark_8.py:32 #: ../src/fenrir/commands/commands/set_bookmark_9.py:32 msgid "Bookmark {0} set for application {1}" msgstr "" #: ../src/fenrir/commands/commands/set_mark.py:17 msgid "places marks to select text to copy to the clipboard" msgstr "" #: ../src/fenrir/commands/commands/set_mark.py:21 msgid "no review cursor" msgstr "" #: ../src/fenrir/commands/commands/set_mark.py:26 #: ../src/fenrir/commands/commands/set_mark.py:28 msgid "set mark" msgstr "" #: ../src/fenrir/commands/commands/set_window_application.py:17 msgid "set Window Mode, needs 2 marks " msgstr "" #: ../src/fenrir/commands/commands/set_window_application.py:22 msgid "Window Mode on for application {0}" msgstr "" #: ../src/fenrir/commands/commands/set_window_application.py:25 msgid "Set window begin and end marks" msgstr "" #: ../src/fenrir/commands/commands/shut_up.py:17 msgid "interrupts the current presentation" msgstr "" #: ../src/fenrir/commands/commands/spell_check.py:26 msgid "checks the spelling of the current word" msgstr "" #: ../src/fenrir/commands/commands/spell_check.py:52 #: ../src/fenrir/commands/onInput/62000-spell_check.py:132 msgid "misspelled" msgstr "" #: ../src/fenrir/commands/commands/spell_check.py:54 msgid "correct" msgstr "" #: ../src/fenrir/commands/commands/subprocess.py:21 msgid "script: {0} fullpath: {1}" msgstr "" #: ../src/fenrir/commands/commands/subprocess.py:24 msgid "scriptfile does not exist" msgstr "" #: ../src/fenrir/commands/commands/subprocess.py:27 msgid "scriptfile is not a file" msgstr "" #: ../src/fenrir/commands/commands/subprocess.py:30 msgid "scriptfile is not executable" msgstr "" #: ../src/fenrir/commands/commands/temp_disable_speech.py:17 #: ../src/fenrir/commands/onInput/15000-enable_temp_speech.py:17 msgid "disables speech until next keypress" msgstr "" #: ../src/fenrir/commands/commands/temp_disable_speech.py:21 msgid "speech temporary disabled" msgstr "" #: ../src/fenrir/commands/commands/time.py:18 msgid "presents the time" msgstr "" #: ../src/fenrir/commands/commands/toggle_auto_read.py:16 msgid "enables or disables automatic reading of new text as it appears" msgstr "" #: ../src/fenrir/commands/commands/toggle_auto_read.py:21 msgid "autoread enabled" msgstr "" #: ../src/fenrir/commands/commands/toggle_auto_read.py:23 msgid "autoread disabled" msgstr "" #: ../src/fenrir/commands/commands/toggle_auto_spell_check.py:17 msgid "enables or disables automatic spell checking" msgstr "" #: ../src/fenrir/commands/commands/toggle_auto_spell_check.py:22 msgid "auto spellcheck enabled" msgstr "" #: ../src/fenrir/commands/commands/toggle_auto_spell_check.py:24 msgid "auto spellcheck disabled" msgstr "" #: ../src/fenrir/commands/commands/toggle_auto_time.py:16 msgid "enables or disables automatic reading of time after an period" msgstr "" #: ../src/fenrir/commands/commands/toggle_auto_time.py:21 msgid "autotime enabled" msgstr "" #: ../src/fenrir/commands/commands/toggle_auto_time.py:23 msgid "autotime disabled" msgstr "" #: ../src/fenrir/commands/commands/toggle_braille.py:17 msgid "enables and disables output in braille" msgstr "" #: ../src/fenrir/commands/commands/toggle_braille.py:21 msgid "braille disabled" msgstr "" #: ../src/fenrir/commands/commands/toggle_braille.py:24 msgid "braille enabled" msgstr "" #: ../src/fenrir/commands/commands/toggle_emoticons.py:16 msgid "enables or disables announcement of emoticons instead of chars" msgstr "" #: ../src/fenrir/commands/commands/toggle_emoticons.py:21 msgid "emoticons enabled" msgstr "" #: ../src/fenrir/commands/commands/toggle_emoticons.py:23 msgid "emoticons disabled" msgstr "" #: ../src/fenrir/commands/commands/toggle_highlight_tracking.py:16 #: ../src/fenrir/commands/onInput/56000-highlight_tracking.py:16 msgid "enables or disables tracking of highlighted" msgstr "" #: ../src/fenrir/commands/commands/toggle_highlight_tracking.py:24 msgid "highlight tracking" msgstr "" #: ../src/fenrir/commands/commands/toggle_highlight_tracking.py:26 msgid "cursor tracking" msgstr "" #: ../src/fenrir/commands/commands/toggle_output.py:17 msgid "toggles all output settings" msgstr "" #: ../src/fenrir/commands/commands/toggle_output.py:23 msgid "Fenrir muted" msgstr "" #: ../src/fenrir/commands/commands/toggle_output.py:31 msgid "Fenrir unmuted" msgstr "" #: ../src/fenrir/commands/commands/toggle_punctuation_level.py:23 msgid "No punctuation found." msgstr "" #: ../src/fenrir/commands/commands/toggle_sound.py:17 msgid "enables or disables sound" msgstr "" #: ../src/fenrir/commands/commands/toggle_sound.py:21 msgid "sound disabled" msgstr "" #: ../src/fenrir/commands/commands/toggle_sound.py:24 msgid "sound enabled" msgstr "" #: ../src/fenrir/commands/commands/toggle_speech.py:17 msgid "enables or disables speech" msgstr "" #: ../src/fenrir/commands/commands/toggle_speech.py:21 msgid "speech disabled" msgstr "" #: ../src/fenrir/commands/commands/toggle_speech.py:24 #: ../src/fenrir/commands/onInput/15000-enable_temp_speech.py:28 msgid "speech enabled" msgstr "" #: ../src/fenrir/commands/commands/toggle_tutorial_mode.py:18 msgid "You are leaving the tutorial mode. Press that shortcut again to enter the tutorial mode again." msgstr "" #: ../src/fenrir/commands/commands/toggle_tutorial_mode.py:21 msgid "you entered the tutorial mode. In that mode the commands are not executed. but you get a description of what the shortcut does. To leave the tutorial mode, press that shortcut again." msgstr "" #: ../src/fenrir/commands/onInput/80000-capslock.py:22 msgid "Capslock on" msgstr "" #: ../src/fenrir/commands/onInput/80000-capslock.py:24 msgid "Capslock off" msgstr "" #: ../src/fenrir/commands/onInput/80300-scrolllock.py:22 msgid "Scrolllock on" msgstr "" #: ../src/fenrir/commands/onInput/80300-scrolllock.py:24 msgid "Scrolllock off" msgstr "" #: ../src/fenrir/commands/onInput/80500-numlock.py:22 msgid "Numlock on" msgstr "" #: ../src/fenrir/commands/onInput/80500-numlock.py:24 msgid "Numlock off" msgstr "" #: #: ../src/fenrir/commands/onScreenChanged/80000-screen_change_announcement.py:20 msgid "screen {0}" msgstr "" #: ../src/fenrir/commands/onScreenUpdate/76000-time.py:66 msgid "Autotime: {0}" msgstr "" #: ../src/fenrir/fenrir.py:24 msgid "Start Fenrir" msgstr "" #: ../src/fenrir/fenrir.py:99 msgid "Quit Fenrir" msgstr "" fenrir-1.5.1/tools/generate_translations.sh000066400000000000000000000001511317357605400211020ustar00rootroot00000000000000#!/usr/bin/env bash pygettext3 -d fenrir ../src/fenrir/*.py ../src/fenrir/*/*.py ../src/fenrir/*/*/*.py fenrir-1.5.1/tools/traceEvdev.py000077500000000000000000000012311317357605400166200ustar00rootroot00000000000000#!/bin/python import evdev from evdev import InputDevice from select import select import time devices = map(evdev.InputDevice, (evdev.list_devices())) devices = {dev.fd: dev for dev in devices} for fd in devices: for i in devices[fd].capabilities(True): print(devices[fd].fn,devices[fd].name,i) while True: r, w, x = select(devices, [], []) if r != []: for fd in r: for event in devices[fd].read(): print('Devicename:'+ devices[fd].name + ' Devicepath:' + devices[fd].fn + ' EventType: ' + str(event.type) + ' Events:' + str(devices[fd].active_keys(verbose=True)) + ' Value:' + str(event.value)) fenrir-1.5.1/uninstall.sh000077500000000000000000000010501317357605400153620ustar00rootroot00000000000000#!/bin/bash #Basic uninstall script for Fenrir. cat << EOF Fenrir is going to remove. All scripts and settings will be lost. EOF # ask read -p "This will remove Fenrir and its settings from your system,, press ctrl+C to cancel, or enter to continue." continue # do it unlink /usr/bin/fenrir unlink /usr/bin/fenrir-daemon rm -rf /opt/fenrir rm -rf /usr/share/fenrir rm -rf /etc/fenrir rm -rf /usr/share/sounds/fenrir rm -f /usr/lib/systemd/system/fenrir.service # success message cat << EOF Fenrir has been successfully removed from your system. EOF