pax_global_header00006660000000000000000000000064135144624150014517gustar00rootroot0000000000000052 comment=d6343012b43cc861eeebb45f194667bde4a70127 torbrowser-launcher-0.3.2/000077500000000000000000000000001351446241500155305ustar00rootroot00000000000000torbrowser-launcher-0.3.2/.github/000077500000000000000000000000001351446241500170705ustar00rootroot00000000000000torbrowser-launcher-0.3.2/.github/CODEOWNERS000066400000000000000000000001031351446241500204550ustar00rootroot00000000000000# All code * @micahflee # AppArmor profiles /apparmor/ @intrigeri torbrowser-launcher-0.3.2/.gitignore000066400000000000000000000005461351446241500175250ustar00rootroot00000000000000*.py[cod] # C extensions *.so # Packages *.egg *.egg-info dist deb_dist build eggs parts bin var sdist develop-eggs .installed.cfg MANIFEST # Installer logs pip-log.txt # Unit test / coverage reports .coverage .tox nosetests.xml # Translations *.mo # Mr Developer .mr.developer.cfg .project .pydevproject # vim *.swp .*~ torbrowser-launcher-*.tar.gz torbrowser-launcher-0.3.2/BUILD.md000066400000000000000000000015741351446241500167200ustar00rootroot00000000000000# Building Tor Browser Launcher First, clone the repository: ```sh git clone https://github.com/micahflee/torbrowser-launcher.git cd torbrowser-launcher ``` Then install dependencies, build a package, and install: ### Debian, Ubuntu, Linux Mint, etc. ```sh sudo apt install build-essential dh-python python3-all python3-stdeb python3-pyqt5 python3-gpg python3-requests python3-socks gnupg2 tor ./build_deb.sh sudo dpkg -i deb_dist/torbrowser-launcher_*.deb ``` ### Red Hat, Fedora, CentOS, etc. ```sh sudo dnf install rpm-build python3-qt5 python3-gpg python3-requests python3-pysocks gnupg2 tor ./build_rpm.sh sudo yum install dist/torbrowser-launcher-*.rpm ``` ### Run without installing Install the dependencies: sadly, not all of them are available in virtualenv, so you will need to install (some of) them system-wide. Then, you can run: `TBL_SHARE=share ./torbrowser-launcher` torbrowser-launcher-0.3.2/CHANGELOG.md000066400000000000000000000146511351446241500173500ustar00rootroot00000000000000# Tor Browser Launcher Changelog ## 0.3.2 * Switch to keys.openpgp.org when refreshing signing key, because SKS keyservers are broken * Use new Tor Browser logo ## 0.3.1 * Ship with latest version of the Tor Browser Developers OpenPGP public key * Fix bug where TBL window stays open after Tor Browser is launched ## 0.3.0 * Switched from python2 to python3 * Switched from gtk2 to Qt5 * Switched from twisted to requests/socks * Use QThreads for async * Removed modem sound * Only refresh gpg keyring on verification error, instead of every time * Updated AppArmor profiles * Updated available languages, and fixed locale detection bug * Fixed false signature verification error related to twisted ## 0.2.9 * Fixed crash issue related to Tor Browser 7.5 changing how the currently installed version number is stored * Updated list of Tor Project dist mirrors * Fixed edge case crash for when stdout isn't writable * Updated AppStream metadata * Updated AppArmor profiles ## 0.2.8 * Update URL to check for latest version, which changed in Tor Browser 7 * Automatically refresh GPG keyring, to prevent signature verification false positives * Improve GnuPG code by using GPGME if available * Updated AppArmor profiles * Added Czech, Hungarian localization ## 0.2.7 * Updated Tor Browser signing key because they added a new subkey and verification was failing * Updated AppArmor profiles * Improved localization, and added Russian ## 0.2.6 * Fixed bug related to fallback to English feature that caused Settings to crash ## 0.2.5 * Fix issue where Tor Browser Launcher failed to launch if currently installed version of Tor Browser was too old * If Tor Browser download isn't available in your language, fallback to English * Avoid re-downloading tarball if it's already present * Verify GnuPG importing keys using status-fd rather than exit codes * Various AppArmor improvements * Removed unused dependency ## 0.2.4 * Fix signature verification bypass attack, reported by Jann Horn (CVE-2016-3180) ## 0.2.3 * Removed certificate pinning to https://www.torproject.org to avoid issues with upcoming certificate change, and hard-coded minimum Tor Browser version in the release * Fix issue with detecting language * Make Tor SOCKS5 proxy configurable, for users not running on 9050 * Improved AppArmor profiles * Added translations * Switched from xpm icons to png icons * Changed "Exit" button to "Cancel" button * New package description ## 0.2.2 * Tor Browser Launcher no longer attempts to auto-update, now that Tor Browser has this feature * System Tor is now an optional dependency * Fix issue where downloads fail because of unicode URLs * Removed window management code that stopped working many releases ago, and removed wmctrl dependency * Removed test code that caused signature verification to happen at the wrong time ## 0.2.1 * Stop using RecommendedTBBVersions and start using more reliable "release" channel XML * Converted settings file from pickle format to JSON * Download tarball signatures to verify, rather than SHA256SUMS and signature * Implemented IPolicyForHTTPS to prevent twisted-related crashes in Debian * Some AppArmor fixes ## 0.2.0 * Fix critical bug with new location of start-tor-browser * Silenced some AppArmor denied events from logs * Print less console output * Remove support for accepting links * Added better support for updating over Tor in Fedora ## 0.1.9 * Added option to disable accepting links, to workaround Firefox/Tor Browser issue ## 0.1.8 * Added new Tor Browser signing key * Fixed removing alpha/beta code due to change in RecommendedTBBVersions syntax * Fixed opening links in TBB if you originally opened TBB without clicking a link ## 0.1.7 * You can now pass URLs into TBL, and set it as your default browser * Hides TBL window before launching TBB * Default mirror switched to https://dist.torproject.org/ * Added AppData file to look better in software centers * Exclude AppArmor profiles in Ubuntu, where they're broken ## 0.1.6 * Updated licensing confusion to just be MIT in all locations * Fixed bug related to TBB 4.0's new folder structure * Updated .desktop files to comply with standards ## 0.1.5 * Split source code into several files * Several AppArmor updates * Prepare for upcoming RecommendedTBBVersion format change * More verbose UI when updating * No longer detaches start-tor-browser as separate process * Temporarily disable AppArmor profiles in Ubuntu ## 0.1.4 * RecommendedTBBVersion URL change * Many AppArmor improvements * Allow installation into a virtualenv ## 0.1.3 * Force installing stable release if available in RecommendedTBBVersions * Removed Mike Perry's signing key and added Erinn Clark's signing key * Fixed AppArmor profiles (thanks to troubadoour) ## 0.1.2 * Updated Dutch translation * Fixed bug with loading mirrors list * Huge refactor of AppArmor profiles * Added OnionShare support to AppArmor profiles * Suppresses output from detached TBB process * Uses freedesktop xdg-user-dirs instead of ~/.torbrowser * Removed all signing keys except Mike Perry's * Made tor and python-txsocksx dependencies to update over Tor by default ## 0.1.1 * Added TBL_SHARE support, to more easily develop without installing systemwide * Modem sound and python-pygame dependency is now optional * Support for updating TBB over Tor using a system Tor * Removed support for stable/alpha preference, forces stable now * Added French translations ## 0.1.0 * Added Polish translations * Version 0.1.0 marks first version in Debian! * Changed GPG release signing key from 5C17616361BD9F92422AC08BB4D25A1E99999697 to 0B1491929806596254700155FD720AD9EBA34B1C ## 0.0.9 * Fixed AppArmor rules that were broken in Ubuntu * Added support for basic RPM packaging * Removed un-used dependencies * Fixed URLs to deal with TBB release filename changes ## 0.0.8 * Removed older code that's no longer used * Updated list of Tor mirrors * Replaced certificate for www.torproject.org post-heartbleed * Fixed URLs to deal with TBB release filename changes ## 0.0.7 * Added AppArmor profiles for torbrowser-launcher and TBB * Removed included libs in favor of adding new Debian package dependencies ## 0.0.6 * Fixed URLs to deal with changes in TBB releases for 3.x ## 0.0.5 * Updated paths because TBB 3.x changed directory structure * mirrors.txt now has local version in /usr/local * Updated TBB signature URL * Made optional modem sound when launching Tor, because it's sooo slow :) * Extra check to make sure the latest version is installed torbrowser-launcher-0.3.2/LICENSE000066400000000000000000000022001351446241500165270ustar00rootroot00000000000000Tor Browser Launcher https://github.com/micahflee/torbrowser-launcher/ Copyright (c) 2013-2017 Micah Lee Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. torbrowser-launcher-0.3.2/README.md000066400000000000000000000035701351446241500170140ustar00rootroot00000000000000# Tor Browser Launcher _**Are you getting an error?** Sometimes updates in Tor Browser itself will break Tor Browser Launcher. There's a good chance that the problem you're experiencing has already been fixed in the [newest version](https://github.com/micahflee/torbrowser-launcher/releases), but Linux distributions can be slow to provide up-to-date packages. In this case, you can install from the PPA (instructions below), or [build from source](/BUILD.md)._ Tor Browser Launcher is intended to make Tor Browser easier to install and use for GNU/Linux users. You install ```torbrowser-launcher``` from your distribution's package manager and it handles everything else: * Downloads and installs the most recent version of Tor Browser in your language and for your computer's architecture, or launches Tor Browser if it's already installed (Tor Browser will automatically update itself) * Verifies Tor Browser's [signature](https://www.torproject.org/docs/verifying-signatures.html.en) for you, to ensure the version you downloaded was cryptographically signed by Tor developers and was not tampered with * Adds "Tor Browser" and "Tor Browser Launcher Settings" application launcher to your desktop environment's menu * Includes AppArmor profiles to make a Tor Browser compromise not as bad * Optionally plays a modem sound when you open Tor Browser (because Tor is so slow) Tor Browser Launcher is included in Ubuntu, Debian, and Fedora. To install it in any other distribution, see the [build instructions](/BUILD.md). You might want to check out the [security design doc](/security_design.md). ![Tor Browser Launcher screenshot](/screenshot.png) # Installing from the PPA If you want to always have the latest version of the `torbrowser-launcher` package before your distribution gets it, you can use my PPA: ```sh sudo add-apt-repository ppa:micahflee/ppa sudo apt install torbrowser-launcher ``` torbrowser-launcher-0.3.2/apparmor/000077500000000000000000000000001351446241500173515ustar00rootroot00000000000000torbrowser-launcher-0.3.2/apparmor/license.txt000066400000000000000000000030661351446241500215410ustar00rootroot00000000000000TBB AppArmor profiles are based on https://gitorious.org/tbb-apparmor/tbb-apparmor/ Originally written by Radostan Riedel -- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the names of the copyright owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. torbrowser-launcher-0.3.2/apparmor/local/000077500000000000000000000000001351446241500204435ustar00rootroot00000000000000torbrowser-launcher-0.3.2/apparmor/local/torbrowser.Browser.firefox000066400000000000000000000000001351446241500256470ustar00rootroot00000000000000torbrowser-launcher-0.3.2/apparmor/local/torbrowser.Tor.tor000066400000000000000000000000001351446241500241320ustar00rootroot00000000000000torbrowser-launcher-0.3.2/apparmor/torbrowser.Browser.firefox000066400000000000000000000107311351446241500245710ustar00rootroot00000000000000#include #include @{torbrowser_firefox_executable} = /home/*/.local/share/torbrowser/tbb/{i686,x86_64}/tor-browser_*/Browser/firefox.real profile torbrowser_firefox @{torbrowser_firefox_executable} { #include #include # Uncomment the following lines if you want to give the Tor Browser read-write # access to most of your personal files. # #include # @{HOME}/ r, # Audio support /{,usr/}bin/pulseaudio Pixr, #dbus, network netlink raw, network tcp, ptrace (trace) peer=@{profile_name}, signal (receive, send) set=("term") peer=@{profile_name}, deny /etc/host.conf r, deny /etc/hosts r, deny /etc/nsswitch.conf r, deny /etc/resolv.conf r, deny /etc/passwd r, deny /etc/group r, deny /etc/mailcap r, /etc/machine-id r, /var/lib/dbus/machine-id r, /dev/ r, /dev/shm/ r, owner @{PROC}/@{pid}/environ r, owner @{PROC}/@{pid}/fd/ r, owner @{PROC}/@{pid}/mountinfo r, owner @{PROC}/@{pid}/stat r, owner @{PROC}/@{pid}/status r, owner @{PROC}/@{pid}/task/*/stat r, @{PROC}/sys/kernel/random/uuid r, owner @{torbrowser_installation_dir}/ r, owner @{torbrowser_installation_dir}/* r, owner @{torbrowser_installation_dir}/.** rwk, owner @{torbrowser_installation_dir}/update.test/ rwk, owner @{torbrowser_home_dir}/.** rwk, owner @{torbrowser_home_dir}/ rw, owner @{torbrowser_home_dir}/** rwk, owner @{torbrowser_home_dir}.bak/ rwk, owner @{torbrowser_home_dir}.bak/** rwk, owner @{torbrowser_home_dir}/*.so mr, owner @{torbrowser_home_dir}/.cache/fontconfig/ rwk, owner @{torbrowser_home_dir}/.cache/fontconfig/** rwkl, owner @{torbrowser_home_dir}/browser/** r, owner @{torbrowser_home_dir}/{,browser/}components/*.so mr, owner @{torbrowser_home_dir}/Downloads/ rwk, owner @{torbrowser_home_dir}/Downloads/** rwk, owner @{torbrowser_home_dir}/firefox rix, owner @{torbrowser_home_dir}/{,TorBrowser/UpdateInfo/}updates/[0-9]*/* rw, owner @{torbrowser_home_dir}/{,TorBrowser/UpdateInfo/}updates/[0-9]*/{,MozUpdater/bgupdate/}updater ix, owner @{torbrowser_home_dir}/TorBrowser/Data/Browser/.parentwritetest rw, owner @{torbrowser_home_dir}/TorBrowser/Data/Browser/profiles.ini r, owner @{torbrowser_home_dir}/TorBrowser/Data/Browser/profile.default/{,**} rwk, owner @{torbrowser_home_dir}/TorBrowser/Data/fontconfig/fonts.conf r, owner @{torbrowser_home_dir}/TorBrowser/Tor/tor px, owner @{torbrowser_home_dir}/TorBrowser/Tor/ r, owner @{torbrowser_home_dir}/TorBrowser/Tor/*.so mr, owner @{torbrowser_home_dir}/TorBrowser/Tor/*.so.* mr, # parent Firefox process when restarting after upgrade, Web Content processes owner @{torbrowser_firefox_executable} ixmr -> torbrowser_firefox, /etc/mailcap r, /etc/mime.types r, /usr/share/ r, /usr/share/glib-2.0/schemas/gschemas.compiled r, /usr/share/mime/ r, /usr/share/themes/ r, /usr/share/applications/** rk, /usr/share/gnome/applications/ r, /usr/share/gnome/applications/kde4/ r, /usr/share/poppler/cMap/ r, # Distribution homepage /usr/share/homepage/ r, /usr/share/homepage/** r, /sys/devices/system/cpu/ r, /sys/devices/system/cpu/present r, /sys/devices/system/node/ r, /sys/devices/system/node/node[0-9]*/meminfo r, deny /sys/devices/virtual/block/*/uevent r, # Should use abstractions/gstreamer instead once merged upstream /etc/udev/udev.conf r, /run/udev/data/+pci:* r, /sys/devices/pci[0-9]*/**/uevent r, owner /{dev,run}/shm/shmfd-* rw, # Required for multiprocess Firefox (aka Electrolysis, i.e. e10s) owner /{dev,run}/shm/org.chromium.* rw, # Deny access to DRM nodes, that's granted by the X abstraction, which is # sourced by the gnome abstraction, that we include. deny /dev/dri/** rwklx, # Silence denial logs about permissions we don't need deny /dev/dri/ rwklx, deny @{HOME}/.cache/fontconfig/ rw, deny @{HOME}/.cache/fontconfig/** rw, deny @{HOME}/.config/gtk-2.0/ rw, deny @{HOME}/.config/gtk-2.0/** rw, deny @{PROC}/@{pid}/net/route r, deny /sys/devices/system/cpu/cpufreq/policy[0-9]*/cpuinfo_max_freq r, deny /sys/devices/system/cpu/*/cache/index[0-9]*/size r, deny /run/user/[0-9]*/dconf/user rw, # Silence denial logs about PulseAudio deny /etc/pulse/client.conf r, deny /usr/bin/pulseaudio x, # KDE 4 owner @{HOME}/.kde/share/config/* r, # Xfce4 /etc/xfce4/defaults.list r, /usr/share/xfce4/applications/ r, #include } torbrowser-launcher-0.3.2/apparmor/torbrowser.Tor.tor000066400000000000000000000027101351446241500230520ustar00rootroot00000000000000#include #include @{torbrowser_tor_executable} = /home/*/.local/share/torbrowser/tbb/{i686,x86_64}/tor-browser_*/Browser/TorBrowser/Tor/tor profile torbrowser_tor @{torbrowser_tor_executable} { #include network netlink raw, network tcp, network udp, /etc/host.conf r, /etc/nsswitch.conf r, /etc/passwd r, /etc/resolv.conf r, owner @{torbrowser_home_dir}/TorBrowser/Tor/tor mr, owner @{torbrowser_home_dir}/TorBrowser/Data/Tor/ rw, owner @{torbrowser_home_dir}/TorBrowser/Data/Tor/** rw, owner @{torbrowser_home_dir}/TorBrowser/Data/Tor/lock rwk, owner @{torbrowser_home_dir}/TorBrowser/Tor/*.so mr, owner @{torbrowser_home_dir}/TorBrowser/Tor/*.so.* mr, # Support some of the included pluggable transports owner @{torbrowser_home_dir}/TorBrowser/Tor/PluggableTransports/** rix, @{PROC}/sys/net/core/somaxconn r, # Silence file_inherit logs deny @{torbrowser_home_dir}/{browser/,}omni.ja r, deny @{torbrowser_home_dir}/{browser/,}features/*.xpi r, deny @{torbrowser_home_dir}/TorBrowser/Data/Browser/profile.default/.parentlock rw, deny @{torbrowser_home_dir}/TorBrowser/Data/Browser/profile.default/extensions/*.xpi r, deny @{torbrowser_home_dir}/TorBrowser/Data/Browser/profile.default/startupCache/* r, @{PROC}/sys/kernel/random/uuid r, /sys/devices/system/cpu/ r, # OnionShare compatibility /tmp/onionshare/** rw, #include } torbrowser-launcher-0.3.2/apparmor/tunables/000077500000000000000000000000001351446241500211665ustar00rootroot00000000000000torbrowser-launcher-0.3.2/apparmor/tunables/torbrowser000066400000000000000000000002351351446241500233210ustar00rootroot00000000000000@{torbrowser_installation_dir}=@{HOME}/.local/share/torbrowser/tbb/{i686,x86_64}/tor-browser_* @{torbrowser_home_dir}=@{torbrowser_installation_dir}/Browser torbrowser-launcher-0.3.2/build_deb.sh000077500000000000000000000004621351446241500200020ustar00rootroot00000000000000#!/bin/sh VERSION=`cat share/torbrowser-launcher/version` # clean up from last build rm -r build deb_dist # build binary package python3 setup.py --command-packages=stdeb.command bdist_deb # install it echo "" echo "To install, run:" echo "sudo dpkg -i deb_dist/torbrowser-launcher_$VERSION-1_all.deb" torbrowser-launcher-0.3.2/build_rpm.sh000077500000000000000000000005411351446241500200440ustar00rootroot00000000000000#!/bin/sh VERSION=`cat share/torbrowser-launcher/version` # clean up from last build rm -r build dist # build binary package python3 setup.py bdist_rpm --requires="python3-qt5, python3-gpg, python3-requests, python3-pysocks, gnupg2" # install it echo "" echo "To install, run:" echo "sudo dnf install dist/torbrowser-launcher-$VERSION-1.noarch.rpm" torbrowser-launcher-0.3.2/makepot.sh000077500000000000000000000001671351446241500175330ustar00rootroot00000000000000#!/bin/sh cd torbrowser_launcher xgettext --language=Python --from-code=UTF-8 --output=../torbrowser_launcher.pot *.py torbrowser-launcher-0.3.2/po/000077500000000000000000000000001351446241500161465ustar00rootroot00000000000000torbrowser-launcher-0.3.2/po/cs.po000066400000000000000000000165151351446241500171230ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-23 15:47-0700\n" "PO-Revision-Date: 2017-01-29 21:33+0100\n" "Last-Translator: Marek Suchánek \n" "Language-Team: \n" "Language: cs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.8.11\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" #: __init__.py:65 launcher.py:470 msgid "Tor Browser Launcher" msgstr "Spouštěč prohlížeče Tor" #: __init__.py:66 msgid "By Micah Lee, licensed under MIT" msgstr "Vytvořil Micah Lee pod licencí MIT" #: __init__.py:67 #, python-brace-format msgid "version {0}" msgstr "verze {0}" #: common.py:100 #, python-brace-format msgid "Error creating {0}" msgstr "Chyba při vytváření {0}" #: common.py:102 common.py:180 #, python-brace-format msgid "{0} is not writable" msgstr "Do {0} není možné zapisovat" #: common.py:177 #, python-brace-format msgid "Cannot create directory {0}" msgstr "Nelze vytvořit adresář {0}" #: common.py:187 msgid "Creating GnuPG homedir" msgstr "Vytváří se domovská složka GnuGPG" #: common.py:254 #, python-format msgid "Could not import key with fingerprint: %s." msgstr "Selhal import klíče s otiskem: %s." #: common.py:259 msgid "Not all keys were imported successfully!" msgstr "Ne všechny klíče byly importovány úspěšně!" #: launcher.py:83 #, fuzzy msgid "Downloading Tor Browser for the first time." msgstr "Poprvé se stahuje a instaluje Prohlížeč Tor." #: launcher.py:85 #, fuzzy msgid "" "Your version of Tor Browser is out-of-date. Downloading the newest version." msgstr "" "Vaše verze Prohlížeče Tor je zastaralá. Stáhne se a nainstaluje nejnovější " "verze." #: launcher.py:100 msgid "Downloading over Tor" msgstr "Stahování přes Tor" #: launcher.py:111 msgid "Tor Browser" msgstr "Prohlížeč Tor" #: launcher.py:128 msgid "Start" msgstr "Spustit" #: launcher.py:174 msgid "Yes" msgstr "" #: launcher.py:178 msgid "Exit" msgstr "" #: launcher.py:192 settings.py:136 msgid "Cancel" msgstr "Zrušit" #: launcher.py:231 launcher.py:245 launcher.py:249 launcher.py:279 #: launcher.py:281 msgid "Downloading" msgstr "Stahuje se" #: launcher.py:238 msgid "Latest version: {}" msgstr "Nejnovější verze: {}" #: launcher.py:241 msgid "Error detecting Tor Browser version." msgstr "Chyba při zjišťování verze Prohlížeče Tor." #: launcher.py:256 launcher.py:357 msgid "Verifying Signature" msgstr "Ověřuje se podpis" #: launcher.py:260 msgid "Extracting" msgstr "Extrahuje se" #: launcher.py:264 msgid "Running" msgstr "Běží" #: launcher.py:268 msgid "Starting download over again" msgstr "Stahování se spouští znovu" #: launcher.py:279 launcher.py:295 msgid "(over Tor)" msgstr "" #: launcher.py:293 msgid "Downloaded" msgstr "Staženo" #: launcher.py:393 msgid "Installing" msgstr "Instaluje se" #: launcher.py:401 #, python-brace-format msgid "Tor Browser Launcher doesn't understand the file format of {0}" msgstr "Spouštěč prohlížeče Tor nerozumí formátu souboru {0}" #: launcher.py:427 msgid "" "The version of Tor Browser you have installed is earlier than it should be, " "which could be a sign of an attack!" msgstr "" "Verze prohlížeče Tor, kterou máte nainstalovanou, je ranější, než by měla " "být, což může značit útok!" #: launcher.py:446 #, fuzzy msgid "Downloading Tor Browser over again." msgstr "Znovu se stahuje balík Prohlížeče Tor." #: launcher.py:516 launcher.py:525 launcher.py:533 msgid "Download Error:" msgstr "Chyba stahování:" #: launcher.py:517 msgid "You are currently using a non-default mirror" msgstr "Používáte právě nevýchozí zrcadlo" #: launcher.py:518 msgid "Would you like to switch back to the default?" msgstr "Přejete si přepnout zpět na výchozí?" #: launcher.py:527 msgid "Would you like to try the English version of Tor Browser instead?" msgstr "Přejete si místo toho zkusit anglickou verzi Prohlížeče Tor?" #: launcher.py:548 #, python-brace-format msgid "" "Invalid SSL certificate for:\n" "{0}\n" "\n" "You may be under attack." msgstr "" #: launcher.py:550 msgid "Try the download again using Tor?" msgstr "Zkusit stahování znovu pomocí Toru?" #: launcher.py:559 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Trying to download over Tor. Are you sure Tor is configured correctly and " "running?" msgstr "" #: launcher.py:563 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Are you connected to the internet?" msgstr "" "Chyba při spouštění stahování:\n" "\n" "{0}\n" "\n" "Jste připojeni k internetu?" #: settings.py:46 msgid "Tor Browser Launcher Settings" msgstr "Nastavení Spouštěče prohlížeče Tor" #: settings.py:50 msgid "Download over system Tor" msgstr "Stáhnout přes systémový Tor" #: settings.py:57 msgid "Force downloading English version of Tor Browser" msgstr "Vynutit stažení anglické verze Prohlížeče Tor" #: settings.py:66 msgid "Tor server" msgstr "Server Toru" #: settings.py:82 msgid "Status: Installed" msgstr "Stav: Nainstalováno" #: settings.py:84 msgid "Status: Not Installed" msgstr "Stav: Nenainstalováno" #: settings.py:87 msgid "Install Tor Browser" msgstr "Nainstalovat Prohlížeč Tor" #: settings.py:92 msgid "Reinstall Tor Browser" msgstr "Přeinstalovat Prohlížeč Tor" #: settings.py:115 msgid "Mirror" msgstr "Zrcadlo" #: settings.py:131 #, fuzzy msgid "Save && Exit" msgstr "Uložit a ukončit" #~ msgid "" #~ "The python-txsocksx package is missing, downloads will not happen over tor" #~ msgstr "Chybí balíček python-txsocksx, stahování se neuskuteční přes tor" #~ msgid "DNS Lookup Error" #~ msgstr "Chyba při vyhledávání DNS" #~ msgid "" #~ "The SSL certificate served by https://www.torproject.org is invalid! You " #~ "may be under attack." #~ msgstr "" #~ "Certifikát SSL získaný od https://www.torproject.org je neplatný! Možná " #~ "je na vás veden útok." #~ msgid "Error connecting to Tor at {0}" #~ msgstr "Chyba při připojování k Toru na {0}" #~ msgid "" #~ "SIGNATURE VERIFICATION FAILED!\n" #~ "\n" #~ "You might be under attack, or there might just be a networking problem. " #~ "Click Start try the download again." #~ msgstr "" #~ "SELHALO OVĚŘENÍ PODPISU!\n" #~ "\n" #~ "Možná je na vás veden útok, anebo může jít pouze o síťovou závadu. Pro " #~ "nové stažení klikněte na Spustit." #~ msgid "" #~ "The python-pygame package is missing, the modem sound is unavailable." #~ msgstr "Chybí balíček python-pygame, zvuk modemu není dostupný." #~ msgid "" #~ "This option is only available when using a system wide Tor installation." #~ msgstr "" #~ "Tato možnost je dostupná, pouze pokud se používá systémová instalace Toru." #~ msgid "This option requires the python-txsocksx package." #~ msgstr "Tato možnost vyžaduje balíček python-txsocksx." #~ msgid "Play modem sound, because Tor is slow :]" #~ msgstr "Přehrávat zvuk modemu, jelikož je Tor pomalý :]" #~ msgid "This option requires python-pygame to be installed" #~ msgstr "Tato možnost vyžaduje nainstalovaný python-pygame" torbrowser-launcher-0.3.2/po/fr.po000066400000000000000000000167461351446241500171330ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-23 15:47-0700\n" "PO-Revision-Date: 2016-12-02 15:16+0400\n" "Last-Translator: Andrey Kunitsyn \n" "Language-Team: French\n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.8.7.1\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #: __init__.py:65 launcher.py:470 msgid "Tor Browser Launcher" msgstr "Tor Browser Launcher" #: __init__.py:66 msgid "By Micah Lee, licensed under MIT" msgstr "Par Micah Lee, sous license MIT" #: __init__.py:67 #, python-brace-format msgid "version {0}" msgstr "" #: common.py:100 #, python-brace-format msgid "Error creating {0}" msgstr "Erreur lors de la création de {0}" #: common.py:102 common.py:180 #, python-brace-format msgid "{0} is not writable" msgstr "Impossible d'écrire {0}" #: common.py:177 #, python-brace-format msgid "Cannot create directory {0}" msgstr "Impossible de créer le dossier {0}" #: common.py:187 msgid "Creating GnuPG homedir" msgstr "Creation du dossier GnuPG" #: common.py:254 #, python-format msgid "Could not import key with fingerprint: %s." msgstr "Impossible d'importer la clé: %s" #: common.py:259 msgid "Not all keys were imported successfully!" msgstr "Certaines clés n'ont pas pu être importées" #: launcher.py:83 #, fuzzy msgid "Downloading Tor Browser for the first time." msgstr "Premier téléchargement et installation du Tor Browser" #: launcher.py:85 #, fuzzy msgid "" "Your version of Tor Browser is out-of-date. Downloading the newest version." msgstr "" "Votre version du Tor Browser est obsolète. Téléchargement et installation de " "la nouvelle version." #: launcher.py:100 msgid "Downloading over Tor" msgstr "Télécharger à travers Tor" #: launcher.py:111 msgid "Tor Browser" msgstr "Tor Browser" #: launcher.py:128 msgid "Start" msgstr "Démarrer" #: launcher.py:174 msgid "Yes" msgstr "" #: launcher.py:178 msgid "Exit" msgstr "" #: launcher.py:192 settings.py:136 msgid "Cancel" msgstr "Annuler" #: launcher.py:231 launcher.py:245 launcher.py:249 launcher.py:279 #: launcher.py:281 msgid "Downloading" msgstr "Téléchargement" #: launcher.py:238 msgid "Latest version: {}" msgstr "Dernière version: {}" #: launcher.py:241 msgid "Error detecting Tor Browser version." msgstr "Impossible de détecter la version du Tor Browser." #: launcher.py:256 launcher.py:357 msgid "Verifying Signature" msgstr "Vérification de la signature" #: launcher.py:260 msgid "Extracting" msgstr "Décompression" #: launcher.py:264 msgid "Running" msgstr "Exécution" #: launcher.py:268 msgid "Starting download over again" msgstr "Télécharger à nouveau" #: launcher.py:279 launcher.py:295 msgid "(over Tor)" msgstr "" #: launcher.py:293 msgid "Downloaded" msgstr "Téléchargé" #: launcher.py:393 msgid "Installing" msgstr "Installation en cours" #: launcher.py:401 #, python-brace-format msgid "Tor Browser Launcher doesn't understand the file format of {0}" msgstr "Tor Browser Launcher ne comprend pas le format du fichier {0}" #: launcher.py:427 msgid "" "The version of Tor Browser you have installed is earlier than it should be, " "which could be a sign of an attack!" msgstr "" "La version du Tor Browser installée est antérieure à l'actuelle, ce qui peut " "être la signature d'une attaque!" #: launcher.py:446 #, fuzzy msgid "Downloading Tor Browser over again." msgstr "Nouveau téléchargement du Tor Browser Bundle." #: launcher.py:516 launcher.py:525 launcher.py:533 msgid "Download Error:" msgstr "Erreur de téléchargement:" #: launcher.py:517 msgid "You are currently using a non-default mirror" msgstr "Vous utilisez actuellement un miroir non-défaut" #: launcher.py:518 msgid "Would you like to switch back to the default?" msgstr "Voulez-vous revenir à la valeur par défaut?" #: launcher.py:527 msgid "Would you like to try the English version of Tor Browser instead?" msgstr "Voulez-vous essayer la version anglophone du Tor Browser à la place?" #: launcher.py:548 #, python-brace-format msgid "" "Invalid SSL certificate for:\n" "{0}\n" "\n" "You may be under attack." msgstr "" #: launcher.py:550 msgid "Try the download again using Tor?" msgstr "Essayez de télécharger à nouveau à travers Tor?" #: launcher.py:559 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Trying to download over Tor. Are you sure Tor is configured correctly and " "running?" msgstr "" #: launcher.py:563 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Are you connected to the internet?" msgstr "" "Impossible de démarrer le téléchargement:\n" "\n" "{0}\n" "\n" "Êtes-vous connecté à Internet?" #: settings.py:46 msgid "Tor Browser Launcher Settings" msgstr "Configuration du Tor Browser Launcher" #: settings.py:50 msgid "Download over system Tor" msgstr "Télécharger à travers le Tor installé sur le système" #: settings.py:57 msgid "Force downloading English version of Tor Browser" msgstr "Forcer le téléchargement de la version anglophone du Tor Browser" #: settings.py:66 msgid "Tor server" msgstr "Serveur Tor" #: settings.py:82 msgid "Status: Installed" msgstr "Status: Installé" #: settings.py:84 msgid "Status: Not Installed" msgstr "Status: Pas installé" #: settings.py:87 msgid "Install Tor Browser" msgstr "Installer le Tor Browser" #: settings.py:92 msgid "Reinstall Tor Browser" msgstr "Réinstaller le Tor Browser" #: settings.py:115 msgid "Mirror" msgstr "Miroir" #: settings.py:131 #, fuzzy msgid "Save && Exit" msgstr "Enregistrer et quitter" #~ msgid "" #~ "The python-txsocksx package is missing, downloads will not happen over tor" #~ msgstr "" #~ "Le paquet python-txsocks est manquant, les téléchargements ne se feront " #~ "pas sur Tor." #~ msgid "DNS Lookup Error" #~ msgstr "Erreur de type DNS Lookup" #~ msgid "" #~ "The SSL certificate served by https://www.torproject.org is invalid! You " #~ "may be under attack." #~ msgstr "" #~ "Le certificat SSL servi par https://www.torproject.org n'est pas valide! " #~ "Vous pouvez être l'objet d'une attaque." #~ msgid "Error connecting to Tor at {0}" #~ msgstr "Impossible de se connecter sur Tor au moyen de {0}" #~ msgid "" #~ "SIGNATURE VERIFICATION FAILED!\n" #~ "\n" #~ "You might be under attack, or there might just be a networking problem. " #~ "Click Start try the download again." #~ msgstr "" #~ "LA VÉRICATION DE LA SIGNATURE A ÉCHOUÉ\n" #~ "\n" #~ "Vous pourriez être l'objet d'une attaque, ou il peut s'agir d'un problème " #~ "de réseau. Cliquer sur Démarrer pour télécharger à nouveau." #~ msgid "" #~ "The python-pygame package is missing, the modem sound is unavailable." #~ msgstr "" #~ "Le paquet python-pygame est manquant, le son de modem est indisponible." #~ msgid "" #~ "This option is only available when using a system wide Tor installation." #~ msgstr "" #~ "Cette option n'est disponible qu'en conjonction avec une installation " #~ "système de Tor." #~ msgid "This option requires the python-txsocksx package." #~ msgstr "Cette option nécessite le paquet python-txsocksx" #~ msgid "Play modem sound, because Tor is slow :]" #~ msgstr "Jouer un son de modem, car Tor est lent :]" #~ msgid "This option requires python-pygame to be installed" #~ msgstr "Cette option requiert le paquet python-pygame" torbrowser-launcher-0.3.2/po/hu.po000066400000000000000000000166171351446241500171350ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-23 15:47-0700\n" "PO-Revision-Date: 2017-02-16 00:55+0100\n" "Last-Translator: Barcza Károly \n" "Language-Team: \n" "Language: hu_HU\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.8.8\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: __init__.py:65 launcher.py:470 msgid "Tor Browser Launcher" msgstr "Tor böngésző indító" #: __init__.py:66 msgid "By Micah Lee, licensed under MIT" msgstr "Micah Lee által MIT licenc alatt" #: __init__.py:67 #, python-brace-format msgid "version {0}" msgstr "verzió {0}" #: common.py:100 #, python-brace-format msgid "Error creating {0}" msgstr "Hiba a(z) {0} létrehozásakor" #: common.py:102 common.py:180 #, python-brace-format msgid "{0} is not writable" msgstr "{0} nem írható" #: common.py:177 #, python-brace-format msgid "Cannot create directory {0}" msgstr "Nem sikerült a(z) {0} létrehozása" #: common.py:187 msgid "Creating GnuPG homedir" msgstr "GnuPG könyvtár létrehozása" #: common.py:254 #, python-format msgid "Could not import key with fingerprint: %s." msgstr "Nem lehetett importálni a kulcsot ujjlenyomattal: %s." #: common.py:259 msgid "Not all keys were imported successfully!" msgstr "" #: launcher.py:83 #, fuzzy msgid "Downloading Tor Browser for the first time." msgstr "Tor böngésző letöltése és telepítése első alkalommal." #: launcher.py:85 #, fuzzy msgid "" "Your version of Tor Browser is out-of-date. Downloading the newest version." msgstr "" "A Tor böngésző verziója elavult. Töltsük le és telepítsük a legfrissebb " "változatot." #: launcher.py:100 msgid "Downloading over Tor" msgstr "Letöltés Tor-on keresztül" #: launcher.py:111 msgid "Tor Browser" msgstr "Tor böngésző" #: launcher.py:128 msgid "Start" msgstr "Elindítás" #: launcher.py:174 msgid "Yes" msgstr "" #: launcher.py:178 msgid "Exit" msgstr "" #: launcher.py:192 settings.py:136 msgid "Cancel" msgstr "Megszakít" #: launcher.py:231 launcher.py:245 launcher.py:249 launcher.py:279 #: launcher.py:281 msgid "Downloading" msgstr "Letöltés" #: launcher.py:238 msgid "Latest version: {}" msgstr "Legújabb változat: {}" #: launcher.py:241 msgid "Error detecting Tor Browser version." msgstr "Hiba a Tor böngésző verzió felsimerésekor" #: launcher.py:256 launcher.py:357 msgid "Verifying Signature" msgstr "Aláírás ellenőrzése" #: launcher.py:260 msgid "Extracting" msgstr "Kibontás" #: launcher.py:264 msgid "Running" msgstr "Fut" #: launcher.py:268 msgid "Starting download over again" msgstr "Újra letöltés indítása" #: launcher.py:279 launcher.py:295 msgid "(over Tor)" msgstr "" #: launcher.py:293 msgid "Downloaded" msgstr "Letöltve" #: launcher.py:393 msgid "Installing" msgstr "Telepítés.." #: launcher.py:401 #, python-brace-format msgid "Tor Browser Launcher doesn't understand the file format of {0}" msgstr "Tor böngésző indító nem érti a(z) {0} fájl formátumot." #: launcher.py:427 msgid "" "The version of Tor Browser you have installed is earlier than it should be, " "which could be a sign of an attack!" msgstr "" "A Tor böngésződ verziója egy korábbi verzió mint amilyennek lennie kellene, " "ami lehet egy támadás jele!" #: launcher.py:446 #, fuzzy msgid "Downloading Tor Browser over again." msgstr "Tör böngészőcsomag letöltése újra." #: launcher.py:516 launcher.py:525 launcher.py:533 msgid "Download Error:" msgstr "Hiba a letöltésben:" #: launcher.py:517 msgid "You are currently using a non-default mirror" msgstr "Jelenleg használt tükörszerver nem az alapértelmezett" #: launcher.py:518 msgid "Would you like to switch back to the default?" msgstr "Valóban szeretnéd visszaváltani alapértelmezettre?" #: launcher.py:527 msgid "Would you like to try the English version of Tor Browser instead?" msgstr "Ehelyett megpróbálod a Tor böngésző angol változatát ?" #: launcher.py:548 #, python-brace-format msgid "" "Invalid SSL certificate for:\n" "{0}\n" "\n" "You may be under attack." msgstr "" #: launcher.py:550 msgid "Try the download again using Tor?" msgstr "Megpróbálod újra a Tor letöltését?" #: launcher.py:559 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Trying to download over Tor. Are you sure Tor is configured correctly and " "running?" msgstr "" #: launcher.py:563 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Are you connected to the internet?" msgstr "" "Sikertelen a letöltés indítása:\n" "\n" "{0}\n" "\n" "Csatlakozva vagy az internethez?" #: settings.py:46 msgid "Tor Browser Launcher Settings" msgstr "Tör böngésző indító beállítások" #: settings.py:50 msgid "Download over system Tor" msgstr "Letöltés rendszer Tor-on keresztül" #: settings.py:57 msgid "Force downloading English version of Tor Browser" msgstr "Kényszerítse a Tor angol változatának letöltését" #: settings.py:66 msgid "Tor server" msgstr "Tor-szerver" #: settings.py:82 msgid "Status: Installed" msgstr "Állapot: Telepített" #: settings.py:84 msgid "Status: Not Installed" msgstr "Állapot: Nincs telepítve" #: settings.py:87 msgid "Install Tor Browser" msgstr "Tor-böngésző telepítése" #: settings.py:92 msgid "Reinstall Tor Browser" msgstr "Tor böngésző úratelepítése" #: settings.py:115 msgid "Mirror" msgstr "Tükrözés" #: settings.py:131 #, fuzzy msgid "Save && Exit" msgstr "Mentés és kilépés" #~ msgid "" #~ "The python-txsocksx package is missing, downloads will not happen over tor" #~ msgstr "" #~ "A python-txsocksx csoamag nem található, a letöltés nem fog megtörténni a " #~ "tor-on" #~ msgid "DNS Lookup Error" #~ msgstr "DNS feloldási hiba" #~ msgid "" #~ "The SSL certificate served by https://www.torproject.org is invalid! You " #~ "may be under attack." #~ msgstr "" #~ "A ttps://www.torproject.org által adott SSL tanúsítvány érvénytelen! " #~ "Lehet, hogy támadás alatt vagy." #~ msgid "Error connecting to Tor at {0}" #~ msgstr "Hiba a Tör csatlakozáskor itt {0}" #~ msgid "" #~ "SIGNATURE VERIFICATION FAILED!\n" #~ "\n" #~ "You might be under attack, or there might just be a networking problem. " #~ "Click Start try the download again." #~ msgstr "" #~ "ALÁÍRÁS ELLENŐRZÉSE SIKERTELEN\n" #~ "\n" #~ "Lehet, hogy támadás alatt vagy, vagy előfordulhat egy hálózati probléma " #~ "is. Kattints az indításra az újbóli letöltéshez." #~ msgid "" #~ "The python-pygame package is missing, the modem sound is unavailable." #~ msgstr "A python-pygame csomag nem található, a modem hang nem elérhető." #~ msgid "" #~ "This option is only available when using a system wide Tor installation." #~ msgstr "" #~ "Ehhez az opció akkor elérhető amikor használatban van a rendszer szintű " #~ "Tor." #~ msgid "This option requires the python-txsocksx package." #~ msgstr "Ehhez az opcióhoz szükséges a python-txsocksx csomag" #~ msgid "Play modem sound, because Tor is slow :]" #~ msgstr "Modem hang lejátszása, mert a Tor lassú :]" #~ msgid "This option requires python-pygame to be installed" #~ msgstr "Ehhez az opcióhoz szükséges hogy a python-pygame telepítve legyen" torbrowser-launcher-0.3.2/po/nl.po000066400000000000000000000134161351446241500171240ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-23 15:47-0700\n" "PO-Revision-Date: 2016-12-02 17:40+0400\n" "Last-Translator: Andrey Kunitsyn \n" "Language-Team: \n" "Language: nl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.8.7.1\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: __init__.py:65 launcher.py:470 msgid "Tor Browser Launcher" msgstr "Tor Browser Launcher" #: __init__.py:66 msgid "By Micah Lee, licensed under MIT" msgstr "Door Micah Lee, onder MIT licensie" #: __init__.py:67 #, python-brace-format msgid "version {0}" msgstr "versie {0}" #: common.py:100 #, python-brace-format msgid "Error creating {0}" msgstr "Fout bij maken van {0}" #: common.py:102 common.py:180 #, python-brace-format msgid "{0} is not writable" msgstr "{0} is niet schrijfbaar" #: common.py:177 #, python-brace-format msgid "Cannot create directory {0}" msgstr "Kan map niet maken: {0}" #: common.py:187 msgid "Creating GnuPG homedir" msgstr "Aanmeken GnuPG map" #: common.py:254 #, python-format msgid "Could not import key with fingerprint: %s." msgstr "" #: common.py:259 msgid "Not all keys were imported successfully!" msgstr "" #: launcher.py:83 #, fuzzy msgid "Downloading Tor Browser for the first time." msgstr "Tor Browser Bundle opnieuw aan het downloaden." #: launcher.py:85 msgid "" "Your version of Tor Browser is out-of-date. Downloading the newest version." msgstr "" #: launcher.py:100 msgid "Downloading over Tor" msgstr "" #: launcher.py:111 msgid "Tor Browser" msgstr "Tor Browser" #: launcher.py:128 msgid "Start" msgstr "Start" #: launcher.py:174 msgid "Yes" msgstr "" #: launcher.py:178 msgid "Exit" msgstr "" #: launcher.py:192 settings.py:136 msgid "Cancel" msgstr "Annuleren" #: launcher.py:231 launcher.py:245 launcher.py:249 launcher.py:279 #: launcher.py:281 msgid "Downloading" msgstr "Bezig met downloaden" #: launcher.py:238 #, fuzzy msgid "Latest version: {}" msgstr "Laatste versie: {}" #: launcher.py:241 msgid "Error detecting Tor Browser version." msgstr "" #: launcher.py:256 launcher.py:357 msgid "Verifying Signature" msgstr "Handtekening verifiëren" #: launcher.py:260 msgid "Extracting" msgstr "Uitpakken" #: launcher.py:264 msgid "Running" msgstr "Uitvoeren" #: launcher.py:268 msgid "Starting download over again" msgstr "" #: launcher.py:279 launcher.py:295 msgid "(over Tor)" msgstr "" #: launcher.py:293 msgid "Downloaded" msgstr "Gedownload" #: launcher.py:393 msgid "Installing" msgstr "Installeren" #: launcher.py:401 #, python-brace-format msgid "Tor Browser Launcher doesn't understand the file format of {0}" msgstr "" #: launcher.py:427 msgid "" "The version of Tor Browser you have installed is earlier than it should be, " "which could be a sign of an attack!" msgstr "" #: launcher.py:446 #, fuzzy msgid "Downloading Tor Browser over again." msgstr "Tor Browser Bundle opnieuw aan het downloaden." #: launcher.py:516 launcher.py:525 launcher.py:533 msgid "Download Error:" msgstr "Download fout:" #: launcher.py:517 msgid "You are currently using a non-default mirror" msgstr "" #: launcher.py:518 msgid "Would you like to switch back to the default?" msgstr "" #: launcher.py:527 msgid "Would you like to try the English version of Tor Browser instead?" msgstr "" #: launcher.py:548 #, python-brace-format msgid "" "Invalid SSL certificate for:\n" "{0}\n" "\n" "You may be under attack." msgstr "" #: launcher.py:550 msgid "Try the download again using Tor?" msgstr "Probeer de download opnieuw via Tor?" #: launcher.py:559 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Trying to download over Tor. Are you sure Tor is configured correctly and " "running?" msgstr "" #: launcher.py:563 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Are you connected to the internet?" msgstr "" "Fout bij het downloaden:\n" "\n" "{0}\n" "\n" "Bent u verbonden met het internet?" #: settings.py:46 msgid "Tor Browser Launcher Settings" msgstr "Tor Browser Launcher Instellingen" #: settings.py:50 msgid "Download over system Tor" msgstr "" #: settings.py:57 msgid "Force downloading English version of Tor Browser" msgstr "" #: settings.py:66 msgid "Tor server" msgstr "" #: settings.py:82 msgid "Status: Installed" msgstr "" #: settings.py:84 msgid "Status: Not Installed" msgstr "" #: settings.py:87 msgid "Install Tor Browser" msgstr "" #: settings.py:92 msgid "Reinstall Tor Browser" msgstr "" #: settings.py:115 msgid "Mirror" msgstr "" #: settings.py:131 #, fuzzy msgid "Save && Exit" msgstr "Opslaan & afsluiten" #~ msgid "" #~ "The SSL certificate served by https://www.torproject.org is invalid! You " #~ "may be under attack." #~ msgstr "" #~ "Het SSL certificaat geserveerd door https://www.torproject.org is " #~ "ongeldig! Je bent misschien onder aanval." #~ msgid "" #~ "SIGNATURE VERIFICATION FAILED!\n" #~ "\n" #~ "You might be under attack, or there might just be a networking problem. " #~ "Click Start try the download again." #~ msgstr "" #~ "HANDTEKENING VERIFICATIE MISLUKT!\n" #~ "\n" #~ "U wordt misschien aangevallen of gewoon een netwerk probleem. Klik op " #~ "Start om het downloaden nogmaals te proberen." #~ msgid "This option requires the python-txsocksx package." #~ msgstr "Voor deze optie is het python-txsocksx pakket nodig." #~ msgid "Play modem sound, because Tor is slow :]" #~ msgstr "Speel modem geluid, omdat Tor langzaam is :]" #~ msgid "This option requires python-pygame to be installed" #~ msgstr "Voor deze optie moet python-pygame geïnstalleerd zijn" torbrowser-launcher-0.3.2/po/pl.po000066400000000000000000000121701351446241500171220ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-23 15:47-0700\n" "PO-Revision-Date: 2016-12-02 15:35+0400\n" "Last-Translator: AreYouLoco? \n" "Language-Team: Polish\n" "Language: pl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.8.7.1\n" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " "|| n%100>=20) ? 1 : 2);\n" #: __init__.py:65 launcher.py:470 msgid "Tor Browser Launcher" msgstr "Launcher Przeglądarki Tora" #: __init__.py:66 msgid "By Micah Lee, licensed under MIT" msgstr "" #: __init__.py:67 #, python-brace-format msgid "version {0}" msgstr "wersja {0}" #: common.py:100 #, python-brace-format msgid "Error creating {0}" msgstr "Błąd przy tworzeniu {0}" #: common.py:102 common.py:180 #, python-brace-format msgid "{0} is not writable" msgstr "{0} jest tylko do odczytu" #: common.py:177 #, python-brace-format msgid "Cannot create directory {0}" msgstr "Nie można stworzyć {0}" #: common.py:187 msgid "Creating GnuPG homedir" msgstr "Tworzenie katalogu głównego GnuPG" #: common.py:254 #, python-format msgid "Could not import key with fingerprint: %s." msgstr "" #: common.py:259 msgid "Not all keys were imported successfully!" msgstr "" #: launcher.py:83 #, fuzzy msgid "Downloading Tor Browser for the first time." msgstr "Ponowne pobieranie Tor Browser Bundle" #: launcher.py:85 msgid "" "Your version of Tor Browser is out-of-date. Downloading the newest version." msgstr "" #: launcher.py:100 msgid "Downloading over Tor" msgstr "" #: launcher.py:111 msgid "Tor Browser" msgstr "Przeglądarka Tora" #: launcher.py:128 msgid "Start" msgstr "" #: launcher.py:174 msgid "Yes" msgstr "" #: launcher.py:178 msgid "Exit" msgstr "" #: launcher.py:192 settings.py:136 msgid "Cancel" msgstr "" #: launcher.py:231 launcher.py:245 launcher.py:249 launcher.py:279 #: launcher.py:281 msgid "Downloading" msgstr "Pobieranie" #: launcher.py:238 msgid "Latest version: {}" msgstr "" #: launcher.py:241 msgid "Error detecting Tor Browser version." msgstr "" #: launcher.py:256 launcher.py:357 msgid "Verifying Signature" msgstr "Weryfikowanie podpisu" #: launcher.py:260 msgid "Extracting" msgstr "Rozpakowywanie" #: launcher.py:264 msgid "Running" msgstr "Uruchamianie" #: launcher.py:268 msgid "Starting download over again" msgstr "Ponowne rozpoczynanie pobierania" #: launcher.py:279 launcher.py:295 msgid "(over Tor)" msgstr "" #: launcher.py:293 msgid "Downloaded" msgstr "Pobrano" #: launcher.py:393 msgid "Installing" msgstr "Instalowanie" #: launcher.py:401 #, python-brace-format msgid "Tor Browser Launcher doesn't understand the file format of {0}" msgstr "" #: launcher.py:427 msgid "" "The version of Tor Browser you have installed is earlier than it should be, " "which could be a sign of an attack!" msgstr "" #: launcher.py:446 #, fuzzy msgid "Downloading Tor Browser over again." msgstr "Ponowne pobieranie Tor Browser Bundle" #: launcher.py:516 launcher.py:525 launcher.py:533 msgid "Download Error:" msgstr "Błąd pobierania:" #: launcher.py:517 msgid "You are currently using a non-default mirror" msgstr "" #: launcher.py:518 msgid "Would you like to switch back to the default?" msgstr "" #: launcher.py:527 msgid "Would you like to try the English version of Tor Browser instead?" msgstr "" #: launcher.py:548 #, python-brace-format msgid "" "Invalid SSL certificate for:\n" "{0}\n" "\n" "You may be under attack." msgstr "" #: launcher.py:550 msgid "Try the download again using Tor?" msgstr "" #: launcher.py:559 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Trying to download over Tor. Are you sure Tor is configured correctly and " "running?" msgstr "" #: launcher.py:563 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Are you connected to the internet?" msgstr "" "Błąd przy rozpoczynaniu pobierania:\n" "\n" "{0}\n" "\n" "Czy jesteś podłąćzony do internetu?" #: settings.py:46 msgid "Tor Browser Launcher Settings" msgstr "" #: settings.py:50 msgid "Download over system Tor" msgstr "" #: settings.py:57 msgid "Force downloading English version of Tor Browser" msgstr "" #: settings.py:66 msgid "Tor server" msgstr "" #: settings.py:82 msgid "Status: Installed" msgstr "" #: settings.py:84 msgid "Status: Not Installed" msgstr "" #: settings.py:87 msgid "Install Tor Browser" msgstr "" #: settings.py:92 msgid "Reinstall Tor Browser" msgstr "" #: settings.py:115 msgid "Mirror" msgstr "" #: settings.py:131 msgid "Save && Exit" msgstr "" #~ msgid "" #~ "SIGNATURE VERIFICATION FAILED!\n" #~ "\n" #~ "You might be under attack, or there might just be a networking problem. " #~ "Click Start try the download again." #~ msgstr "" #~ "WERYFIKACJA PODPISU NIEUDANA!\n" #~ "\n" #~ "Możesz być atakowany, lub mogą być to tylko problemy z połączeniem. " #~ "Naciśnij Start aby pobrać ponownie." torbrowser-launcher-0.3.2/po/ru.po000066400000000000000000000211461351446241500171400ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-23 15:47-0700\n" "PO-Revision-Date: 2018-07-07 19:50+0400\n" "Last-Translator: Andrey Kunitsyn Sergeevich \n" "Language-Team: Russian\n" "Language: ru_RU\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Gtranslator 2.91.7\n" "Plural-Forms: nplurals=3; plural=(n % 10==1 && n % 100!=11 ? 0 : n % 10>=2 " "&& n % 10<=4 && (n % 100<10 || n % 100>=20) ? 1 : 2);\\n\n" #: __init__.py:65 launcher.py:470 msgid "Tor Browser Launcher" msgstr "Программа запуска Tor Browser" #: __init__.py:66 msgid "By Micah Lee, licensed under MIT" msgstr "Написана Micah Lee и распространяется по лицензии MIT" #: __init__.py:67 #, python-brace-format msgid "version {0}" msgstr "версия {0}" #: common.py:100 #, python-brace-format msgid "Error creating {0}" msgstr "Ошибка создания {0}" #: common.py:102 common.py:180 #, python-brace-format msgid "{0} is not writable" msgstr "Нельзя записать в {0}" #: common.py:177 #, python-brace-format msgid "Cannot create directory {0}" msgstr "Нельзя создать каталог {0}" #: common.py:187 msgid "Creating GnuPG homedir" msgstr "Создание домашнего каталога GnuPG" #: common.py:254 #, python-format msgid "Could not import key with fingerprint: %s." msgstr "Не удалось импортировать отпечаток ключа: %s." #: common.py:259 msgid "Not all keys were imported successfully!" msgstr "Не все ключи были успешно импортированы!" #: launcher.py:83 msgid "Downloading Tor Browser for the first time." msgstr "Загрузка Tor Browser в первый раз." #: launcher.py:85 msgid "" "Your version of Tor Browser is out-of-date. Downloading the newest version." msgstr "Ваша версия Tor Browser устарела. Загрузка новой версии." #: launcher.py:100 msgid "Downloading over Tor" msgstr "Загрузка через Tor" #: launcher.py:111 msgid "Tor Browser" msgstr "Tor Browser" #: launcher.py:128 msgid "Start" msgstr "Запуск" #: launcher.py:174 msgid "Yes" msgstr "Да" #: launcher.py:178 msgid "Exit" msgstr "Выход" #: launcher.py:192 settings.py:136 msgid "Cancel" msgstr "Отмена" #: launcher.py:231 launcher.py:245 launcher.py:249 launcher.py:279 #: launcher.py:281 msgid "Downloading" msgstr "Загрузка" #: launcher.py:238 msgid "Latest version: {}" msgstr "Последняя версия: {}" #: launcher.py:241 msgid "Error detecting Tor Browser version." msgstr "Ошибка получения версии Tor Browser." #: launcher.py:256 launcher.py:357 msgid "Verifying Signature" msgstr "Сверка подписи" #: launcher.py:260 msgid "Extracting" msgstr "Распаковка" #: launcher.py:264 msgid "Running" msgstr "Запуск" #: launcher.py:268 msgid "Starting download over again" msgstr "Повторная загрузка" #: launcher.py:279 launcher.py:295 msgid "(over Tor)" msgstr "через Tor" #: launcher.py:293 msgid "Downloaded" msgstr "Загружено" #: launcher.py:393 msgid "Installing" msgstr "Установка" #: launcher.py:401 #, python-brace-format msgid "Tor Browser Launcher doesn't understand the file format of {0}" msgstr "Программа запуска Tor Browser не понимает формат файла {0}" #: launcher.py:427 msgid "" "The version of Tor Browser you have installed is earlier than it should be, " "which could be a sign of an attack!" msgstr "" "Вы установили новую версию Tor Browser раньше, чем это должно быть. Это " "может быть атакой!" #: launcher.py:446 msgid "Downloading Tor Browser over again." msgstr "Повторная загрузка Tor Browser" #: launcher.py:516 launcher.py:525 launcher.py:533 msgid "Download Error:" msgstr "Ошибка загрузки:" #: launcher.py:517 msgid "You are currently using a non-default mirror" msgstr "Вы используете нестандартное зеркало" #: launcher.py:518 msgid "Would you like to switch back to the default?" msgstr "Хотите вернуться к стандартному?" #: launcher.py:527 msgid "Would you like to try the English version of Tor Browser instead?" msgstr "Попробовать загрузить английскую версию Tor Browser?" #: launcher.py:548 #, python-brace-format msgid "" "Invalid SSL certificate for:\n" "{0}\n" "\n" "You may be under attack." msgstr "" "Ошибка, связанная с SSL-сертификатом:\n" "{0}\n" "\n" "Возможно, вы под атакой." #: launcher.py:550 msgid "Try the download again using Tor?" msgstr "Загрузить снова через Tor?" #: launcher.py:559 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Trying to download over Tor. Are you sure Tor is configured correctly and " "running?" msgstr "" "Ошибка загрузки:\n" "\n" "{0}\n" "\n" "Не удалось загрузить через Tor. Проверьте, что Tor запущен и верно настроен." #: launcher.py:563 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Are you connected to the internet?" msgstr "" "Ошибка при запуске загрузки:\n" "\n" "{0}\n" "\n" "Вы подключены к сети?" #: settings.py:46 msgid "Tor Browser Launcher Settings" msgstr "Настройки программы запуска Tor Browser" #: settings.py:50 msgid "Download over system Tor" msgstr "Загружать через Tor" #: settings.py:57 msgid "Force downloading English version of Tor Browser" msgstr "Загружать только английскую версию Tor Browser" #: settings.py:66 msgid "Tor server" msgstr "Сервер Tor" #: settings.py:82 msgid "Status: Installed" msgstr "Статус: установлен" #: settings.py:84 msgid "Status: Not Installed" msgstr "Статус: не установлен" #: settings.py:87 msgid "Install Tor Browser" msgstr "Установить Tor Browser" #: settings.py:92 msgid "Reinstall Tor Browser" msgstr "Переустановить Tor Browser" #: settings.py:115 msgid "Mirror" msgstr "Зеркало" #: settings.py:131 msgid "Save && Exit" msgstr "Сохранить и выйти" #~ msgid "" #~ "The python-txsocksx package is missing, downloads will not happen over tor" #~ msgstr "" #~ "Пакет python-txsocks отсутствует, загрузка не будет производиться через " #~ "Tor" #~ msgid "DNS Lookup Error" #~ msgstr "Ошибка запроса DNS" #~ msgid "" #~ "The SSL certificate served by https://www.torproject.org is invalid! You " #~ "may be under attack." #~ msgstr "" #~ "SSL-сертификат находящейся на https://www.torproject.org недействителен! " #~ "Вы можете быть атакованы." #~ msgid "Error connecting to Tor at {0}" #~ msgstr "Ошибка подключения к Tor через {0}" #~ msgid "" #~ "SIGNATURE VERIFICATION FAILED!\n" #~ "\n" #~ "You might be under attack, or there might just be a networking problem. " #~ "Click Start try the download again." #~ msgstr "" #~ "ОШИБКА СВЕРКИ ПОДПИСИ!\n" #~ "\n" #~ "Вы можете бы быть под атакой, или имеют место проблемы с сетью. Нажмите " #~ "кнопку Пуск и попробуйте снова." #~ msgid "" #~ "The python-pygame package is missing, the modem sound is unavailable." #~ msgstr "Пакет python-pygame не найден, звуки модема недоступны." #~ msgid "" #~ "This option is only available when using a system wide Tor installation." #~ msgstr "Эта опция доступна только при установки Tor в систему." #~ msgid "This option requires the python-txsocksx package." #~ msgstr "Эта опция требует пакет python-txsocksx." #~ msgid "Play modem sound, because Tor is slow :]" #~ msgstr "Играть звуки модема, если Tor слишком медленный :]" #~ msgid "This option requires python-pygame to be installed" #~ msgstr "Эта опция требует установленный python-pygame" torbrowser-launcher-0.3.2/ppa_release.sh000077500000000000000000000014161351446241500203510ustar00rootroot00000000000000#!/bin/sh # This script pushes updates to my Ubuntu PPA: https://launchpad.net/~micahflee/+archive/ppa # More info: https://help.launchpad.net/Packaging/PPA/Uploading # # If you want to use it, you'll need your own ~/.dput.cf. Here's mine: # # [ppa] # fqdn = ppa.launchpad.net # method = ftp # incoming = ~micahflee/ubuntu/ppa/ # login = anonymous # allow_unsigned_uploads = 0 VERSION=`cat share/torbrowser-launcher/version` # Make a source pacakge rm -rf deb_dist python3 setup.py --command-packages=stdeb.command sdist_dsc # Sign it cd deb_dist/torbrowser-launcher-$VERSION dpkg-buildpackage -S #dpkg-buildpackage -S -pqubes-gpg-client-wrapper -k927F419D7EC82C2F149C1BD1403C2657CD994F73 cd .. # Push it to the ppa dput ppa torbrowser-launcher_$VERSION-1_source.changes cd .. torbrowser-launcher-0.3.2/screenshot.png000066400000000000000000005277061351446241500204340ustar00rootroot00000000000000PNG  IHDRvMa"?sBIT|dtEXtSoftwaregnome-screenshot> IDATxLK,Y3s="qoUWwWuZq 7Ԏ@GF;A B DPEq4oNT}dfD9̴;v@fr'E'fDw,WR Q k_)h\6x݅7Jjw"F( *F{k\p֠uG2$" bLRj k 1('T'yGYLiL $e)4 V߃mO0Vlt@OHLH&;C:f̈́4g (`H!,D 31PCS@Lkٷ7J.ub*6):q[d "at0$IPa첢2 I퍽;PLbceqΧ8:c0ֶ;<@KΜDy|WMN;Z SY7ZP}EEyJwR@jmDtbC6V߹To}MzZ8,e``HM7[sPh2CL.uF{㺿e3=;() KЧ›ŒT,4$1qœJP, u|H>G Y Xq"lD:.u44ϊe0 +rib.$IiA2YTټmGYl& b#:xp19KYx,xLDBVa"i!^x`~fͿo[v.;^1pɄooN3Ad+Xnj?|߸n \~uw^Pn&)ץ!m7ʌ B J-aSR.G8fJ"ܶFGBfePHX0h;[x]8cI NUcNl섞X>Ak7Nk2ddr"qʙ} iaDGTipv"ǜdDDD FsY#`-<$Dl6@VppLZk 'ci +bc'.'J$E(!i"ȝYg MzA{m$ ,̅]F;3#_T;wzg18Mh9T=S&%bEIDG ѹ탔 uFLN2X2%FR2L/)wpU90;$8;Rw<ډ6*9l;\xOԄ"Ý:|<2\X(Ra$=f1R9Hq{gk;#&c Y(eb2%Gýw+W TSaS;+k!Űm'#4ʙoBA[WpVUz&T8/癵m Fߝ߉L;'~ξoZn0a3!cP"ydcVIHH 47 a3 :Kh; ũa #)#L34J 80H 2XYM"6*7??x A N$Tu:0h^>ݒwz~ !A]xΙ )䀞IxB:il\yTx;ODx39 23} sy7 f+tOܝq"Y0`*B] ˙﷍[_qGBNgR /\ әoؙSSP^^ (9.pր*0!Aj,PuLƼ =i#RQQ'2 ۺ"+|9}ظ^W,E ߿ky^xFRg ۝. ^cb%wR9(Ht2He{"t[ljϹv!43PcGSo!c@&iJH@ Dy+;zJӼ"D:#O},mL}֨ZaK.Ӊit+{=,2HaA/K33L&xU’…D]5\!͎D Z `D`WtmܨcZጣљ(L-Q!68I%Axt^ C$N7vM #tݝIK V*nʢdr=CH7҅q|Z DH={ b¤r5!&';@b@UDI` SP^bj̵@q\LbIAP\,"Bv4'eCyb~q9,10'w$jeXYt&@3*\GG? i lhZ1ν'3jk 4ͼ?-DqϊLh}myOl [kmi^Pw晋 l}p2>ϼ+yDX=pQP;9$|kBwXh|0 O<al}GK#!Ÿ,-3c)F醦 tFL3 zĜƄ3{Rja jޡ BdQD $*(d~bIYo[c(,u¬YCNϙh1h "0*8:TpjB(u"& m8#(v,Jz,>o+__yOdtMϔG~suK5UYl@F<9F$&ǝ祠NoA\Bsg|x1NFԢ5cB"GmqTT'Lw9M'"S=DhcTWrNir/[eM„}|;۶rÅ{܀J9:Y F`׭UYPu?.#{{`-PH x8m;>dƒ.bl~6J S=m\}GlG wY/cPN {FƝ@KNJycƷc2/rgP癹w:TqcJʎ!{kI$ơHD_~,6ތQdiPę*h$JqO¹T<;2bJd;9?G"* Vw;q9#ӉFM8S3Q dlL|]/T(5xOㆧqT>H !Ag!(&h9_`:bBUek_4ʱŒECnXv2 !%vLTNWAE.E19ctz'预)*w*\'@$ M))X4f2p؅b4r3q+۸R29MF7< y#2!09Yy=RiXs+)"0GpmWuAh%+1 XUpܜR+eIѹnw4cxuq¹7v+Lu}7OFQY+Be,xlH:߉r)p?nn;]eeG*xS/I|}~biz|5vַOL'$d@w^?y_-k+ 2gQ)LZz㨧RiB-`pR@ }^a]!,0U=ԜT"I橠r~RAbE& " Ax`:Q4ٛs|cE Ũ"<- PrzP32ѼT 腽'9q'^rЭsMЧ .Adrd7fOJ~ _}}OE}_Y{tyf؁_<@)w3n )Ma3?􅏟<̂F 5EJIGbL(zWU3ÉMIIPJ-kJC}@eb띾mxqQʌ 46*;R0B+EF‏*H57vf~<=҃~ULJg؝$μH9v+3Ýe>aGmߐRL(zRF,`J.Plsoptz`$ e^x~p;1ii#&&V/X(vmp#,y 2QJINp.:$a%2X+fH1*Ž!j贠VnéuF{GTmC" ImX.x1tuҙlFPa5 6'twLHBI`KUX79'ԉ}љB6Ia8{C4 d a\O-LQQMdxe  cLH5PUc{LJ>SC҃b9 d σ/@Jb %A;9(LޒmTe>ZgUTAjE80IH$6oG/4θ%];R4eDOhh,hTix' ? K"N6a ,уp{,0- cCxV8=- ]Wz T&i ݔjFY*{wvc.3UxlX<\۱( k\d:dGgP(.q[q-7nJ9@rPF27zء֙USQ Bzχp$5bC2aWh9x5 'bo[+r13Ս>6N k4spg]Ӊ!dT72RA$:VFrEhZX)rh`iB+ŝrA1Sqw'jFkPJT*o7>E8' ;U"w^9-'ſgoD2gdWnJLɳeHw%HY֏_1ˍ2!Zq yty+WT:ϴksX>8(.?~྽!u5\ e2htVX֝&R ⅅfwera6g_iFF`Y\FՂ;O|e1fnwyOt"[Tغw'/ 3'`H`@:@J hSEN$Dp;"n#.dQ]3Q( P$j,) A䄄D5;b61O Q im4۝DH1K^G'T2r(9m}^P]4=ݮg."zg(\DXb&Iq\ I`)n;`r__ N_<{|qIñCxrۓͅWȢ`Rx. HgΛ zvBDE=FG#CC,}bpH 3: dT;DtҒH~x]LzəgN2}dŵW4y%bHLJ߃O9PXlFm1"gHn71"nw\v6ccPCN#ؤh$njҘfcN#VRe:dF,|<3" bi.h=mguf3e>c6X?W~nY)9,EԜ u|߹\h#8_Lc6#v5x$w(2:\\B fA2A"94*g~#p#&s6,[uKe~Ouzb5Gu[XJgvB,$[&$|-gZ3Z_Ki7ggøHaρzxM5ǗX1bB h\jEP9aݽsc)FN0O-vv9Aŷ7q IDAT>5YlasT^%q1Kib >W#_O6&5y`Z0]A1Ɲ4y 8_/'.%Lv.Ӊpc9)g=D Jq#}72왐AaQ 3T)7[g44wbH}no>\LΣq*3A냎#s%)a7: QCU4q\Sʈ[7Fj!L&<P3TYNQ&L-=zֳD U0;ˉsED HVz/qm&RِLOR8> L&&wahAD8)R%N`JEaϊN {NSA5m ȑO;%1Yp¡ 7/HƧAQ K}$6:;AkWٝٔa9}?XTԪhvsbe AJ%iEMp4$("Ar%B(5/9/9U "ȔCF/xg;<{Y)Ɯ%SI'dra}d &K9|g$ȍNb(wVV${)F%LZ1VIvLAzrȾ\a!kȕѿ0ftf- S<:=v1 aؼq ^ەpJC5XX 3뾲=;gSvG+f`A33=d}zps}8EHI|@}^05<E0ONF鎫 F;M/PPJ(}PR1ND<*C\᝖V*TW$ʀ q< TjgI5۸AtY =f Rr3Lz=S=1FpAtc(p MB2kgV9r 2W&7/DQm fCq;4ۆT E&j(pSe _u+52q_'|)R,Yj h}:0Pqi~7=4>S a%qk+ᯰo~I;HahІ#(CA7`ΞIeN-;i}ιSͣB,#$66I:+NN^1$6+c5  X*x瞳wJ*TuK[KKs={SЗZGrV` ؾ$dfCUC;)V -^\ׁ3D:|Ki@hX`,K)SZS #6a; c0[*?:,])Mv@;1u~*m0P9[&93kKFJhH;I@*4MMcmRs|q=p(kZ[R0h[)EkQfLkeFk{#~cTfe0/zCmU2̆f2Y7G`R |_ADDQBLYa[nu5EΨFWE__;`i6Dh0*bƒ(E&<YmLu?mᨔƢ1JS1ơfzhjK_bލvD[mlAJZ5cG+ )W>I@Q9UGV}0P  !MՐnh:Y^䌪 k-p`PhVWj\7h7өOѷ:DVRdFtB 4$1b)Ug1t~щ*MF8TLk: ε<ȱjQ [8Qr&؂-kmїA~aϑAN8Wc@nj*GT?"^Y (rO~>pnŠM.G"2l#ĺ[Ɖj L(;ʚ~ah b996!ruld>e5ĕ%UwƲ#MۢR^&'J4ؾtwjBQ Tos`h51dKqRfG2Xu74Q)B2ԱS_Q-Kbj$ʒRI f<ǏLgjb 6 DŽ'U(h'ڰ1iXi!eBY"+M1쳌334qG XuʑhE;UХH~={f  \ MEϚmN$Q4JrP%!PCN;E"dHZ1ض<37E&'BldP2*KHۀ'kRU_reNbJ|$5`,]زks+)ICϸVehY0(YZ1J` DV9F׳J:V` t8P]Bk ҅D3Kt ڈV3-IARDdh|gE;H0gAhJ3I9zWἝeZiSdKݵ(}-lH]d}zƢ u=%[)fv]h ]5ZefeLaj4P)^c"`V WbK@j3ɢ% Qd)B2-4t*B+*0UGHw^t͵u5{|7I t)\x'ǀ }c3Zm\3 pLa}F#džF0Jwjo4:@}#iڗQHfhٙy7kclL%ZR -*VYRUS$UtOiZHL oDc#@]ʤcJUѾ?Ԭ%)G@+ I$Qv }"M웯Sf-~uFR LfXR9<]EIԔeEa JeIkź-u 8?;)@m2n'2NJicMp)OY/bd.)ZcRs &ܗ)h|HNyV f!>et 2(Y4!'&ݤoT#E?JBfGLg-_5(̀QqLutmd2iꆚt$pj@$u:dM?! kF7&d&]EIҞxO}*"mpJUPI1nWiBB~,*MG2.dlb?3r`ࡣ,55ӜoA zJ k#CU3JMiRQx/8!sskX]ij( Rc_>}31 =&"ƂKԗMԺ̨} T (* +I)@;׌fف}}'(M"%ʁ<& eZ[Z1 )G[tgM3(m1*q}+)r2}C0}uTNiwL:$Mt; gZ8h2e"9xRHGiȪ *D9QI̘*fST3.RbpaZ;ƱAcAkr$pEI]~״Kt`Z V62hiaXĈKk$)!jt1R8lQҩtIZ!˹/5 OHXPLBQ ƕl4O4LcR7- lrѦ Q(cN}C^Y%$ /y!Haغ~%gɺ$@-*ErAt=^f|al.ǖ=`mPr?1|kr a6tqV)^)** )b ӄTUR$ E&&t :h\NtX|4Cl]9e29sTІ(}MrEa},+1fh,+ǘi" 2SLiKSxYҦ#.v̻AkB{ Rە>hbAʄ &ؗ%}[2JH/&jͰ}߭7)E#ņ6EFYv(X;^Ɔ[q$8+)G‚,kGjF Vgψxj"C$)JKS %RPeI}/:ĜY͙*mhzd"(֡S$ qo4h-ʷLN)fjCgӡSKz[!B!xI)c[߂y ZqӉr6nBU]h&FliqE&;vsB!B!Gjj|hZR0}C{rER℘pE@ԞnensB!B!^P\r (k44\dBע ԓO3Y4P$B!B Lfa7|W B] 91Ԋ-15ATqh]f ݃}D!B!Bl,LTƠc)C֟V;ոYTj!B!Bͫ)Y-Aq:#("AeRbsבS^z4}B!B! S٬(&]BY9%Йed g`x!|cOA!B!1i.b'X[TA@at{D5Yj!B!BP "1$E U9m6=Oh*Q5&9*ltB!B!TW3SH CP6؅d-dԑB'Q0c[$ot@B!gL[X)4mv,yRn.k*QjM#wBqrf;W\h|w_܀4^b*B!Y8QR{a40&b P yc Bl>)`zg޸mײG/l2CkN|D.\cHU]a]|yB-9?=“m;USClQnJkAJ;ri8vS x AQ@i*".BR+O~y ^w3|E\k|릿Σភ/ :LW[M;^üҽlh|K}Bq&lTgKΙ7p/7_򓧽?LU*91W81QjiV&@ARBl8o/sq9s_Ǝo~ g4m<;_|Q w8O$B)vq+OO*ҮMI3LBLzݗ^vG,EhGaL3{X8|pg-#ۘ`6occ [l 79t<^qKxq, 5;q._@ǖSk6Qƿ'L,B'1̘0N^'B1j .݅=_~ ;Oӟ+3K_Or3.cםqeu3,'8of{/=fzXjBK =$# R&eJ3e-DF =N[NB!>rK$ v]|Ÿ'OLz s(l2ۇރhUlf)? cJs {};o?y䟷jzyL7>ƱGY\353:[R:Xf[ٺy ۷;Z`۶Yl_@80+xx5͏孼/c!jV6Ylo9wk5yߵS9w!h|K5>hiKAz*fMw0)c 1e_!Ygz>j}ݼb.{^9IZכerSˡ˔Ɯ¥Ԛ=-g$ݟk^2".wF,yƼda.!dM;ՀρC륆_&V.]^r7rR(ăڣ#}?$95'R]:jI9uF*"rRcWfV8cV!Yfwp#nF{Q 7s \v1[482;Rǎr7qѾئ Yl;|y+zwzt 1ȁ>Go{xNR KӌeX{,yo>]&_y{/fR2;nol׽nĞݳ}+ 3{]g e\>&cs.t?qB!sk埌R+q5' IDAT++_iuOADV6ЖB $t.3&G .MBdE{)Cp1d<%W27slc';p֝fn_5?K/ͦk^$|#-7WV8vlگ)6fRU0=1(}Tb:xzf2*2)LCr=>& ǒs}K囘RtAq߁=*2^i27&&Gy;_M|nl))styIҰ? !O߹0ѐsOO;︃yi?&OQ yL68k(uF+K6w(oϣ9 ߲qZ!B!}}aD:Q ! ͤ39G10B!B!9Œ1CF ]n!0 5)c%ȱc' B!Bʸ[AR \a\7 `Qtf5h%mB!BsB ]` ϐ1*MG[&@ IB!B! 9+Vub8B$5܏mQb.X.'lB!B!t(JV+hC0xvy@& ɐ#FVB!Bsמ;'c6c,Jێ-1uT`TءRB!B4D0,j@xEzH Q6B!B!qkjŜK`Ε,5tdr*gMZJVRB!Bs\rPVS8MT:Jp)!EE;|B!B! r8 Qi2.h`SR:uF:iB= WntB!Bsp3)uTP(HZElc5d '8SwW>!^~E#B!Rh6]JDx6]sa2dZbV7:~!B!Bm)+*E贆4QioIc"3_sK7:!B!9GC,Ɣ MΑ"w6m$4#*_!B!@5 e %БR&Q12k>sIa4}rB!B!6 S8Qhmbd4Qk֌H+.t"c(rE6B!B!/yOLb"[T)f-47:~!B!BKIQR 0[Z r&}EȘJRB!BsZԤdil6N3҉Bk͔!e^d]Gɞe}x{߻a!B! 9b]"*sІcM-{l&Q(QkiB]wotB!BgEœb4ʖ,є4dl,YgB.̐ ~uϽӏ|ho|?׿Y:SɭzňB!BS3 T4N1&Qr4"D@uQ a+Bio,K>g2 o_ K,..ok+(l*G>A=y;?\wg92!B!Ŭфij$GǠpI΀6D &' 6:ϤϠM7W_W_M7Swsm7ofϞ=ٳ۷?k۶m;[azZs-7m[n L!B|Q:Ϛck5+㖮$JT.麄O6tTƒbdOX뚧uGrWu_u׿ロȶ~w3o{+}ϯrw}'c|u/_;dx[nO?wW~m~;z70B!B!s.,^jҤ)"eE2]౉)]2"&~zMn&x^֚m۶qM7˿+y?1~W?nw窫7Ї瓟+?o{~~׿ OT_r 9>3\veO{]z7v9G')}[=|χ>t&B!B<eTV#QeHЍ75m7|cZlWJQ9t[c|&~EYGW޵a !B!Ljb⊊b0 Ic 6Sp*y2p?ٟ?lԧ>şGY[[cf0`c^sA=|%@?>?׿5XkZv#߻cL=ձx*?:-_B!BgtB҉"MYadmжATh u682C{jυ{[6o7R[??7=܍o{-7?CQ5g"??֚{r739x '}WUY^^~\yc d><5B!uNe\8(̐aqy+Lچ& HTҹ!*%)oFmm \{|M o$;s}l޼\ޕ7FkE]oosz+;Ξ={W;o|ӛ_pxoS[ u?m{׻h8b˖-B!X11й@)@'5I9uŜ(@=9zA/g}7B!Bd`Հ rh눶$(E +jZH9 |)Bs B!xHɓUAB$ 'vBVɠTK S@!B!g;+0ZaU 32T`;+Ip !B!eb4 ;J_3;g!w;ȧeJk(:'hcH9@n0 bCkF/B!B`5@;.Q!BL#GְR 2/B!B  : D ɠ+leʲ !B!b㵾B֎)C:)vX)Bt*"MltB!B!4)0DPْQLBC"bubi>J2B!B!шp-][KiD&Йe0AT8ZotBu޳xF!B!8!xꔘv)k rȣYNisCc2+VF/X߻A!Bq_ތ 4+YU #8 L.#EB!B! ]*Fa24]fԓU3#lfiaҵ"sbf!!!B!6dd?䰉:i&CЦzJ; kXNX(-`GbRm[zJ{sh0 )-2B!I) f:XyV%#Fn*IQfG1gaXF.sz޳B] CZ1&bLS;`0`~~ܳ  !B!^N N O eܵ ""[ q\[kV` 4:%149*R1ڵgJkC377ifϮ휷{G%B!8c{0Fq۽C ,kbD2d9> @GT%%7Oxt:e=jݳC I'S.wG#Fz! [stNIԭcЦ [CVrdE1: 9mfuu;vZko*!?N4(|c'ʻdp//,stsVϙ|Wr*أJRlR`glCKBci`p1Fٵk};wp!v%q !x*rBq‰ ޔ<$NwLfFL]AʑA(jCL0i;j˅c5D2@̉x@iܟϱ[+ '7nB!Nx rmBGKdg}^h[r !%E|D☬"*[ #>Տۡnrss?p=Nq7_9gڕȁs-d!{^5C1'yB\L 2B??gg>L+tڃżUbmg/|[>} ?^{|+>{ٍKMˡ1u,!Z[R6i*S]GCy槕C;W>ZyfV;Nyʶ+G;@@шH%h,Q1%1bƂ( AD&M#w}gy:v癙g}|˔ҥKV_e˖0rH,Z9g}>`6_ʊ VXqE˙>:X~oW\q%ܱ6Wꕫ (@qmH'+b]_yQ>=#bkzؒ?W_;N>PF^s52o}Vq|dggsҫW֯xɓ'3tЃևCN;A\'kx-5ܹs͛[u|{'Z]Oaax"VX+''M`ڹ9g3gl9'0rVy$wܞݧOn~SNqϋ VWP^Di~VÇ/-L.ȺEQ`~Ԩܔk 0D"`끸~Ŋ\/\'Q#G2aDrssdÆ 6lXC> 7opq\F.&xe~<?_%rq35+n;{McӉg?_@eYY3iЩk&3]8YlK,ᤓN"''˲bڵ={긪VpB~?GH*h~eFѴ?W:P\\ʕ+[%S1{d]&woFu7ƿz@0ȨI'ѷodٶmΙÒ%YNJ<}V#lDx|NoIWZ_P%=UUbc&$$%i *XTR9Qpcu*DIwhL)҈D--:"_x/ '&%77'ŋ`z QJ1Uשּׁu9#ry˟–eugս#tk~t[^ӿ^?aٜZ7ndСqmPثCrrrv74Fi~~NMFxJJJ(--e޼y(X-z-͛GFF:tcǎ-֥Dʸ%Wi Jy6nرKx_1h`.2:Cxuc!TK璠w\q_}Z">-vݿroJ﭂ď!l`Co_UX>Si`K?R9TET^JKq`&w=pE> -}}6"6lX.6G4Ɗ7|Ӡ?/cic촏XNP'L0KpXZX#>\5).D'g^ƍy.={1(ύ\K.~wx[8jy[>߼/,f]o喽0R2a'e*M{+#rv?xϵ%BD?>7oF)EΝ?~|R2o۶ӧ'xbrrW־oK{Fi_6nȲeسgh4=33aFyQRR3<{30o߾{gH8L /`+3gdÆ;/E>}NS}B->mYʤwcT'Kj7Am!C0(&JJ,3A( UNAS$2VWI)1]{4Z=R/[ghpWs{pd $9lB?>|d9Ry^ԟg?=nbӢ= ^Vw% 3+O~o?^Gop5cpn,/Ggԋk&NG4U '~޼;"&8o/o?7=} }o$%x?~(J)72:x̿󟼿ӭw6k3^{~CNNN'}.R~?k׮^.#33YfѩS'.r,b…?0 Ldҭ[KC%\eY̟?~/<&Mĩڵk9Mo0uTk֬W^ᢋ.";;>ԧBd&M)RO{.ӧOgIKO͍7|]rUWys̩sCjh;Q>eG$a֬Y̟?y IDATSN9f5_=qlLZ/F , ??Gn֭ Jj)SqFϧ[D8W[o}K$f\vُHKKCJɇs搓Ӌ[n_zիVq=ws-%?qIUvCSԏï烈(oll?!u a HFHlMp Yb.Yg=˗SQ^@Ey ovڤgd4egp,[ʊMcƌiI1!ӻu"5lYNjj|f/Fbٛk9Rv/QUl*eNV-\snk?;[#b#&5[׬ 5ca?gau'  s/gs-/Vo?Ұ6]{eW Kعinӯ3ĬgpMg|m!''K/<6o̲e˰,3qD233)..f˖-\~0#Fzj֮]رc袋;l0VXAYYYݫW^}}v.d8p K9w\@sNNJFFF"//דݠI< abR>͎m4qcDzi&ly}hC)E ,2228묳U"H嚯Tvs">T}h41zcu53aXfMrѣG7)PTm/pc˥FD]J)>C/YP01ϿgP:st-{\@*ux[7kZu7ERvnC!?hD#1V.XGv?ܟo?ٛ'gУ\ro}TεtЁN8,]^zK/b|v^>dΝ,]"\M~inᄊ.))h1֫0Y'>'>'P'?As}JlnlPI;-7ևݭ[7rssyWҥ }eɐ5_%ZSFhڏ#8)%o6oR& )S6F|ɘ9ϫHL yo㏗z* B){S~UUKVYYY R1M~.--[0lmNxaY"@bR(a)Ŵm +D^۶b}M[sssV Fn.XqcnE?-=MK(4FNܱm۶ڊ93gc+9ql\3MspgUE߃6_ߧ?KZR]p/|6zwnObXp=aF?`zCzv&֬) ?Vlj;N.ݹ\ӓVW Ayy9:ÇOǶmxXJKMT&Pئγ}J&nMcK!~O4ѣGuVm /q1R|X7XF9 :xw9s&e1p:|̜9{S&i OzxI۷mC)$#QRXXHAAΦM}۶vYw|f ׯo2Sף{ S?Q^\o.K)uoL %JIPv؆@}VU|B(r eZK^r*k7/lW}{%_7kk:PllG9'G3w9p1U >c?J)vn _ծ@M\?Z2Np#ai@ʡ8Iv$^z]^~=.ɶ6A G@߂F8{lr/l徰]'XTTDϞq %%% nd-yOS_KcOXZZ C(,,L-v]H$BFFÆ cذa|,_c9rWCSB:Uqߘoj[R4F :UVcln mFJI޽[ғ~j. }egK}6)eǴÆfj}nwF)a[vS&QH}7l-3diZa`ŢHWaZ6°q]YT*ʜ '*͘oYfJ u`D8XVYS@{'̬f"/ 4Iٰ֬aW2 3,zyk|.Ow=N9c܇82 hCz{‘R#<./Gfܹ}~N|27w.\zYu]IߴgwfS%ݛ[o]|,.PivtriׯUQ+u]J 2ڇ&'Rk.郑Enȯh1K~sHؾ}{r=!e@,\&`+FnnnrLBbT-[_K#5/w/^EZ7y)>57Dtk~vM7Mh4CYYO=TJG?"33}>Y#׿Fԩ'L ͛Yh!/~: ۃO>_~ 0yr\Ξ=͛O.{ZlF7zw{:ۛڷg^I_h_؟} b(0 KXTJ-b~ G*pI V0xnA0$dŇɒ m>>_0q"rs,[\>/worG2+!Uo>G|R)ÄK8/$CFhZ&q_}*¾on[k,MUh4Kqqq!C$s,]4طlNBE⡌{1 /<;vK.!#3 FEff&}l96},\r%0>VB=HًVo#k {:]"]bϬo/$HR,*^b+TQd,JeeH Wqػw/999)[;w$;;;,jJV.:aдmh4'𛋷oN~m1X[-Qh4K4_k׮?>'Ayy9- . :t: 苨c5n})k׭c%={dԨJ[I$aɒ%,_)!8HYɍnr8kDr<5!otLˇQR Ut1es]6(FŜ'k6`R:vh~`0};c2x&҂Fhjޒվĺ$ T\?5F~uVMǏ Ś+M 47Y^^^:S'yveeIk p/4-,¶mLD) 5~m !60p +$ %|XRQBa*.0=R:td!>~ ^KDc1JKѣmGh4Ms"9aߔO4eo~>Ϛڵk),,lAPh4M|t҅3yt_}3G_!m*iP^#EQö :`b!l IΝ?璟O׮]1YDx F|I%^S⾪sR\ifFh4EAA~>_l :B&LH hoB׶m<!>Ķ,뢄B0bo7}ĢUMv4 ɞ={޽{|sٻHO`6јߧ {FMǼh>⑇&h4ͷvڳ7?>sN$Hj~}(` ۴@FnƓJL 3ZIȀn :YUm_ B;w$ڎ.~X/M(jDBSFfZ7F9P{_?^J8ciqh4A&ԓ)((߳ek!~=s >> cx|*A[vGb\|Ja[~Eni2x@_vgʵx2ߝFh~4'HLK<,xh4…֩h4FiL"!Tq_DWg8H2oto0LPiX0#E @cc&YYqR BB!L0dh,*TUU zVR `[lvbF|ijkyx$TkFh4_' [#k|} ed0%0:0VTd6=p>qmt%' 5q} LB;wnPډh4Cc$ҩY7X'YTh4kF4$s%p\m(L!HᢄVP—.C%j{f|0M$oFJ7 RE~m}h4놔$B5o/ Ea"M Bb!@bQ2Ld*7R M<;IGh4MM^_c&}@h4">E1.:!FI~ ϴ@(0 y  %*VRڥPk47zrv_|+U߄Fh4ɶSLlսe&/Zuڮj D]mO#pKI }˰ Xi8EL*b{1*![l6wXh4Mh)RR: nʭŵEو?Nq^01&T3eriLgkqud͖m6vqվdAqCluM:ߴ.IU?ndYqK,a GO4j D_||4ν{e'gp,H [fq߯f~+\r=W;!]Mwd6nӹ7Ec~~@gaŊپr6O l :}xjKtk9%8@νל5/ݲ:PZg埯25 :pWsԓٷ#F.V?Ogc3wsKQ8:b2'4I)0N|2-HyupUϑLk]#N B}<{Kmng\qUºsψa6{9+ IDATMiZES"%01J,ywes \q;UOuRحֵ/ǬX0BO0MONDu1){0AQ& ҈z‰bHz M*e5בm5q5{{f?i#Yg|.CXI尣` CG0~Ud_ dr&7J&\Jw~h:=}TU( Du⾋`;%acAtNPm>{mWQ_Iswml!֥Rك&4Ep:Y}[A}y8 vC<<H%Tz!qȬ["H]ȝvU^F CERvګj*RnpQZ3~nz{J&.;h53.o|S prcl)ckjo@B'tȚ5k8k KyX>31m WzHba]`O8H7z4[I_5׌K[m~Դ #{ Wg.{x8˘|0]x9ܻöM&}s|rk*:fzy]2lr:hCR5f8FۦppO:Fvozj:^0, \0ƴc;xW.'/:ID^do}mܛ%g|ddu$I_qL\FfkJK^] d3#O~p(A[^LfG/ͽrC/c2a؋x^No"{x{;w#AAM<{mf4~=p{aݼuq^Yɠ]S7μWW@צO%4GeEe\)*+*ۥ bQ-2xn ee<pC~ O?4z-i4׊J?X1'ŋxs\bl]V #c(39J8ͩI5\>M vYӳRܾE[=DhG Q儍0UOJ6/brkoĝW(4!~>fe #ͷtM`tc5~ޜk AWϚ5H :v XCȠ@7Q<r/}AsLT1ﺔ󮼍G\ʎhg|=?3Ch d_\ksהFɥoh `?0@E0eōb&(@*9>Z_kmՏBn O$ o6h4_ߧw}Meӿ#Hw+3?.3yr~ vp9>,dOQx3"#x`4\z9SϘ)W3;xǗab*f,`gGbYGI`M/=U .fd8d9$,8NǷߘػb&cwNʄfؔJ{*h ^se)`H}fGƚ:J5m"spѯ_fjK2ɨoHCPy\p}0[iu {!Ž,Q{C|5A O%]gjfh4_S¯ѴwjŦpLqRw}@Ul`ݶVED|rIsvTyRM p&NOC7ťV: _gz@&7=F؝yJ N=vtӛt3;ZŌqP}:b.)-igҋ3w&=ݤ2nn11zr)[Ma<*D(4#*p3:bK²u͕i>gi9uU\SX`d:;&(rEW}{ҹ'bBG5rjeЩMaxQT l/L,?aaGQe%=*)pY>/Oh1!)@gjZW40tOZ/eZk4? k4.Oz!w&nbgaSf~9km6#}7P2:)͇!$e{wHhbfюa&,y+N8E$yIE~M& v*9޹ыI7=זP!CtHO友b59⚗-mnzpO gzpV8co~cvj6|p!^7N &A0LmiǷ㘘C~P/i'dϢsSlOV9e|'-亩duseÌ9Oor5u|CȖ _frvVa` >ow_I~ߵJ&0_ic~JP8ʼnňJ;ózS_RuigfYXaEzp0(vkL|F5Py S~z~rxg\μ?#ڪ"ݾtȦ{čgç,a6[ǻ|?Dlނ96 Q_T.?pC;ݸ-e,%?㏹a5h1 މH=RyQ6&fZ漿I5[ٷs>,٢rngwwtm^:ooŽ۶m}0!0 49׳:"iXH)0϶p- \l@(0q:o^Td!vH# AL2;fg^K+%_h4^Q *]nCxoAoY)j݊YQ/D+%0m' 2QJ"cD><IGZ1*! tHYg-hA}죸 Hd>h4FHD=kZ܏]a9lY}7kyM6biN~D%q|OZk!޻+ۢ_8Iq5Fh4CBGt)T/WƗ;XSpT4I?JK sB(Op{T[RPtAkaduHI&}i4k4Fs0P`wַo[;`.~K\|%Mi6Ŏt ,K‡ ^% c >wo()߇t,Fh4F9 ZGG&>#`*lJ!<,C ǟ;o=LKK;X]|KHL5Fh4MF>1E,&pcsMaot''[6#w+P`F 'Lfh4Fh4EYK> 3gDmib); NpY)DZ 42QQ²2YD*UGxnFh4FѤ0 #.TVU(3kRR.V`s?!29+6>Gx}C({5Nv7J{|~+ݫH9"8HgU#M-W\^;ҵW# f [q\Kx)صU=|+~.*v׿n|ϖnBAaKٹ)5ol6ڛ!cs'wQ?w^! bAņX@E`{;>VDy!"H/$žHnfwi}Ć?Pz2C,tivJii\RqRlq pq /̋U +iZ8Ra6|C!0pT(.R7 ro)ĪThGIBneMհ($K?5TLzq>=\S^ƉPJn&vNbNV.Zϐ˞uB76Y_,qiiiY5!`(BR^rl#T@bY#ʟHy|] &ԫa56N:>#Dᆺs{R %c{d-FWUm9W`p7}urdZFwj@Z4eW_+Fdt8,'??a ´oy<]|7pma^_EBr,w=_N_g.VӪ\qEd֔y)S.޻Mۺ21d9ReR/ ɱ,<*%Y^I˧~CֵhܮY~>37{Kr,`U4M4M4M;KA ȓ\i` rlL r'kH܋%|ɟ(btBJ.1xL7蒽W2?0w'ݟmJ˛ˣPL{wT5bov2yNױMp=[?7X?<*˻Laɜ)Cng뺝XMjR nvj<"I,Ϛ%)'>Ź yu{޺px?%l OXh}/.vyOeU/?sHZ^I΋a4j[׽c4nW~byvFnnvҜ;M4M4MӴIH0 LAJb\ˇr8 o(պ@T6U[ GH"l܃7 x$Ӓ%Q[9\bF Z–rHnFNVP{fߺ~'~Yͅ};ndgdJҷcܕ܀ RIU괨ά) X3ͪ%ju2۝ɲWѸmR_\>=*L}9EL`2r# z :璛8"-=;E ҹy΋;&Z\iiivX5^,W\ LG %%{lI^r, (GYE H h.$"{J!cO,g.NhCFz~fז=mQ"cOkEfU%X2fphe>:.1ǛOiqE,WPGqfKt^V.ZE1-=SmZ~wH|Hr20bqQ|֠LxV( ?Ơnz- m#kE<;7 J"X:"c"hЪ& ɱ4j[g(U'+ ɱ'gX뼤HK0MqٶaW cd掎?4M4M4M;] Kb6/i)Ěi ,^2S[A)ɲ(aH!LxEx j2%/HRXެEOM*-_巸w r0~w"6:am8jsÛ㿘t KKjpij>}'bbbdd\0Pj֮qB'PJbY`1nji:b=*",|LPJ/GPH$.3}ii\JF= ˲x<1u 0M `&ir<IpLaz1 W^Lab`Bۄ .ycu8Kx%4^h|;t <ދyٻ1Hb,k> `F@Piiiig;`e! ke0&K)AVKE V]? C_![3. IDAT*IrݜADX G:d H"|Sa+[jiiiX.AIq%lY7Q 74=¶J] ͠\"EXc 9*ݰT,$n|n~y*R(:^M4M4M4M;H>/eqm"P!]L p ,O@f2v.0(m… #Bn-(TDĘ\͚1< OIbXrڗ$X g_A;ezqdxΑiZRN:("M4M8^aBP 241P0V2#\E+u6~W%o P0ߒ7 vѶռh Y98ʡl6%/7@t?iiE&55Ti-Zt91 \0j&}=fXzEү ^l&2K[!2JhUlX `G{;_?\JRq 2&$E4d>C4!66T8OZSeǏo_*k[~6ɲeюR~7ݻ:McoFr?'(3X0%&=pJa:&n b%52<Ӈcz C`YB8'<\揕wb6i ~Zþy,ʲ5,O /ĖمuطfMn.t] 4w?e+$t~nIϖiڙ(o6bR" MDf5`$Sjg {9n//كO||[rωl?;oZ!EH4B٤h܁^ [>>0iE0ǛI6NrL=ѼY>FƲXTPFY<;&^G, q]a9Hİ]]WD80 8be߃IPLb¨wNMhOe*vW{Տu;%MGаUjI?{e%^ ^ߝw G8 .HȈЄ۩ޠQh۽9#>cͥ17pN*pPT&iu>エ0T~r0ν /OO9"b [3F~t7 iک%bѢui߅}Of2m @i#+Pzs?kF$w7m?Ҕϳp\4J͈q}uW4N$I˞ʊ!Tނ)\nv1՟=mP!9-z0fЏ [ףJJIźY9c䉱 ׍^7>zR۽C=74gT=t.Mj\ qpc5<~ yJ;9PUir>X#v~:0W{ӶN+PYWqPTnꭒPv Pkֱ{7Sӱ~%RRШ|^bN5`J%"׫PJ r²H<USJ)-3p\e# &ѣV|CXT/+%?ws>_o߯L.'|ͺ!KrʅGqs}y),2yhl]76{CKA~+8KvuH=o>1\;x+#.WcpxZcrK8V-@FAC|r,Cz,?|0mq1dg%FEc .02<ĸ{1Q.ϣ1Z0o7ɰsN~KˆIi$ΨG痻\ÏSc}/7'vw/2xo`kxeL+:i3Yv^YżtlGM+#o}k>ةRݬ]&Tɒ&o|wDT].xOh#T1R}0/ M,{1}A] _D)o{.&DRWOD\/?\sF˥>`ƨ.ĩ MegDyI5#̊5dGk]D #KLV^z@DQ]<ӭe|?M1# W^8ؾn igc Wa_Op\‡ -pk׉_=Epf*Uu!#Eģc\>ҳojCxqPx1PƒT.eC{,wpf{3|Any!'#q<&4jW_jzܯL}¢Y>yO_Eu3rY2g%tJZtnglL>B 5?.OՏ.kC8BIir>? vlSO&p@;o: %(.\R73sC ? If 2>|4~ 3z,ZuBBbtiUK!$]!\4EИuuJқ3nMTr歏MؙHّ-49$g7u+E;Ky%7V4}v53MaʒImf(kЦc;YЦnAyqҨ|obi!Vʼno4ٯjйXOGZ!{X4ujKȨЗcWscWZׇn$r];3ھUKm,\٪Qs~AyRE.ifi5IӖܫ{s7ʴҎfI4nMźwgBsjq̃cǸyԼ{ l >{GKuZiX^0c)AHa;X~;% #\0,o!J)\$K#ڌ/s5zEyR@JKJnĕI=q])k`),9qcV(Rxٿxbm۰qCK^ ر)O_u6ܨ3rٷg*1\ԯ:qX!H/b^\1dS#{ǪiM,m90Ӂv)nj^-zA|{&i^&5f.&xACoѤEYGVJb&9$1\O>[/cco,7gTۊ%jU.I\t9<4f=4jX6@!hؾ_A * /7؏^T k݋iڜsYKsׁ穋9g\hFh%Iv/[ƎJ^<"co-pDlEIVڋ"ARrY "J1Km@&y ;R[6T(yvr}d>}vs}F8UμOs>(~IEK9("5pv!Mj\y7Wnיi \=ؙTq׬c gO6u9\-F Fiڙ#wpl_&GLj^pGM%} FxYwsȎˀea"9zűbfk7^7g>`F,cirtxA>%ٳ:&y( VLzo~$PZ{oۯK^eL7 I^Uyzd39>F83=|0ercA)6<\| >n/tŠ RψF?vw%izq2cXݢϓbr+4iT_uCϡ0 L^7bTrEF25Gs_fjGI}kֱc_cv 𭝀cc鉀hr3p< X)Zz.!%<7EJ\l\e"q] }}G>//<|O_x-/Y^lm1 Q4lS0v3TBJt%Uzw%l۰c3%Qz2pϴ*X16":ܬg6kDmgh`av%#Iܪ=njXMQ)d٬]98|)^1q敮9|3SV $մu@<~uzFeEgLh,a A#0p&#@X2`5 <LlW:'~KF_eJKx#[esQ][qs[ng͒,y[0QqQK`aO3ѝ_wH3_mڐny_^8Yޢ˸wt?|c3?_יPy5F|tҕf1O,wֽ|>n:w=ߗ<~[D)WNJA)uH_5O'/F~vHbch4nq5~^6b>߯85MӴCec9lpػy9?fgt<)4.ֵqěv#8. =2ƨC/>"[*fՕKaD]4K^I4I?ǿp~ǎ['}_畩t7S8H{(~DzR10Kv^ib$P}bkI5 '"m`Snwx]<7 1Lt\UЭg8gxR].y^'"׷LyՑ|ӝ2 M%Nlmmd!04,"5tӞ;GrK7N#I1=νS_=){B{N]hZ= 6hB]a“Rw6fPsfaP&G&p$11Qq]M-\­]jld. eNxc86C`ˇ$&na#CJ)8pSX($v~]! A 0qC 7\}aDDZiv66J8b+_؆?|?/EW2ùLpnm.hJNfq_OҟWzӔ4ea?GO4M;D)7RjиVJM*q-z0f<3lO0V G#ea2Ws^4$r>}\w>qiٟG^0ֱbۈvܰ=uZ1p`>0{zl}zB.EoxFŻRѹbDs9J\5m y^+yT;<dڙtّ /KsnէԼ_}c暏51kI>C?co=6tI#Ǻh4c?Mh*7Pcx$L!UWpa z.SK!3#S%wOJ Єz&B(U_`D*PaaR J!q< ~SZuj^=/cci^;W&KOHwʬ^>4"ȳeigÿ=*"5. S(HdoE懲mǾIf23K2ILL j*UvMV/Rヹ<6tiҹzexxca@!4L ӤóQ1Jm<L,׏kqX\v '-P<$J:HTl)Ba+ *V#+O MZ#BR008r<>L?DWO!iJWԵBr+4 IDAT߃bmt^4L q1:9Ɨط';hR>aV gg 4M4M4M;L!\Lb0خB)Et m…V&r1~hzVl{AaE,;3yH(@Llk%"s{vDZ}[ t|M4M4MNleG9iEca`\tJI\8Z *Jϯ J]vmŞ]DDkaYiCҕK0$+#l?St^4_e͚5dffo߾㉍f͚>oڵdeegϞ)2M+Dbcc^)+#G aR"]" +l$>+t$.&$vj]ɇqҢ`sk+2f73?i Y;C2>UX?%_W5M֬Yi4kti6l`ڵG]!:u{ӴRZx1֭F$Lk`kZH le#%,l ebb`sJ:Cy8^_N_!R[iڿYff&]t9ah?JBB3f8YYYtرpH5kO?t(?Cb``@cHT6[rFzzR+c׹xӛpB3wdb .U䬟GSwdB)P_{R։DA ^LLB K p  ]hj kDvHYO>M!5&@ewU#w >]8zp}~Lmc[x7b ZkyDe΄[;P#!tMfW;;mzyhhnvL[6 lg0{R:7C7:y9LPĨpˆN\tiX]V$׮Mp8`gv^n2m:-ErRҢwלɱDGRȸw-g]+a`X&ǃ+y69y`8~,00,<"I4M4M+:% <|0sߗ:ҽIQn #kDF4p%p#O?y'x1R;˞ťT&4vu} y9ƼY<ɷ_ĝ?W>n""ՓD,2LƄ>C-Crisʗ'. س?Oڕ=K@Ls,vo)NxudnzFO#'cy2~X?_Ah hd*OR_n=֑^v>݋N6雗QbrOe([ r"! ^ȐL\ I)^kiڿAJö֎Ub02k׮%5b y]GWJ\t5~U-:1>/:R(\'V_k6/ؙI*WFa 3;.n]J)ס/OOJA3CՑ*\6*MncrzI[`$>=9~EU$, Egs)s"qi"@~Ǹ׍}^Euϵ2o?x%\ܟy'0zܕC&K>bGiXƭu~7p(FБfW^22~|l]./|OLjkѭSLz+{_`yӦ4mڔMP1*TzюZ*D*yȾ\&ӗC˺UoEǬe+V,{hkS֭hօ}`‡:ko~69ƯFЧcC*&Ƒ\=Fa".+R {xJe"..ny IQc([<`A˻ċb #,>D}|5-u'KJN1oIVQ9iӾ}{5)OFioߞh^9揽'>6-/OVSOޯ|Rk#>:M} DlUlIvꁼ;i\_CY>w^ԚKrxw\}cWzX[^bN̼u17_RYRbpA/]M}:eTOA,"*T$BHny$@pܽ37;w+rsjOZQ3,ǟlwAk:e}cˡix+ZYVf/m&Nc>u k~pVϏ3SѮh^X~fYmbGAwӎR%3 'sp. k+f#bmˤ(ٶuѬt?C+ENZ+_w)?lICՎx sx{wqM OүfR: Ķ]gd*HCK?*&C\\풽b$=M[f^=;ZRϣ}=> ml.deeVe։ӹ4}RƯ0Hw(uc]ː`[>*g#/"] Oǯco.4ڌMu?3?۫xXZyOy<=q6;a3o5 E5^[G_y5Cca g_2{\L/Mö-(6h,Dgeզ;nAc/`Dc/i cmI@k?:'U86]B&7 «Syw}b qԼDD\x!-+q̆?̐+|cY1IkqGWR8YqҶ[(HTb4pXn wCP E#y'ysiHr/{5ZiifYJ'JHJ&=hTvOX>ynpv!N>)pH?4dۑ |浕c]23NF7Rt>a=%;7 ȧ~G(Q Ѓi&/Xē|H nRΛfe+F_T5ոȸ|%1iVh@زNo4O.'-Ӭ^ 4ptթQ[ [b~L5OӴ^|}~R ö~'\G KugSS 8z0)w~wڷ*pbDڎ}+SDiuf Ff&x+Ж9jO,۶wNghJ~X"7~ĚݷQ~|X.rLI_fZРuI?*ĵ=`zE1En(M˧<C,dB! _lDlMCMYoV\?pR|=5-rEl6΍(Lrr2ɥjp˒\y?//6{Wl fT#J'[ ^I{s`w繲l0]@ԑ O]nFӘSJrS/22׊[ O|fMJ&8Ѐ8g#_&e֦}>l]Ƅ ~+qʼ'8|m9;2NDbl:W_?CoZD\ We7ЪT.Ft\I*ȵUꛌlw|1JB<'TwswFI}XTZc.7a4\ֈտ$tˬXmU<غ {F#Xc>c>zoӆg]=ya.7keR=[ӲT IhG&U#+>x;WjWeCpW8s{IC,q76iA{flkv^-MGqNdcZ63\` ?<̈́BqNȻ;V{om/a+jr:ThmR沧y:6Fz, ᮒ|֧v{VR2a!8ڊ)8+6Nwl=ueQ//rRʟ+,Y$iرSW$G4g+̲=xtE7H[6r7"RINw?Jݹ] G[ԒkN%7s&l'g#{c%?7=DGR!Z.wAN,# v2ݣ,9KS}Iv[l͛]6){ =IJPGz5:OW>zz*#wN":j^KFK1xmesV3HO?Ыz=b;kxFkuL&z JhмrKxSMjU_^eP8$ѡkCFNX̪̲YNgdq](LOi_is2y/Ǹx .7vѶ|  5[yK8'UBvG.\vTt2fϿQɎBTRS B^W\N_7^DV,gR6t+%OEg.ex|{ ,>N kBVӭыdmF a>Y}qζ,1&-5nD(O2a;Q+*aMZP/Yˀe|sAc-OqG8YZ\b47n痝mE AQllGoTLCلj\ @cXEZԮߝf=LrwHs5ڬJݚۿڌ>)|G8z∤WrK+th_~cl+r*b]iZ:5ԥ\rsɣ@Y>u3YݬKJu]cxlf9-aՠl;-ClQ~UL(ӭMܩoxo6/Nέ IkЋաt4d$.[Ԏټ;u¤6u1x58 X>|h&:pM!g&~k=`nT l`Cy[YloHjװ%[2J˙r\5X3_3EH7 MgKpqZwTfkt'n=#Ԧ tlrPzgsmxxP%v}%Px*S\t~6̗>!4-}DYxK$E5憡96sc==f<_VĒ%P8l܉6es{uޟ }|wAq+C jϏ|OqoϜ+rOqiɼҙ sBĄ{#_60uhP)3k+fr%~4ĹS2MNdQ1þpy !nVn:LÉGTdm¿HFeԯYso1e\߬&5*Ul"R @6H?32]#S1>o5t7.>x?~VѢLzUyfz;ѠJM|K3>hQpi4 WQa ˅/h+c15a%P'Bԃ'zcϑi%S^h#N2w7?>oYJ4Q\ ElR2<*z,]jmJ$AFizAWrs 0k'RuԾ ӃO $;a-0Nyn~> U1`*&U IDATnxoeؓW5GW⋏~͡?WrVCtX`*%ϼÞa24N{C߰xhn*51LCJTn3xQ|6LrW ѥde.~Q1Zux$3f+=`bS;@R>΍,nM'`DQF=b2weijgfRM.{3]x?gܤ3'!mC&3Oy{ ڞ!{q}<^w'Rי11o +7p_߲bJA\ }8]M/Tӌg>ǐ)sO1yL5fJn1VۣΌYn}P %t/sre2uI߲p$6io>ƅFx<*JY1=pPc&{ʲ ip!;'Ⱦ;E]!r Q}'{yC]\W.B;ج_ҥK⋋:Bu̙CҥKܹ3{Ǝkg_?LBm;LF|(laeYŋ{.Զ%q0юkx1AvAXamc` ;QBKDQ@!Oزe ###"@LL +W.X:2 <Wk p (,[Q! i,4BeRiӦ"~znJ*U %}q1me0Q_Up ÂPHB!ٷo[F:BB!@  -}°¶Le jPX(/\p(@DE8B!A222q/H1 d eZJay^aa1o)IB˚B!OB!Val\0L`9^S(ƃO~rB.ن"06B!B!ΛsoYxU< Մy!:m,) !Bi|c׼*lNs$hw;+*²I_3)޾T5n'<EM)P@&a4!7HXy0g00v h5xm)B!8{ۧP>Fkn_xs{NW-|ry$CΏA9ߗ=äװKc\Ҥ~t;dnY;7t)lMr|{iye? A3!&>Lq 9&8DĈAOQ&ABsEhPH9;9#ie͋PQBJY~gcp/^EpQ)|8 usS%ziu0f7<;*vMSSI-dd#pإvITM-CqT:~2 :&;7rlL cp V\rPs?B!8hNqYe"xgƼKtb0*v1,g _~M> L$p~`޼(ZDD2f WZU3僡EBg!Y44v5r a?蒫LOaxLR]eB! .v)Tz/n]&}L )2pܟ9ۖ|ڕ)D*M{Egk޻5SR21 g^l^XɔӞACym\֡%X.}p{rM4DlL *4=oo#x} b@ODA8~|gо!(Uz|%s nShbKVKaq3skT4ͷSW/js$]hM_ ʓP?0N'IMRKx.P~du5:[^M*%OeҸ >lG $H(ӏ¤0alqC(BL)inC{@5QJS!ᒱk7T,bɬ?@fNZH+fqAܷ3f>X VxW9(VˋjOZQ3,+}.{k斷xllz|e'V{rIgᔧ,"w h[Cw?Ϟ"qV׎qKS(#sYi.fsYy;>C3&\=2sfwˋ>/?odΚ\׫:x1]v/ʿϧD|xmׇ;Y Z6~sxN'5P=|ߟ7\J)* 1h}fӣkbn15m+@Æ%ĭL#I%d Fh!/A3x["SsCo-K5^[G_yM8pwÐ.X<1G+G(P1{{fPuW+P|{ZD/.ЏQP3:wsy/օ3/^Չ??#Ul~)y.H[! S||2vWY4(i@qwd_kPIVAM7g]|yǰ]k4w" kˍeޗҒm/{ ,2СMІ*h|?Di F :vUC/<qLV@[ZЪS<f_Wbb&Oy`€r@:XR,M*mD^Ӟ˧y@e/L.Ÿg{{kL3,1i Qw~T#GBGa(x, ӰpP"jr6] XZ@xe=!✠'3Y< 28uӟ[yDeL=dv›XU -[Q`A~S╨D4HlX57 oFړif&'*R(E#Ÿ᭟+pQxzCϧIݦT;qcg˶f=, !*j}1,ۺ-U?w Ulk:%/%7keҡzkZ awG|޺o%㉏'L_^e7Gpz~1saqwq 8-zA=Q &!\"AX2k*.^!d* 'skK]G#SLOi_is2y/tU7+v IG.$rıʫ~c}xQGEkѪ8[˜ OlY,se?j]h¶ 2uj9Zq.!NݻSjUVZ_P+LAl  #=p\mV{B!9boDDFЍ' @Q,uޞԯmU|elV_Qсv<~LŞa=^ 05k$KZkEtJ?5 oә<{xo6CP|Z.N՞=-gU~m?X#M%#yvvi} tV&{ ..gUAW~Ox>ԯe9YE5*8FkVVi\a+| K_!8'lȨȃ#R9sŢ"ziH8]Füc<3_Hi^LI~mOťiRr_48N|-U n;8YM4轿u/d,bե㘙 md, %ʹȨ}=S3!-̓{|=J4mSGwI߲p$6i|5yW P$}?`a8 ͇QWs|˽c; 5h{݋1%tʽٔHՑ=|'__ o=x%=ڈKJf|4DcAM ᆉu 1Q^TBعY$rQA!8; 4ջuS Z>6qpgh\,c/CmҗĻ, b&aR#iyc>T^,EcUd200:؆3%Bq&9-s u~)ݾyLLH|e-ǒ}qgE Lfǵ<(Qp|0]2JU|b$u+dA{gca|<į~1֊(ec*`uF(BQ8\3L0|ɲyxɽaľ\R;vW+EᤱyI bƖnaK B!B|`*K+|рaٸi*"bp !B!gE*k(B ^a(&BYXW Ж\"B!B!pez ;:! 7 caC&ځ( + !4ٲe ###"9/!!*W|qmmBvx 6*+'0m(Em) !̱eRiӦ"ȷ~znJ*U\By=U*fb N8,"[>\2XA`i60€2/ |!\o>Znֺ"נA>/׭g?nOMTHx\,0 /VMB!o\\<cS* !̑!!@'z/׭gB2C^%c#LMz8r\vpA2*L%B34NECjv -k2E%qOP[ IDATVsK10]u`!'XLe`k_cG#ڣ.B! Zki(붼cؿ?BO4٭?rQdլV''m}0h@7nիyILLdȑ?s8b\55r$y v ,\mP`xMHap1/B+4$|A~6kg&h[ "۹d}2#z6rTj0EU&pk8g%1|#+K$鉯@ժ)~.N3=u{zCNN'OccZ-~)}g&j "#q˴iӎVO7F7BɘbDŕugdE_μ3 Y /B(*]xmQưvsrc9{,ӫ1TP\i !BMt8b =+Z\rpa=忱=:nZ>6aܶ2}B[ lw5jǜh`-87%n0KT;ў6cXkJ Dau22QJQ%2/Mʕصsp{cG'=}bhwL;82˕/˜SPvtE/;kbDx5>eBWB!9{撩5ϙ9;SJ_=F)Kl܇W!YwZWٝPҠ+f4kv O8٬Ոr0Ng>bDxܾLW\r=eb1фVAjOEϓ~&jA֭H  Fr$%%{w@];3f G|>7WC߳z1ә5|Zc3W$)& 4y bѨ4SD/Am +m\ޜ1Ĕ(K64Mo0O3'tM.9{;, l uL,Di/>Ub6GU K{4Y{sy,!2#C!8g@8鋇'{t@,j6)ZAle{NΫz4V?Y(uc]ː`[>*g|\XsO,[Iր^U-7lٝ&[y G5wdi</4>,ǻ; RiS^g _{5soMq4)8<`3RJ*C 9U5 K?'cԴ1Ԍ%dis|ny5 iK0|(Y7@4ԧ:)fxp 2puGA)/b0F؇鄋:B!8Mp4浕c]23NF7Rt>a=%;7 ȧ~G(a\ɿkFi{؟nuW6تoT_>|pVs<<]VeK1ZϸvNeS\_Ry<殿F{(L;0;CUxxq)NpCV읇͙nh@D#zun[ϯ+ϻVчWz@E&Z` D“FEVV1c wcֻNw4Gh[.xq~^G>U$[yׂbS:kh '5n;%$[gO=홼| W&&:>=l#Mi" b(vb7jآQQb$vw= ;*6D;3s?ݝ;3["<ٙśs lUUKMfٿoyj$_b APSWo}M}PeAJSS. TS#b#DBzk̘#F皈m7S^_ܗkc>Q Y%7.?{ƈùo# sO{^.<3y۸tڕ]cK$7ogE5q!BXsu1k:TR9X'}mYsJj`u'ޞ:CƟ!(Fz8{u bGϟ>`Iϭҡy;d.~=̐=g\v3,pw?Nt3;6ԇ/eNyR}R">hnps>7@/N.ѢUݗojq_yXwOӳƳs~x_?M-iv{';ҵ f9GPJaSg}O.X`ǏoWuΎ{z~J |s;yWQ= ~,]7;<7XExqnk^8vo ~WUEZIy3O8сZ;.K7B rȄj :iB!V(O޿^]*է\M5WInCizۚn~}pܑ;Q^`_nnn1ʡ#Yz<=pWp Gi?}g5衚?.󜧯|\*]/˼sޓˆ~h4itsIR|RYYYޣ/r1.:o~{h( 痥l2<~=DiOՃئoat=Jsq}re$9cU[)O6 |L5XIfAD2d#B(hW0k=V6wk"BWߘ#v8yYGJ~cv9.zJ Fې;~ŋq_l0Xuq5c8|TF2=^z&Ď>S9U廣yx7Ԝy?7Ib㇓yh0Ǎ[?> *HMañ xg<1wtvv؝.y2M،+ֽ-k7[8犑L\G̎k3z N un e:ϦNoGM 2ck}aq3fW s[vpNQ,ővUgW% +v)'dp.Q@=3.Wۜ+a 7k!h?|柙4irk,2dg1+3'Yr_};lxE\ysdT5=d=d)7?'}9U3pmXgo|@/ⲣw=[:UhΙt W73jV_ g7R=p۰ջP,4tZ1NaBIAc|)cԎxg,Zq1CB!DݣݧvK=pry;[=?Ύ;sn9QEs !bj>QܴPN_<: {l|`ذaK8ŏbYrҩSfK[޷ֶ=~VJam Shڠū"G) 28tdpB!~l|'̙3gNѺ.]ЩS'6}i6jloa3heI0 Ciu rQ@ !GR/ 2dL|V[C']MۛX642C=##*lJ)"qB!ZU'N}Z+Baa\~ؑZ<]6#SRYSIMUTbMY)2>ą,*/B!ĊVz°`7޷B!~l Ћ{u=y&o"Jcq6 T`0UcU@k|(rR!ǖ1tyM !Q(Ƞ~h#vB;MҢRiscdD'B hG(B sPIL#mB!Dhh/|=c-3&9Mc10Mc6|!=innB!hk4^~lT2_,:CQ1ġk1i" 'B!ďTk !TC ~}+  B+tPC 5֧.b4I|/B ʼnB|7K/BOMh~aV?s I+0DT[|pq cV4F{BQƠPX#_ B);~q}Q*B!˜|!21*ȣ5xɺ+ m-67+"rBad\!(TOM}֋ V%_xvA2G;RyBd)~n[57LZ!w!-(Rl`!6k<Qgf"laS{ B_s[;ڛG2Ї཰ǿB!~JGC zA{X- b m zjG]Hi48RXmӤ:d-gD!Dr}-I|i=N?2k4!X5%[KU>q{RWΓҋ!e *Ϝ:GdClk|qأQ@ !Cn}4,5jύ,߰.QY_!XMK ]M Zg$Z C6-WGkOHX02Za,+q | !I˭MayyP}akC^`߿{~_~/⧬dn!WM奺7^)EA{UkVzC5 iC]ψB!@sK7M-Dx}3_|̆yK'}!憪+7to*m [koÒRyu brRj,΃wh@kE7$B!D{RԊ|^Ɲ;'G, B!*TR}CI5)o>*[_Ce*08lZ{1VywB!Dٗ*o_7uowI›ɄzqB!DT`?/o Kto9_Vy@AYW n©Eu1A.MYE+:WXs B蒟XӴ>/ S%w'eBUQ >'%غ1z}_:)MVkr(C.rPyf!B,͵jq=D[*'*"BrTy ˒|-oL\ BQ-uڑqrŚRH+x^A.Bx!|sA> 7[ !AK] ;Q.+wJb#ѥ><HB>dr_}h^2`_!Ī{(hJp_.vch[?Žq16^c# 5 x-!KSR}@dHāYK%!BY`_Kdoܭrx &9Mhy仁BUYnrnRN;TjCJVxDQ#9RZ:OkcB!D;R_ܺt}^!icj_( O:p@N krXO!BF5גܮxН*اN !K1ͷ7Jc &0:ҤF"Cs01 !b9i)~v |QIq_tB!f5E]EZ (@YO*{l(`˝{!}kkk~r&'Bֵr# }1΀R*'8B50ӾB!\>U70(=)bO-\# XaL6V*@j'Jg=!B!=p( ys@99O*B!B!D{S* rT-âXcRh+M*~B!B!y Od)׎86HyEE8_!B!h4;V&q<6r֑5#nE_!B!"5W( 6P+l*pYM{ e B!B>(>Fk>&vF3\9lPqE[B!B!@vxywؠrW?uˡB!h+{bqAkȄQΣOe1^3?+B!)XIuJzэa bmfyΗw1g]M!bYEjV` rD!Sɥ6ʁ@P[B!D{PQfƱŮxW9t'w\PrUu5'Bb4Z[LHcH36 㳊0(^Beefw:$V^q Pݱ^WCE]kMGs`Z ǰSӹ\k;iXUy=-IB,fǡj{vdrr*pQC^ӎP>PBUWˍgOק&p:m4hEWA!D;'M!te5@zcPg q/;mݴq9b~$>y6c66Qvǥqթ'.)rxϵDk!;&OTTg`6a==c_FmD#|KRh!ĪE(F;7-Xvǖ8t9Bq$ Rcb]w+Ce/>&_d')=U|JPߊzo{_Iۍ n0,cAeoL~3qs_{/NIZN\eެ0f7#ƞ>ĴOgP0üY J=uדI=8}K? fMI/}(?_u)ZkEe3)}-ש-gqo\1k0}q FێL=uKx=%*W߉6(ڶna)o~Δ7?/|>~gsQFk6a=j:W%^B2K`=(b4&pOeGGeMŖtaF rGT!Zb_}EƲa bϣ/!gM5.n͵-Ĵ{.86_ۊZ Nب3aⶉ(4+ c.;D6~͇`f&ZqaW1T&њ:kZ QyG\ضcQ^P2ן|uj/?O"Quz[|ȯ`̎67NfѼDF4iY x%ʶؠ|y#}:c%+(l-D࢈lf̹s:CzAyp@N !D|wɷ&9}oz(Q}6{?g?ls￙ˏ$3wvQWrUwdnɤfOJYܧ|ɻ/$[f/|ʧl`]hY׿;^,zDW# aH}l>zmju*Gak͆9_5W+ \r_?e3BQ aڴo9}u^Jw`nfʚ 6iDْBiLl T8C,B131Vh|q8C̰B^Z&g/cצn[=/} =ez$ZfCY{ ^oMBn5t&,l`0Vc)<{ZD>ܒ[O7ks[_;m?"?5IbbCaB ZI) 6Qc{F !V>5n õg[`$ZA+}W=T/g|L.1UEM}UU r[9e6v_[T9FKG bu!>|%:FS0f/mƷ+3vE2\_d"ٯ;l=weR!XĤBk!(MYTHW*)lZ+R"p&)S!h1w#=qz{ߴe%4W&ꊥGLm-[YMm &2|YAxMϟhRdr,9צ᫟R`r_%%A}1裶ȴbc?9oe{_3p1UW,ٺO2B:( .dCPL Gڸu)x"P˿+BT R{\vu%LR0p1K>X-^dq!X%r9ßN"ɛj9ʉK|}Qn:u7k`ى^/qzZQ-ѱZSW$b6s쇉dz/:+ŘO,{ۋkIՖ^[L{2,S !Dl!N+l&t( b ]R,ژȓAz x !*j7.ϝ5uM" &;-x܊tA~~'+'o%JW(z8KZMy;y wH#|.} !D{4p58}ewccҨoIw&~_{%:_~fޚEe9g'/׺]TIALyor9X1ϫd؃k`]F'|Η|WS゙UVn0>{ϒXٮ Z]ԏ;,qdR8BL6ƫEL. "bڢSile*&G8VK}!h pG&Ƒ?yK<sţn8hy[aTYۯ76D//2OX87k]6(8|,Ss-Uݚ[_0kDYaXsX_n|<&yo+(˳M6Y~Ɖoi[ "r&: IDAT=~IlwwH/۟mF!^UEY\1T;K6RdccVEV{mBڴmٴ` Kٰ(Qf?M٣&;Wԋ7N^z9#&Y[S&ZpsG/jmܛ84ǯX"6oRJdS'˴iqv}gj<e;8-wo3sBI[1JqޡJ*|ڐQĕ !DkF_=.Qvѱ70’;u&ןyWlGutec6m{i{eꮗ:_sq)A֊.;c[D:ts(?{!Ob3{,\ٺ\츋*쯔5[I=:jXpsϖo>bɽ|MSc0nύ|iOI4k-w߈Ωzĺꎕ-lq/V9W46Mmؔ[M̌P :l*bMB&֞ =Wx<{H+aG!VZ.>$uZWN_h8\(c'l@)WΡMǗ}C=ƜtD.?ji''?|3^~V_~ w\ kcٺ[͙󏼦1A~Ck/j[XX~3L\ң>fQ\y=u罗kHweo<}C=bxQXcx:TS;:O):FG9T,]9;rKNHk7%kNCVkjeb [͍gÐQkѶ#ܽ#:]~{v5mc[ِ&wQctb烷b烷jw^WeZx9K8銉lJ)Fˆ1CZ=7}i]iG_OGOe=veapΡWrSgPٻ0zoUI% ,r/ WPT]p!("* \E6Ű&@}NUhd@Ozy2KTS/F2r/^j9i LJfa 3O^r =ݶb75ֿoYan"yr  O(0z*perh)j<Yu9Ɵ~dX}uLJ_ klËUe߻vP=3es:7\:EŖTO/u~ɂdȄ9=|Mb뇞˗:)~OVe߻OWՠwLILsAQ |bx'n;ğS.]W/rS.%|c5{\nED}{R0@B غO䌑z#9Vt>VΏ:]xGsLJ;^Xg`Z+;n׭ Q*fLɭWu_Maulflڌ#WZY1{\O=M?;߶c6b]7e_NJcG2jB-;f1)}v] ][@ y4ǔGqߟCw|Ozhj1{m7dn3Yq= (x{}fg^fs63sEf^I168j;椓O}/ڰnx5o8sXIU ϘcLi{{""}z#wuy\oڋQN&"Z_k@hx=Ut ey1)^>LDDDDd:w n EDHPF,Í?A.P+a` [+,7u~Wv0U/Uh!EH)*˷sYƮ9~I^X̣>T""C *XDN@)UBp)c9\F·2j2,Mߐ/Ƭ:zඞ9}{/:JDdh+-cof$%B4EQN&) h4~pI䉈+fkob^f7;l4crΜ?1J)"2Es4j59Zܟ(̃yqaaFHhWfVCǽg9s},*2 |9R6rJ8W9JEpxK&T`H/""""ٽ|܋,NvF*<-K F&TK}~&-;_DDDDs3Ǟaű#5 fϘIrwrOoeΌy("\HJI9^Wd]!#d2A 9""Ci8>q^c,pmNY*aMX(#9 /EkEDDDDDD O$hFJe ej.AeN@DDDDDDDd*ʌO A>;fVDBo cTћ55g8293nD#F fUAYY󋈈Pf)y,8\=D?9B~`. r Y| 2M2CeZfDR&ytzڗԧ)#P@QPdhV #LH)'EDDDDDDHM )']"sc}J_DDDDDDD:we G2.-!cE'9RhbT|2f2-tEDDDDDD:1C0R2R U |&e#9H>T苈 OX6P:znCA.SPPaԼ riK8p92TjP ԡr(2 o8q$BU}j_/"""""""7"A͠׌*#G`h"ÈA| 53-)e"FLl@q*Ȗi iP}?&ʜIGQ7HV"yGPPy#I O8opxx3yB-)e,C"SV9u:#ف3Ȑ[u!~[kչnu_kϽwWTN'\?BvzVK6]>={km2Nv^y--=ugϽx߲J VdP8F7 hdhDXH2+O(34 "+㺬ED\ۙpD>uA/SĄKL^+}B.4y߆ɇ^&e|~|s\&e->j/LeRֿ{YmŕSO˩sHdEdRxpԻ(%?֕O3n9_f?ōo^q4m_wn?>;ߧ_u- 9PF8mu]cXeXҔgpb?ŃwO⫿ +? 3}~#w0̾y{1uTm>9v/wԞ_+ {;ILYl.N/vާg_s?7p{=~9=񽬽Kܮ}l;mc?;m޾<3e%Ȣ-{`Og^64y `XPE%J|r7u_8_`y|`rcf.j,V7\Gr=|َr!8cc➿8O5!۝83{8#].$<)@#rf*E\;j0OHH4e󋈼L,9s{g^Dl^lFwҥL:VɯϾiOge_+̄'odƲm̦lU\yYeN9̝CO]|3+صVuoZ5Oq9=s5}}7/Ęx{Ȱ{ẟ6)i×inyý4?Zz' =536qc.;Z6߱=>6];본~+sܙSgr>Ov;xoտ_jis6pfr;_\.I[ʻ勵w[ǘFs_<7i?E_|_,i[}3fkK8uP~0/o X.=`[z./|f6_;lWWDD'1z"~hDa |YYt 2co7pVzV_(nʣXmKZ?e .pwˬ7uXg5w0k5V>g}-?ǁ;ʫ[ϩ26|qk#/slV4Kܮ~V\e$7 F;n3ONɇ.m}/'sWc?n/}t^(ܙ=̛;m㳴^jIdV{a5yq=m{Xcq|x̢K-{nħ?VY}צ?oӋc?cwӓYd=_f1m: ȅђkϜ>qlF oy&'>&[o;mMX&L{_y [[)߽D~~_tKK/+}fi׏'4`W_\{:4\mxO`յWm׏5qdvw[vw[-KPEai߲[n-vژwڄ;L3^0f̘6]|3_/݇/gYeXc3OstlMx>pnoq=B ->0[E6r>~0m88~y8WJ?Xg5^ED):ԽA=OU9o+uK"> EdăS9KҸQ4|wҪJΙ';>#Gu+sбlU*Iz7\ L8 6_{A;m{ v{ZQ+w>gfa*#YmU _Ļە-߹pىZ IDAT`UFYa` Ҷɂyýa t -0lX}ݱ}ˤ>mogkι~ gԘnu&3 96o;6j=|VyPV-~oV]{en|&?T]ۖZPxv?`oB ->2y|{5UG޵г{9gOn?>GwpWJ?i9gں~K٠?C8//DD*=E^iD&SA 3=-[ oֲ YD5uoȏ9e >)<`{!3?w!G~\YLyq|ap;?Y7DIr':/稳^N>8'Gpg~z߷,>gnu/Z|#ïLos!Ilqm8W^j7_ܒK=xc 3y=レ)/+OUA7Y}E=0V^}4s綉|.uĢăSǦo^^7\NڗoMŷ`3=s| <|/ͷ$}pq7coԏq}dmYYr~3>eœ=w>{BjދQ+SO G}`8fO ,ؿϿWr.:C}s{>83cY|> eآ8ȥk HXW%)bۜ@Z_bDfYߏV _F?QUEDDDDDDhFQgШ #2#FAقVEDDDDDD**KdI2@3 S"hUɤ!iPp9Brt9ΨP9Oht'b̛e)"""""""CA`=шZ Fa0̜^ÙQO}󋈈_f*2F}Iy"FL12rEEi<!!$7(ʎl`Зe !ZFȞȐ322<<)90.Ќ2e**OEDDDDDDh%,rE yHĘ! o}Qs$諸QE#Ō38l;12EvrN 3#x Bs]9F,;**6y"""""""CAgFlPBV49  =5\"Lc# LEDDDDDDE#VF̆w 2VhFghD""""""""CϘdx~<f8Pٗ D=Mui}!A Fx~=eRr)eBj2<侈 )pّq` s{)ZN/"""""""dp~leB+CA1Q '""""""24f 9,y˄hDҨڧEDDDDDDB(#2 If8g.u{#GGL*v:(`>CNHe]"VLgEDDDDDDV9rq `PLL`p$ʖNወ r d\2h A3ÂçDt&ODDDDDDd(}PLQxg!ʇzx TASEDDDDDDWe.S@h_b9]9A4 gĬ3"""""""CA-zRI j}=~b6KF\%ZMr M#UVV4z1;ALhBEDDDDDD".BXÑdARxgF-C & EDDDDDDPeeU kOϙP&hfcvpb3/"""""""@ʙ3`Խ ) ;e ̌*Jݨ$˝/"""""""@e%,gȘ)[F {DH%4GyEDDDDDD ϤpS`d3A˷͖.0A &#F"""""""t#%מOΙ!E029BQ22h3"""""""CA4rp$l`]%OጚsGC-E"""""""z19r~3@e.b|J䉈 0\6BNUtT8\ D(+)DΑTFrEDDDDDD joDvPsAkAW=AKF'""""""2$2e!:70s@ Z*ꆙaɨ3"""""""CDeIԺ 0zfD]pB-#Et~\a$i$pkOoPՠ?B2VːȐsJ  ig70˴#PRvd*;_DDDDDDDH`4h$b4M#hAIQ쉈 a)́yr2Z}#O+c&a8 RRt~y WP=#bٝ$""oȑlXs (o0oV6ߊ39*9sf؈ʞ0+b`F }K0Oړ8j-?oΘ1c:MDD?ӹ;93;[Vh"aAp91f.VQN%!BvOH'Q+ gFN sbX#}1-C99 Ecޝ!"""Ka⑧'v:t*#++}n˄Q43u .+py͂nSMw2g7n\cRX!"PO])Ш`^G5/a1㛉0vU>AL$;]Yfz{{;ADDD҈# $"1-5 s,Z[[猪ʴZFU9 "gF q4$FD jkӵ[~X"""""˭TFJ2QvL#(JRȐ|f4H;0l(ƍǏ^589Қ49W_} """""˝f0$k%sTF Gli/eƏAw2rO0a!s&͙I3Ӟď\:ѵP͜ά_ϔϽQƈ骈,WZu@ưl.1{rtd2VOjgW8)_DTӦ7{mY;5i>rso;o"|eϩzm3+7c>HkD|x5Yp>'  (p ]Esȅ:diVHꙮLU4H:_D8o6ϜyV>=Ww =wUt>+~`ef^}IrU>M\0_xkXW=eEM0ܨjГl 2d Ov1|ۭL9+ҽNވ{9}˜q -L=飤yY_=̽װ6"""""˧ jL *GiTdbQ*p>k/)f{:_D:ΛHsg3zOzj2|āiqt:̹槔S'sFv'o[M{g<+j/"Y4-Ѫ2Vk@s$:wEjE^9 DErf/f<}/ws0ᇏ`Ի?_)Vk,k~Fmzto=kQ#88Ù5kVr,xGztZ*HoF*!IVO{ذtq[zZ&w}8*˿䑌QKOY`cVx{{ۼ?Q(6+1cVFj.kTe. _g}b-ys x n+~ݳ>ɓ'`f4 ƍǛ&j/o;8`Z~nf>fΜI1c7mf_f{#3dԨQ$"ˡej9`1S!C-DBY:H$|[M/"wM n7f_q~[ybL<-008|&{5'}37^ΨwDXuM;]o9ozwR&Mbr!^kh𶷽mtMs=9?W_<>!{V^*Yz{{9쳉1.S%'N+䩧}kEDor Gy$&M _DZjBȞkoWD2Oh.L2lTΈ$4O{mti'5y+bXiۑ zij fׅ_o;wKs„ ll喌=aÆ+N;;[_}os0uW\^VcѬ⊌?va<#z뭯15\üy8r-7nǏgvcg̝;5#"˯QFqg: 5]_D tL-&jT4,]/7 GhF|EJ@șN6O̽>&M\p \j_}?8};0XF y4^93yRe6lSN*BXE\uU رcc=Xgu6mW]uSL!Ī;NƏgᆪ5{3sIJ "EAPVT^P+(X.*"\QQQADE(" H @ 5甙y? $t|✷gʞݠ5o}+]wÆ ?+WK/b-xѣcΏc>j/~wI'򗿜=nK.;ڪN/s|-<̙3g?Q>dz;?ۏ,9cx{Ô)S9}؆ܝ̝;;Rpw~1hР:u*SN]Xww7_~9<F1c׼z޻EWW?Oproc/sUW1o޼MsL6tSfΜƱn>0rH^W774i-lnNV+y衇xvdYp!f qtR89vyg~<'#,DA="lx TqE3usJZ[,e3<9D|Wi٢yZw}T7ۚ=nƞS+y4M{?Mz E-䉲.. Q֭ڊ:oӧsuQTaxk_ˈ#XhsG}4C `=[nnc#\㹻;7x#K.eԨQ&Mbw`…|ccȑ|ki{]v ,?ɓKVoY8 @oo/sC٠OGGk'FAV{k7xq|;HYVIzj7d}`޼y̚5#8aÆ{s7r3~ k:裹7ٳgs1~JDod`"D(K(P 4UhM#76kXGo5i-&`6#uY,6rH7j*Oε^˙g'?I.\'ֽn)Gֵ^i6[EZ_|5i3g3#ƸmنUVh":N\r%4Mf͚xsQ\ʆ;3C9#F ,]]],_'׻__5?G?'"""lJ3 @ieBkqq=OV}: ^gQ; N.ҪuϏ#ƴF [w9kL0SO=~c=vf9ss=9CV̟?SN9ek+ OO~`; IDAT7g֬Y[SV7n=:?}ĉ !Qc{'gfv7 m]@2j(3g;cAZ]yO~+_DSYlYYfRb~e˘1cfm+Xp!/梋._z?ɓ'2gΜ5ӧOgO{Ze…tww?FҥKYt)>(8s:u*dvmd 6(s=r-2˫^*6dN?tnfΝc=7̷-r;mݖ7XFu]NJ+3ȿ75E]#F#1J5 b FaDi@ȿ]/3Q=uMߌRYJuv{3ո筢(ns/"^"H#C:` gȠD9H9R fҟ~sėAk\Rcҿ2gŌy-ݾ4lGw"4I]73wc"""F~:gu"4$o Ds" # UƠ(zJ!e)g eXzyȑ=?Ӑkᆞ_s˼k|6>caÌxnu0ZM6cO› yFs勈HK"2F,M rh8E0HHHj0c'sլ*v})|;ACbh-7g^q/u;TngCa,qtlB ꌁS{${* x4-jLZR)!x!"q0~,YqEt"Ɵx> C*aC;YΨoґ&#'.FtN;v&t3=Gj"""""2'S֡́=*;=85hE["]"R|[sqdG0'Qot2foFPM"0c$A9,4j[NfOXtR*&G! LZ4̠x^F&r1a$"""""kp2I ,n@0'(N,3#d1\j[& -YHWϣx>8lQcߒa{SªvUiBbXlPON#CÌE#5 [k>Ӊ#0oc5^DDDDj'n-Bt7L0#Āa4Z"'C1DDDXr%Æ kw iPB5CS˙"!xP@5j5EWc#8CDDD6Rww7z*;ˡ$85aPM3 .2"Py>YH)v}{_Fxͮ;βGzED H!QNw-N6BN2;u1S۝_Dc6c,tA,[qDDDi,XW۩Μ8"fٍ du6cepzcYZZ4i4NV^y':ãs1ydN>d,Yh"""̛7_l6,cJs?V4MD1AlメXeu 4+^D1[׸mʿp̾+V;ȿ!Cl9~k^,>vV n4=Pa:NF58`pG"o0p"v')0F6I"FPXx|1Rڝ_DDDDDDDfwܛQB(Z94(`i֡'RLm/"""""""Cch!Rm= )c9/"""""""5w e2̜XE(: C t8Fr̝J`dBAAalMW3s::fvf07AQ@D3nD72S b㋈@=@ΉP 9뤺̩dpgti}wB2;QP8E"BNQ鋈=R,p:jj Rd+CrG쉈 NiJ(Jv*)ۄ"`V eH9"0CG 3>| NXvwW/,.ý緜2o_59s+6w>o/#e6$ɗͥ~Sۿh|_˪=ċ PU򺧫} }皕1u~!|k=w[p³=EDDDD6F#eΪ`tGݕ̪"2df ѱx?gt<͇x2s,\gCG}Hٍ|g;qzϻ;9éwże#ۗѯnxFg?&[W|lQ~w|GNЬ7y^kΜ(>{xKaC8;{!?E}ǣˑ{{5H;;rDB |O|*[NȠa{sg0qMuVuVO,]wN$o̸}6_'yYK-&Oy]c~}w`˾Sr_zw>9_ȴ~ᣇrNgwZ g#WngWXg,Yeh8eʄiH ʺ|Y]ہCz=3;]Ch [ů݅}>K,(9w]wџt\#cQY2=g{[JE_żCsryg^CG !cE-su{lNOW~þr>nv~v{ 8u뮫(F%@%@08!9dD S"{sY/ި|?-l#۠gTjFy˸spor,Ml&mpOgvW9ɺݮqI]`=y7t >C)OI!u{vw~Sގ/; =i~3zGwl 192EiTF,!SBB"%hFYBVlF_q*n9N{sg/+o'&oJ݁:zϯ^̔ݷ&W7o7k/y=41nݼʨMUOQ7?=eoރ3n;-E%2|Pm+DcfnʰC?9i&+z#;q?r_|t`h}7p/>uҟf]%.N!n^ypk1Cz_,ܠ =^s ˭-;x2w\?;o+}|{ǒ˙v\zo78鋙ְ| L P(N!B)kYp҇K|/N>,>r;8U Wps{3}Ǿܖ%#^:gpo*Y{~Wxhct?F3c̄7W?k.;Zʩkuolr4My)|™}s=_vg7@>o.{A~|%|Sۻ8q?>׆|֧Y^gFem4E-e@kW-wSzv?'lpV @=,1B2!):s9CYr>V{W/;/\ɭ2`TjZ&Fƅ3O#njns:YʵppQ +8k^!B!]Dנ(]lZU \e!AqP6B!BXm/ю jћZ\a1u,֑ !B!A*<,X` $vlt YE_!B!ҰhWHk,!rs,LM|< 䧯A>)BI4؀q]Y"Fuxka2E_,D!N & %1)HkΡۘ4w}Ӧ-ߛʻ?uY^v4q^yMk5;#0{L,ϐ&LNsCaz=m^<'P4:fɷcRΜ L._H1صm g叁wg nmi\uN(5G !Bxi XXZkՠ(oqq}B9(Ɠ[\wӅ=;o_p'_k_¯~=!T?.KDݍۻ45?7y\tcu~ /r)Ԁ_zMjatB!"C)v,kPE946*H.\CcsLoJ,%7|apw \{;WKOa[b: #2;uFFߏ0ipہ 0.Կw=}, D7>med[[2lЙ=״vz_lCNL2+Һqxr-6}p@jJN6py lEB=3*2<}\.ɝ#;?x7;r*Ͻ߼m3fO ko_+}ȹ_Aso]/ZipY71|#7ʵ*0.|~$LUKߟOv׭mcsn<1B!_`4&ѸX\Ao-:"1AP󂁼_gUϨ:l,qV;Ϯڑ\>1㮔P2K#oOOSd2m@m#n?Ly?;!V*ŃEN̚=҅juNw~3S}Udf*תl UYg3Rz &+n\ŔqjbSOBm4w݅;S1,i6j7Nطkibe,P[~$*D.)P0/&1֜q毜u`즵Yt=g7=x^0헸Usw]eJW(As P*㌭۰sZ};|jZGt#VsZH7:Rd2Afu2|"B*`4 'QPPF!f=N!5Ͱ{e^M:=YE_d@Dvlٝm"x+_ >a]&sn"abM\qDž$(֊; {lߴnz;3ʵ*pօ5}oI8-G#yv.ouAz.ǙKH׿|*<%e_ f,!-%clڭB{y6έfD ژskֱۖ9Ʋx25)? 3g|~$=0mb`J)5ġ_O/T4juNe1Us۶4l Gߥ4d%ݙ)}#ٻ3SϦx"T*=MvK\LV-YNJ0qx'bLN*ֹM]X-|9.o?Ii^p:?ќ*+P ~?!1&%䟓ab¯9,_]n䙖/uB!AJ9(X0CiG+Xv `@Y> g!BD]Pj3`߲Ls9UXӪlpD."wS2Q;|0s\q/+ӻsa i2,^g_ os1K{-k{^jR+׀hj>sgi|:>6=[ôٿ7-F@9塜,1ʏ'Pj8L-붣1dn;)?eO*/XY֤P$~i)!,H5״-N?.~5o]\v[c~_rKEҔ<?z֯R]?C?'`ќߩפ^z&]B!'#QG8Zc37SH}K sqdx/rJ $Di؀gT17$8xJ8x71c%){.M;3sCbƺ~f \*T/ˆ?7<>7ew϶~%L{w.}1jd^KdԼ>,"wnVFWvF63!&rnXhqQͳ`^P/>Es~ 1ݴf?VunČ5 鏄"Ҝ~N?`2i)ѵ%8zeGMa-Y:2#Bq2-xZ9NZ^ K^̰1H(B^U],V[:Gh L̩%)sjלM>-Yß>O f,̆5x2_{嫖I_:Gbm,i57,!\8i-ס5gsyEK%,#V8kUo㹻cn{E3k!BTx>>)ZppCxOB^'r{^l֋)U`a+x+yle-kZ+Gq уĤ Vo!5y %Q)Ue lZz}ZRY/+7o beկx[)f=7/fٹ+㖇yf{%0.^K;픟+vv^{l*z>$} -'w-ݱ2y>ZGs.Q=mw0*U,M;R\r*׮W푘<|F~kWLm$,_{e&Rg-u5"( hBv n0Ȟ^ߛG${)Y~\!B!DlN"$@ *7IA(M$p ZA8iy]qR>z1N/[_+ߙWDY;:!B 4_}iDM@iF4d/roq:|M!B!B *(q**v z[Z贬_%B!B+Yo}AA@XbϺD.: NHu5yB!B!D Vu||‘R-v2;B!B!D~`G〧QQ4PАMt~bǠX !B!RFG4*`A+ pIS8S;g1^6B!B!V?q`( xVau}ߵXe u B!BADYT* qPиFk\F9JB!B!D>@Bh (B7h(e B!B.p08xVc&5#hl|kQ`| !B!W  ֚4 h@U,~DE!B!"{ IDATYOa:HAֳpITp u6 /B!B!')ѐttJuQa@yhq,h "E[cB!B!@MPkP6(< !7p|k,WJqGB!B!D>E8 ;\hg\ `Wc _ B!B!D~@J)Wh h~ZbPQ>(C$k B!B|kAQx(܀oz(ǀjpB!B8& JaB!B!c ƵiFUB[`={F !B!NvR ((Ecqq@[| /B!BڢъRxօ0`AiPZ|kP Z0y8i*_gVDk1N(5 /`$/DQJaeشjkG.B!'xhbЮcmyw@9x8r_oN(_ Hœ{)Q"% qV([5QZYS0@^.B!'I(GcųQAJU> W3"67\4(Q(Ǟͥ:5;hNbHٓW !B!Iw-mQro*kp ]XWay8YyۿF3+RAuu B!(;4)"41.Ǡn,.J{`܏V 2I_{̵^W~_+kv&/=<:[X X"j«_d- &PDa)iJ>{cuu۩PlzRxTyJ^TA!B!NSWVB+p :l t }Y;S>Ԯ_ENtB!BqR1֢Xo LhU>ւ)V_w\^x4?xy7ذr ^~Vj\1<|sGTvۣo8\cSL۟׾=};>>x(7+[7կe|X&ƀI9a4S^;LδodHZqy|X.C!>o-t{Q%!R J#E`ֲ=i h;ud;|g.uv]fZwiNGÈeiG^bye3NEkHL rg֜V2/vw~mz;#"XSr}HM qi'5Obx@Sn 0%. { vn ~]B9Dz[+9?DitU=^P߯N:kD]ǩB<|cBpZ8D߄*b VѕQ؈†d!}>?1>37}!M %$/HfYۆ#.s-)VwӅo_pk~]nX"ܺ;UsjyXX:p=챏m={oRwlŦU[OX \ϩtm{奋nl˷I߶} N:kD]ǟ>61iB!|D_Go{ZU([Xڂ8zqRٲn;\s?Wgyf.}&=jp41FN0?`[ uT;&'F2dZw4> AweuxgLe?pSfʡz}\RV}܅׏䳿^Pjf6b~L6Ik.V0|} MoOϷ:庮,$=m͘wS6J L& 3prgKȶe>03{Pi kvk#}܅AѰW~!-{O7SߏGZXgr{3~gWU!Ӻ3eh.Of8h>$S6:+3zeD ۊ)org/`4^sNmXH4Ƣ o} _)nk̔ͣ)sjoz}g>=@BΫSbR{sgO2u&,y_e~Y]:ɱ|׭mc<O~\ !8>`|χD[ BV%gE.cYF;.#KwHpYl#PʨX*cjGrB[)n ߛǠRB \?Vo;qe:6-)fqs?`2tʵ*,/۰sZ};|jZ,cɩ2K#oOOSd2mc{{̔q_ssǙr!tݴ6즵ҷkZ3=~~Yזm6 E填pNxJॽhQ&~tZSw#2ׇvl7O@Fy=~]?)VjʸY\tc &oپi?Z.5pKxzC?s|'g_T;f3#/YMjrIo;ߋ[w_B;?!1)!x/k-7?!Sӿ9TV^gVL5pZ^m\=ܟ2Dё%w7 !'g!9>T kUq{QhmqpIE;o瑗]ø.۽?^'|@x9OnOB#@Ny2,?`W+CfX ܺH㳱X|Wq,S)G]}#ٻ3SϦx"T*SXe%(֊; {lߴnz;t!?\Buw~RkRC^&QΩ̟jeeL?Ur uaMFxvNшil^[]~ܜYjORԒz=߯`ßX\ c>ܑKVyۯjկFS1cώ}l^7Mt8<(Co.|=kmJs쮑L^¯~e߮|:+6̅ϋ+ޗG*sMxlȽ.W\.Mn"_s&uf<Kx@:gIףmtΉyܱNdj׷i赔*_<Щ,_nc;]o;zJq!u *q\X4Zܰo1VcC輎_$)BH(&=زn;ڍJOs]Нotdج<{+l\%eޱRǢ۟i27}ل/dkՒu. |~ZK$䑘pսtn9UjW @wX3)?a/x.Zf-e,qe|GVI#QtW+CRDy; &פ[oOXĺj?W+ Þ5ްr3T)?ޝ)۵?ö#R*pGz3~UY&W6goJ qU|9J/NgMnNN$+]#Y1CMkR|ݳc/<:}?|_.r_k1ɷ(V*FמC.җݹ.άĪsn9ѭMPD%,7׊>wa_~\-&:s.͂KXկFirBq N@X^3h hчC*:O'~AfF dsUަU[ٳcuμ~ʰ7Uy ӂLy'أ))|6v϶~jgG\ֈ!Y^ޝ7w_4v%#*Z Vrօ5)T$FZJ56RA 5iӏ9SÙ7 *"qYQ~1H#Uː/D %H,@ZJ#s>5+~^ozSj=ĪsNjs_BmQ^g':O{a S~\m߷~N&83y욬_Bq|EBcq\KxU+k*"b#e~^x` c,c{OV/ǽ}}ôwfyzb w}ezFEo2ϩBbRLNqY%O)ߛw1ulz9מy]mǺ f.593X4w[MkQimO!z|OdǢ]rӯ.V*q[GF+~YˊpI\Ң!_5'MGEnUrKuqտBy Z;x``cӁA>oFeO-:?^oZ~I9xMa-Y:2r= @!ıaJ57P|p k>SlY+[7Tl۸juNϾ]I.^+[7I7p}RT[ 8|6+Z.C۩xZ9״6@zHK QF9,eP񔗝̞ݴ蚳eϢ3ŲyͶ˺ۇ3 8-VeʃnGR3pfit? s(_ fGkn[[(Q(I z:J+a˱(Xx_ɞ(HrhuYNnuDm4e2*(ǜ ҷjsk-Wl;Ph*OחG- Un/ij1Zkl|/<}C.ed[Fe% 1޴}SJPR)]s6Onϊd~,mf6Vj8.O᫉x_3 >H4NjNYh6{8;X47>=-hXV@h(R atV$h\0/ム\y AthF꘴!/-}Z;Sb.9tpCg 1)Ȧxy }ZRY32wXby|h . f,gWx|A;"S,95,_'GTbߛ/s1km]/\E"Ilߴ[36|ʵ+D8ŌHo$>ߚ7˪_U}Y_kU>=߀? B!B!(VUh ,.pоc#[L$B!B!@cЀ+UXGH X\ ւЎEc ( !B!H (ϱ>|7 71R˾B!B!HUAҀ4(xJa1p h"σ"l^/B!B8OhmV7F4W]!m2B!B!+n!1>S=8ŀ1Erare/B!B FiЊ&QiW`7`p#g(D񜼎_!B!@(`xViB! BpAȷ()Wڢ l*wB!BP,5XF!Q$Ae˚+B!B!WXmX P kRJ9T zLuشÒky]!B!Bk4*0ecn 60{B!B\k j:@B(QcP tbeg ^ٷK  B!B-ֳъG[ F?v3| XHd/B!BV+"F9n|XF.X$OqB!B!0 QX@+\$: 4O  !B!β}E$b"hSOA\aYh/B!B 14킣 Zk 7X㠴GX+#O!B!t@a*PJHDUD@g~/`0"c|!B!"iƠ1&9t IDATcˋ*Q  ip]K{y_d!0dZw%LNrΡӋw\l4h6L^!]bx˄ kVE ҥ@.€IOgplTfǁw0$2 'fF꾴u/8?!\ÿI3ϯJF)m z~;'OOcV# ;[qu=z+ǢM8U{9J&iQ8І >rq`,iqr(W4r/UϬȼ]ֆ@K$73`b.#ۢP$3KPl1u_fyoW qfǼ mzC}jկ^fx A J`\p4buz7tx\ />4 +6+YGGʞTJ惡SEq])Q(؀}L钋KΤQLw/NY0c ; g>^yl<4ϔOeYßYǼ~bޔh8A /⧧:~vz ;[^)T]!/e'Ko:KZ4dTU.ͷS+S3ƝO)UKs7jzjկNⅲ.!=?@; _3BGZRS'r\Pg$-kzv`9\xE~x+hPW b%шOO#*1hL@D\TME1tceٝ9{fxL=ӳ[˗ST}o>\Νu[Lqy{ -/,AgUt9hE[l~0]E|7 om׾KK} 2/i9S7&Ͷs]j|I)iG- XZ.~{nZW}G8*y?gW K# 9HXJ%}0 }7A O`ߠvopK'q⦫ǹ1n".0̔ʧ0g na_kzyyWr:<2es_qvszI y3vqH)>~h.( s/i?3 ]r.gS|Sm\<~׭;;9vMGW󳏬יdm]9;_=3_vGM￝x %1%b\qD\+։ZҎ5?n|3Fo@`me޾uq{6wӀ\~D"man/ڔM8ĮAy>smÅ2|y~j.w/K=SK)Â0 ;|^}?bf*oϮf<&`/l߽ /D=ҭ [ Uw?{+ȷ<׼ˋ~9e}"&OGK{Pdqp4Lrj=o mw>S3L{z|t33$'b{-DζEy>H=µw|WNRKs.HK+wK^wxYLng={=ɱ=qQ ۾n J\ټm?֦UM{ns7={B_q-'i啕˵r|)|X%.pp# ~RJ|Q[|y|l߃UVe9[w?WۿⷿH,Y}<> ˕?Qu[w34&@`M>~6YJu? ;WYrwcޖE3X{\:Twc9`4H/kcZ pdX}oJ#".aQ|_s_aܰKGw#C[_𑲿穀nu-,1&spƟ}ټ7o/Wf ,ex]$pχ~y9',I't'h1qx?t~w c`vr ,_7%ii_M8<>N?d}R>#ퟹߘV|jb3~plyH 0/I/dj.wPݫDͫ!>m9}Cիg~2k_TLՔ'=Yl0r8h_o"~2{r_u[ r&K ;WYo ʷ;}~%X^].aZA=u*Oq\I:K hRўdF\q,F{voi|v];CZ~vWs'q;oBzY.ݠKs5_~#076O:|/ykvk>#}s￾^OdۓrKߣmz-$S|k|о&uڧ~= O{4WrRiBa/]E_jm}eH% KOzo l$n 'Ϡquw#Zȕ7u,U/N{}uVZw|5pw'r9oyMU$wTC@] ݼ oxZgxPΦG +//ZgenjbJHsK#}-.w e %*pC!<)0KF*B!C$i "+݁o9ؼmW^g|=_]무`ҵ?QXKKË\"ֻfs:/.#3=d5.bX,bX,3 ! pI6+P*%gWdָq ~}-bX,b4% Rsg(AKS|-wD,bX,b4c@LV  85>Jx mQLbX,bXVYMX#N(α}쐂/)h a/, 㪺g>sWDWS/8KZ>rժS۵}.G>ߗ޿46͢\~\yG.97"|ZV}^:\;mR{:o9}}\}˻m=_skX}+h5M\$#HIiY>s"F:i¤$,Bkn}ٳMGw]{I}7޲ZY 5hDJ4AVkPR;.?V*z!ӗ}Wv9^qiZ ф]C%AHQcIh8$Hig-u{5s3 tuO/??9q63s]twƸ|C˦ xY.0_|.r<Ϟ^g߸}~oj7$/{2?pWG\l6>~p=[8 |W=\ZOpp_?9N?vꁲv G1ŚN͔ 9e햷뽿~ph%Hr^u\V+2L$K:yl]}ObގΊil~0]Ef'2>gWl]Aь^1zsyjrUq9;ZҦ* miXŮ8Sʶ;Mry/'+Ae~twysϻb|=\I;(lݵ|6~*>~s?+vP#3y?\;I#λ7Ͻ姘 rg RĠF|ha!#NG4<(w4Ip׺e$]Q w~_0ЖqEWi s/䦫ǹÎ_=?M6oy?$M5\A9/o^c}^p&Ɵ엟? {9WÁ^xry᫟'r#^x߻EyP3 W~P3ۿsWt~ G]zB!n{v9Oat8]ܐ?O~g!Ͻ>OqOVbs/:l3]\1|R@k6PX<4^g^p&@UK5 )nr[NP*geX.r3}M u%.7Aenzbn AuD7#_9n<%g}nP[߭ڎUMQ%-˕84([ͮ5#(Ae~U@CvPLHx}l}Flq+.[errRMO~G^;;WIe+bY(!!pB'5- i1'#\.ֺeA^ዘ8c3$zޱou?گwsㇿɓ iv- EDbaz9.Ƀ.[j(r~? gg}:XQu,Hܐd +Y#H\GLJHG,F-'^Odۓrowm ;7p 9Z Sb|_~@6|`o߹7<}/e׼D۸k⻟)7'$CpNo՚Z}kPYj9X/t'w{ˢfx?k׼/p\I{~`ٗZYy/'(o?x9zEe,! 8%q ,Y'f2,3{K376=j^y!xWy{ Igl[O߆n7g. IDATrVAڭe}^JzǶ㵣V_ ,{o~WWP{ \HG C iv@HB1fHN+܌c<\dEXֆ?ʓ>:+u0E<ݹDb!>sWWzT4znێ-Ofd\1jx`4d]'F ʅ) ߙ=FqJ27u,bX,b9uFB*R HR|>&DtuʟmX,bX,e5c0_gA!Ba0mmiZ[,bX,b1ahFU# N8pRG4A Q-bX,biaFR #0Fđ׀,v<5`X,bX,d!!p|Th ^FFT$z< >!X,bX,2_JF( @NiA#u-bX,btn?7a@2v$NVH KA,bX,bi2cJ#5^Dलi~ t|bX,bXZ 1B:_`sGC֘|}bX,bX,k3J4e!7WH#p\1>HcȤ Z=bX,bX,pP-6xY#$NTB<4 gX,bX,Kk`IR9 @q1Zhc1d6ȞbX,bX,@c@AW pFՂO voX,bX, B#QZd&chT>BοbX,bX,@)z)AaxD(O%Ʒ-bX,bi0h(amp6H hhZ~/$qs H!Jh`5ɦdʢ}jQ!E\ܰi!rIT m}1k,G6%Ȥ{CSz>] 8BJhmZec|w!FL*[[4apS/{YHJ E\Mϫ굞 98!5^#H23\Zz/W ]"U(1I/dȤ22xVQ3|>H O1R HHF ir(x$Iݫ^XO/1?|2̂H4#J[GPĭ^$(PZR2 s $gmjXZ~^c>b~v0r` LNqttjz ne3I`' wBO\^)ewN1αdrj~re պ8" GB),cwi!ʐK0b!젿^RxBHa|-@*C(,q|FC LI)uDţD㑚!:zir\x!B0J ! #F[{&P/HP$D@kgHN3;9gw^*=;VUȤ$>:k5sӋ;REh{m/?AJQiKPJ٭*z;۪U::Z莓ez_wljG‹&j"!?0bnvى9WBi)-A 2! 3xn~߿"]mttlj# &3Igo;3I;0:wʼn'b2H B*Ixg{cv2lRWF}ft\H>:k]3Sc3(xl+#|/%2^IoCwc3`Z%bttO@2M l%9=DrҪX/Hn![qU1U>aL-ʲa  6Z%sNX 2h! xkT텽-eQ6t3=> U*I@DO3y|'uIe#  vp9T'Hs>aZZZ"Gajlw(O =xٴl T2b%= ;L.=ߡ^Ky^ξ%/U5HKϧٿsl:qnحzPY<#}ifNS1VT=W-AHA{W]mY'^YR(@ |F 4H #}A0 VorO_jP{3I&L͔~?^p\E@'_ܱ s3 5|E(G֑ۮ \VT GfN>V 9t]+|ET27?`Cf!SұȤ2"!t@_2 S3'S sϗR2 굾p\EGw@1Oʏ!Ze^֯ɶ-gGHZz&RIz;Ij)-0qx\#Ri2YA6%07cf_/$75R zmon 05>CUToC 2^n)Q{ UK0w/BE($0!VdB(AX* RPa !cɫ1;zuK]m<.tu3h`\k=rXh<ޢcN0stkTի9nm'cqMζ,rG-=]nv5z~=ZJ%il+ aZ_NӾff"515".] XٙZW^=>}\sh4x@ , gp!B $ l!v|ISb`S/=q=곣  1/0zs{g[.B2B2ő}.}%)${I3g|]jTիq\m쥣;cȥ[Xǥy=Qz/*o[2GGZ2z&qƎ)%HA^H[ =yg5c2Un:z[L+q⪜/0$c Î*<_#. 4>hJ2 -L=b3gl]E/lcԺ[m?|Wk05k=|d] :ㄣ!SG'b2׋k}Ḋqtt: vCjz6R 6t^ +T d#ӌl@V8}݅U?zGM_@,J•pH!Fa@6h ٬Shc#!e\,g@+5#&k}s츹FJӆEB,$S'e#2 8r3pAX֗^eu# m[@ydD6q#6 (7,:jw bqT %R*\pD  !$gRoPYJց!$ 1XK wݻ}<9af2IHOIH,̖70wOz^';9Hm ՟(DV#Uyz-+P$DW?z/,Kk Q׽1&S%ܰæӆ;{9e![)\hraR)r&G{!n_*S /NC[-};K#aբ}12e6$'356cji  8" ͢&=l5⥱[oڣz.^Vdf5qѾ.w`S.D{K~w\T@׃^ &Ou6ZVZghh^yW1up1zTۛߖrhrC# .{C8Y\<|m#!A50%}$mrnpCN 70H,Sؿs%:X6WrzчZ7dp 'ٗ rh5]yW(OĈGku.~rd+{H,̦ӆࡖwL#$`yf'b'S-?QL3:>(x!XGwp,O["I@77Bܰ[CȉH+d-VE,V+O4acLZ6O^6&S9bQ3-Atv, k>zUeW^ŴuDskXc2M2=>[1&S9t0wjUbO<ƺ^|B0B-c/$Y_0V$$339_*ÆMTU|K{ 3/f$w,qx A3莳y0'08!ξN:c# ^Ҋzܗ 9<&NJB2Ky# 2wM]3R0r >~ }eE[HMff&%_k_-9oC7>~ # 6ԮӆJ|yPkR38jGw|qU.pvT{}-gw$pV0hU3uYw35>{3;9W=B 6:H[G9[h<†d!5sYfj03+dHp/wAg]V[}԰T+M{|UJGm({ qo%"0# 4|}Z4Zq1 轌Gj!Cf!C6Un\#ܐC(" UziwȒK vR32X k4C'Y9ȏE::оy.?*djl$ݑS nWdR=Ϧ^)ˆ%:z9g^wW<)c*'l上Cul545Vh=SS]^)R 6 GC$z1ԴU՟i~|hf&BT+^ȐMGSk>༿|JM;!BQDUGI%0Z"3謏||fI%+9Dg4&v9]2lnh_e}_Cb54BDM,e[)A3yk>~-~"3U=-V㓴ޡS g+ZUnW&hy|mTzI)WrJNl[)m=LNsxX[oJM,DXSε zpg}CH}* Ć/x]zk9% Bih18h 0f l]Q$Х!%oWI6eQ9MRl6\vV&a5/%?ϝUZ ۆje]cP'{ AgoGD>^H){ {6R .4K_֫{?Q9lkOU/Z엒˹Ze^[ "s>@6<l8y)!'VJ$%>C|:Kr1mVJ6xx# }k^KIͧiLϰ{L:K{WnU\;GW-QN& G3Fz~M !, IDATxYZd*H[*Z_deRB/j}t(G"cdO=JsK;D=o.U&L/[-BoQ֕{мǞ05>Ӱ|6wCD(bCUW3fSo w1ъ)a3>׫*:%?;02313dDɇ-G*YϞgbtp?xY2ѩ}<\MUup6me}>PݪF;zDV1Ic0 \ 2R"!1`$^%Xե' }Qxgdܚy0~p$k@!3+ѫ8XS1yw`}U\BJ4o^5< s(-?)amE=z9b ly_z y`S/mil,'6GGdAU7RU2>ҘLH4=KMd@RhDJ#> 8Y!3l ;^"WZ 9 veT={ȁ ncWnz g& /i Gp.n 9eW dKgOVTkáGJ򫍐hk+wy?8J۱]rL6Þk.wx3%0ѽM}^,TX{ bi±'u"g%az稍UtfiC^;ݿ&݃M=>v!QZc"##PF o0tuݰ[61tu0U~ᮒ}widNX9(C[9# %T^R 6l(q(Sc3+:UJAD骂 c/Fk*9=<ɩh_/3RIUآ4뉘>v`CPU_eqzu}S"[,)>Ұm߆nH%K4+Sz#LNguXjekv6C>d*GGO;h}K; ! A|1`+HcJi!pP1yQtfQ1/=Zsx|Q^#շ$R>`S;MYb;9^@X(CRH~N6=5Pĥ{ htt3EZH8Zg,UD%>x}w)D]}AZyN5d+J8bH]z# =t9emĵ+!q ۅj^ b~2d*G+)Y{m4Uh_}5*vep$ h L2خ;{ )`{SC4C6GȦL,ZaTWDdeGrz= ^c>"=!wZ2 7BqG8W<#\djَJHX gP帪$ĉs-3pl/zW"wE3%Šgh_/]ڒ;{Ë,$St_gC(GRFr$GMMq=C]`鹦%`ѽ㫲c!blDUf׀\*c6R^y+*Iem P.&RB]Ƕ VZh Tnh))$R1B֒lzq峳K=KzȤ2_9zhS}~q=zI) /<^p?gxLN{>v߻{Ǚa!*> S3;{{>fJ܌~P 4spxXIzzZn_^RI:{j^*7.ޥu)T~KJIglo6=Ö'HݒJ.Z; {;XӇ*=V16o@H7'{wƵm?@HhKO>Uʁ#7ānOp>;p{8p]r:]}WZnEOD6 ă/5U]k[$@ pb9ۋXxK(IzrL?il~ m c&'>ק6G-qHc/FooRCk 4rDG/uC . @x #9@ `.znRuBY+q?0eHcR=\ٝ0_5p{ч,<zm{IݐlI;(7UqeXZ1,Xwn\~fcJitC梒4RT.鿍ߒOle t;F,MNT(5KPiՈdQZ~*0 @Q0&% @]hąF]'*jwbFJC0;7mNӑ<ùe *i,{4%Yp] Uz]dl?VB8IeTFwI&{\@0 4LE O>I+vm7/ǰ p,~R{n,Y/4(\VuUP. "O4J0@(&<@4@@9k%!USBjmq漍4ׂ,T=ˏY.?ކGgzAєX;qE))D( 6S#w?7$Rw?ϣ{elc ݇mٸK1Hw؋R NO2aiGj̴s{ &{"pr!kDTe AMY'՜hj:a# x p)GPAmbPB\w<`Ba\ُiz~h۬4=4إt'?n.2j[Nэ;uP'cwMy6S[2d Ŷ(Uw`@In7?bx{ǻxcUAz>|m׻ۋ|pZ 5c`[kvrBY-KiA(~DP4צ^P"6 fX*y/h4L@! T X PCzЋVǃ,WsSNApJۣM9MFڅMj/Ee,rlԤU#N285PF=>Vy6[}^bѳ^U "oTv9uEee/mOw^K%>l^0L1LzõdGy b.mk4,t&<(P0ds4:=(oZ0AitB]BR8:`9R?ae P5˭k-.v qHП-1ZTǕ?q}8Uץfiܷ{׾\5 l]wׁ4 .!Bz 5'0\@x:\N-HwK<SXH۔b8  fLjEe!5WO#W=(-WvZmh>tm8;S%Z :vueԯF٫Xݶ >sz>Zr}3H'ji=v+h(\6ZxʮPTwOƙ䗪x(Ui) xs~_|\\8|mb€d1NK{S(x-_>Ƀz'[ U}L}Ni0[ě qEN,# :{; @"BxB1ơ( 8X$^;s>k[N&E{^ N6S4]Wpщ 5K8wTػ_(Gj2fm "{QJR}nj\Fԯl8_7ƢUq 5Nwz^Khh Z9S.ќvREVk>Qa(Ԝ৹F@<{I^iwki%*S-F9*i |MW|yΎr&Pr\:#p<3qM `J 1E8"(Y BXo6JjOqѩ_'Z;磥\ESpj'3 JU#Rl6KM@Yd/eipzznJxJSG[5RaN9ᚮ銦Ğ=\ m$FIVU!nK1Vj2bvz![>M= 0ʠq@8ț!հ+< J(ą ,#jߡPj_>ΠkA/|(qVR{=>f+H5'0jsw3GbsJ rTMA\JESp: {Gͅ,jrccR4̳WVQ%;dˇkvO?}E.^Ow(zd;DЪw5>vh 0ϾD@Ч "#%hlD0pA1x BB(P(qA=q0x`@I7+(*)!e~GfM;iqZgIRN7/4Lԯf ?{NBQ.jZS=zF/80i[|yzԉ`$;̲MR{i vSuJnBkh>tbڮ~A N5ol(.Ip׫i}WX#QEH d 2s|P!Q0JA(KMO)_|h{ZW.vR|pQ>qDPKwaTMqvqVf:32``Z%r㸹xxx{v (0X?^d}De牢v j2! oV BP0N 8xp0hT8 ʳG"{`%C);fߞd!Bs5]Mlvc4@7zHu߶l|pzƭ{ ۚJF{-xYQǙg/eES1b϶T4%4]B=vcgdtuH E(U g8iMWq|~ó}lMU?l҈J45ʅXǙe/D^ SyvdIf,gln p @B=PCUO*aEdsBB< G D+ fOFFָn.\P<,FN#^8 ,{.;PJB0НےMz핶vReZɏ0j{_QQ.X9幝+0ue/D^* Dd"Z-6u4qPU@р\BA8LP1+Oers- L~ڬjJ_Y&)RXXa0OۨDj&6E\m9hܵ ]9+8Ct] ԜmI:n.{P3tQzZ9O)cVstԜC'֚=^d=0DRCk5'Di)lS2 W `.p((\!Û!!{ȇtvBͩ=^Ztbdf=^qwwa; sm94̩݃Rd A? W)x$jN|K6S]+R4QyFAګ<# j'Ups=Zθ Cxq\ɏw퓾T5@)5KT$286k!'` vfPjX.`е` R@;بF2vZ󆎜!/| Z^ρ>':y:7 qΕ@c a ATpppB\`hXf(E~,nL1^fD?%Bsו={mN뚮AQBG`طJըLX:,f+s%Xi <3Rn;0=PFcoږ3SY|ݔ*Ow9&o8h%;zb }<WH!IJxU>iln\TKM7okY~ شe(u| FLL˒kK !@P6U e \PWW#$d`N݈JC+:7ũvmx0^z\\4?:Ɠ̲㬚QbV$oc!'+D=7QuUjd)h+ ^i6IoBrF=ulzJOĤmK!o:/5]"SA88 U4Cg ,`wHx(`\'+x-( Q OuIKd|?,fP cT,{eEexgx$>r|M)hߣ["YK9^fkz!5Z'WJomD@78 g?j"&Yn![l>S3N1e ] ϐ'2 @aqn^6<*=e"ز{I I?!V5^YRRuY@=u-{;)({;SQ-U=5]Eyog,'@]^g5o)OKc&\vI IDAT4D0#rfTF~,|2vEe\ [u\ aS:q@r*@A8` @U ۱x!%!f ͬcÈ9|ҵM0^viZ o9b盋t{{˸ws!"A]IjsLt{l&Hz̬^;$'þ D٤VvD vT0!@@s v4`. xT ân!dYfne^LςxgV7/'R2~է; } eqѿ/zoJWsld>'h戛YOsO iHz̬^;$`+3/%5LVf8Ys*^Ph*@)es) r.G8e p!Ny!o\o*B)PF1R^U4"A]f'iۋ'=fϵk'yؖ=]_?{חeG=7O"D_fCd1xz[Y# 8U(Qya`0p <(CXf\ -RFY \L/밗L?՜{j +=' eƏ@g qshԵ\"dY6)c&!M0' ,((Mb4Uii g"?4ʅnNU*7O̲צ$f5ĢJ@8`qeP<݃}̃GE>kƶPo .2q-ٜV-[$"X!)vm#sI$8` $,㸉5ZhܵPj],1TDp Gm&$'!>ݡ~@㮅A7zbQI(M&B{t'!B% .B9@ T_HPod{ؖ]frVufy*ъ=W?XnGlP;6ʅ)1UlƜ?CTI]:كukVM\nR_^_/hwz{MW:!1fޚ'I^c_=ZJU*q}_릚DMWq!(_7"3NjR߫Γ Le%3=u,Hb1IKŠkahٱA[U_>j_a!ݦ`"f+kl~|.IrH=g,V"@  % 8!p8rˌ |{-b&Z l~{k`oZN\0GƸϫE]:8RͶH:#ۂS:| {Qo_R>Kto MN>Q(Y?Af;@ #Ij'qk5|pk'U"xU~݈|q9oOjx^ͲW[^;s/\#FF2v ׬;?yURC+;D .=x)pΡ@M@s P cV`B:;A'BbNb{S=F|+N"XJ]+4] h*VT]rp)V?^$P$ϜtL;EQ(Uw_$JUyC.4]Mle%eAiog}'J߫8%Nxxޤ5$Y 3ea`L2ESr P]UPQ y rҎ,6߱eU-'݃rk: 3T~ƜQJp߹@{I!̶*-gYt\tq}q$m^A_fo\}Γ' Z4sooxlc]%HGTeqJl QA8 xPl DC!ʳ@3""F>Hք<:d}f`9 ;ȠOB,G#N>h .U M)?8QqYZ5_t|"z00-/_SsLk}pm͇RCFES0}WMjy HSF cxyíq_={ǰ-'i%g/DYAVvJlsT2<ϙ|P ?A/80(T#p# {~r.0b KVrƎO)LjNűנ; =ҙ5[q_*ꥪiULjwOW}{/ [NSYS ͬx;^it?@)ucjSB~7נX. 9n?gWQq &6Ea[n/z ֢e$<{I$Z!{_dzڃ#`P@*< a{&ɖJ L)̉q4I {pE}免5#׍kM'8<ۏ] gx$ܛ~9BgR,+ ?ԠMR8:ۇ)t ?"_$em6i/EeC}I^|~?g_Oq|~*HQ=,zmZwI" QpY%>AM J:a.@93K8%( nfwef"wSqJ%%O$m9pmw$SFaT6~mN : },f^ lp.@)נT˅ovgZQ)NN+^iR,'SLb`m)*û'!ȸU;lbU(*Db0 {PƗױI$Y"o8:ۇ{|bRQ.o#~vŤ-A,uC@T"aG9<S0.=L@Lۅ5r[0k){3M^Bc&lBd>R k'U^dֆsۋ1R EE)A:wqDيs^ixn3q>k#=W(>( 3]7Ԝ:YL%ulQ:/;`rejN\\#$64*MAVZ8eR+m<_uJ6H d 2i~ĸ<J!x#L@CpB?Iѓ6E  &Y=6 .`M|W=3ʅXZ OM|(8|Ww:*PŵD;jS0ЦCQ({{&҈N0Mk#=Β` [okrJWgtOMyUL9r Lk|ږ3/qm7h+\# $?+F5x-ֱ̞G\ghe-U ?!L7;-5AHiAbxw ~=wKT  9c q7 J@=p:i 1Z.i^TQ)J-S)N<i8IR{BT_n:ZF~ x#^T5{PMĶl4:~)o;:YqQ`^1=ʢ˅qpSdTK㠷R+oZy{MN; u<|pf:eE Q7Fꀹ S7ZűqU|ז연{i7;L{G鑈HOLT/*Mȟ0#E\GU@o5Zx.WTWn&S ow 8! p`9TB # G뱓ރ@3w̆O-oɒx` e{5:8l+UX;Ow-T`^;bhىQu/g1|^f?v$ra:¶u<{HƱ"&{geJp/]f&n~Ierz W%v 7%^If٦T5589.Oݩ?Fdp'yiz0*E jN4ӊZ$OD\|YY?ncFkг挹xw:O&;:H40!Sr a.p&NAe$kFp0qpR9nlܐG/g n30hp'׿OO\~M|3:q}k{vc=$kdnHܰ=(MҞ|QǠgӈ|IVOEy߀k϶؋s@X.`{/LMvkz {+sZiu(%8>?g8~X*UR{̓sxfi> +GQr]9?H\wYx;qKKUow kYʨ <6H$(@MkfuGj1ʟ4G)Hb8_^k'U1DB0J <a%Й@ @B2( "(OwPfQ<& E{$cr=XUi59iD;3l 8ۍl v戜cMWCNÌd$PJP|$ PLMj|\>$N=ʄ'HìcFi~ϱ+&?7e4 :ҟ.@Hc/I;ňeu$ɂ`{m+v]{34$%4^~{7Ɣxz})y؇g8h#ħX.#ޙ)%xop)>o9?Ŷi5֪2yCgߜY&?78,ګОҟ AwXSګ 3%~HП3f<ݵ#̒@VѫIRCk5xN*mBp"B@U#C<Ar.49G? ilV2e]qr}Tv\JMa:|p=s)@vR]*3 8 ˇJ҇jKPʝ^P;Mzl,X;[fUHVˤʰ)r_^ \zU#:1J:Wyњ]j]Z{2~׸UIJ2R80NOϹOOh"4xi'%D`K0e43e"c̱5ޣ#9WHC7TU؋s?C%Z)QQ%>.yf=:g{뱯JŅ m9 I(~(/~7H[fS?DףVn %s=to>6,GGPJ(^U1x*я4Mk =XI3RO| C!|]E#Mr5fw1Z IDATJUg!(y' 6U@%B%+\=r<H8CWW|*ct?Զr=мU\e5/7OpRYituuDX^NjyIrJUm 8VUEf=f`ZtOcQo{a'~wTz\5Ucz^Q˗n/ækjܷ[+ isJ 5jD|ʋ\unL#`@Q=x*{A=x1^)Z L @Q)'9ӲwTA8]Zָk%R&Dz)x$6fvږ8_J՝hó}E4]ȼJR5E:Ssbrl7VQ@GHJ ΢m3䇯g|O  ` `'Ep9J}prgWr̂s`8SJS)0WVjJYGŪ0(|#ry ea.Ee]mhhUۋsC6KJVCaF3-3k`ZXǣb-%Ml?zic&Jqhq=wTUirz[IUO&x8i+P(A (g`ry]\n _E|7}O[;72 1ɇrJ5XG L zAc*r4]c$ Fžnqnymٸ\7IvmK]򆎳?of޶O)tpk9K?\ߜ;6 :.8pm7wTmz)Lsaand*e6M?ؤz2 0s4L~~Hi{ٖkrf'7RE6{  >'  SASA8(! pb[P!v~kaгp²p֌o\/hTfX/OopvcmYgT6[ZY/nP;A!|Gpf E#B˩P7&k,kxk.{)*Cj`7t䋹XJ{Ǖs(Ԅ 0u`︂ {&3p~hss4J2V" i&Lf4]?[9E&uBVi/p͇6wm3)%ОE=cmsvOkƶu?4N>oSJZHix|qp`]-u<< C"@0x.(PF(þ[s`ZK],k8AV4L4fD94LxDw| 4x# WbY9_i0[=r{@X``?s=\vzruշfwq%arͨ4]N8tA k,n{ sG q.ȼ Lkkel^lǕJ͇4*| f ,۩JxmeZ7 <ݶP;0㼶m/K&U{}|#_ިN~>W=H)NpoxZ ڏįQKQRP0pP<#`B@er&8_7Ъw{PFj*y~1%Eéoiy#MCOSn/ٸm9~Ϙ}Q5Z^?lgal8 g YMu<|p%b`Zt+6/Q9.:v#bWYvRQ.}):u{MWg ;q~ESR5)3N-I0ན,kг&h[6 ==۲W ^$rtLPB*AZ1^gvK8Þ`T#wAA!n7\S ;: N>ּ$i bїŶl<ݵ`^sUA<>ynY:}}=c)U vٿX.`P$^ a==OxI&+\~.>ǻ=ޫК#:[V̏"ioxHLGBU8g*A@w˞؝z>ZUh9` cPPFƽ{B𱐇c9myM}Ǜ&: ?BaMp\EBJ vʨJs{r/菐Z=Ggͅ}\jǓ$c)U_MOW?5/[?1o?U?uVtf<'?۟~/[~!-W#~3!1Zw//O>})LK[/?sMs~}?UO>idU?;ٟiSh}103yMއ\ o?{w_9;;8N-o?{/ѷ_cTOQ_?,ks?;I1x|z7u\15/hoǠmϾs8~aYkFן'/ry }# e}دzw̑||82Ve3&nPa0`K?kHLOoU+^|헿1G޿}zpwܿFN}ׇ>s}{0_γݍ~缞?u}دoֺ Mu-Y_Y{Կo-?]U~}} ;;<'?~m%]{`^ii-gtz7zp00 ?0ֿG?)?O_|O^~i{xm&/f׃ŜIe3An Ne-|7|[~5`g]ܿҟ|>⼎߫O8>WƪT_߬5O/;<ˋ`~taa+??¯ޫ_^^տo/}o~w?I7Xw}dOUOgw7r&VF;G$6#{A9|XzF43^}/>ū:O]sLG~?_MS?̙"}>7mk/(?۟O]뛱ޯx񋯴@{_~»I__Dyzdz-r3~:OSW3a*`aeawɤs5O'=99EX➘!Rf1/Sg1O`x #L7#`"*ɂJY9“͝6 J?ʒ Q- ǀYth@aC0"2۝Ʊ%?w*~ zkXEGkOg- üiX$[QVX^+n/Z/fAqf11 3h u=( KN8U0s#pri8<{|y#iSix&YB PoŶϙAMg (7^O[^䲖Ӡ r™t0K^DA=LpFAO's (h"&Ŝ4\p7z+ aJSnE:ˀcS'ܰ*Zs 31Jurݗ* r}F|èE1Ŷ9a a1YF3+)I/hEbvip@yVQ(Q+vhK{QP ӻ5,*uoè,'F9a:uU\) ]=2ÂQ'9U:9(7]4p&-е1aVAt ðӜΝwwuPuQPE$F%X:CEקgPKpk(K _gIQT%c݊! C<`K̂ OŀZ笵$r}g,sB4Qb! ¬̰0Ғ(=+,hat+L7n=7 0Mjb sIl2K?tu'qd^ܠV茺)><֡{D@wF"6?hf ,#2'˲tnp ,=hˬm+WA1+7h+0Y̩8 e ܨ ,ts휷ArxMk2[4w\u7(U*OwrKض =O8 oV /.wOSU$ɹok04|+UY@_aPe8y-Wa`^)NA\VN+p&H@f:H3K8c`s賰*,\/9G,̉AsJya2>8O-&? >7<9ޓQ_N0BgX3܁)IyJܝ9QRn)=4*f ՏU\d 9 BwSqɍ9 #\6 7֌-5s CTdӰ愁(2ug+1u."f ?YS`:Y+µ4YL+뾻)s(PQS ݡy|Ρ@S^lMLgqbc&mC9z r )]z&0s\G-h;pMF bԜ8 7  H(iX5~7~+o^N8dݣGΩ+ya%{B Jyˆ aD[WIc֤B8Ib)TNLafN5` 77}&+0vVќsvS5Kղp(j.aZt\u2n.[rM8y IDATNW6Wcf$p6儹0 L=[[İjEOh^gR~i $ĮM{nJ9'Ë*{kϫ\EzSaT(I[5.Q_\'UTqL1Ip/eiE` ZD:&O8鯓ˋN^|9qDÌbix:I.@Z(l/. *ѷdے ]L}_xs$'ӌT5]|TEEgRg"Pc?4x`{ea*f0<%M3 ,%tnEی+ZU]cXBTTQJ }O1' ƺ|E಩̡+rdL.T Ka92'VOQ$ 7A0 ̌4W02xHdqK4Î΍:`﨏|T 6c@X"4V^6W|떨V (s9sji&BDly$fq:-8H[DF@/]~ړk+ j+a>9 4CBJHSFN(}\$ۂxg9l+~'bT`@) TMѷZ.p?vx"3uIPH&<(g /-r+_xFmsiKWso7b6pj+IiT,"c>kEl£hp}ROnE`z0d9` [+Ǣ80 n:д"H67 zaťY ъ29l?6 T@7h}-@d˜t3ɣ+ `)Ό- fM&L5igs. .:rw&NFY kݽTI79} l0Isc PxW^יnkvv}\DA8arW)@Y[Wnm- mM#0FIpnFL"2<ֱZ_XMH(8)OD +fo%+ cLmqZ`>\žU̠N?FoVt.ť|fd`;EH ?UDS"EDUL E+&SgdK>"T݄DgrM$"StBP-+/!<(Ca&gb{Aypw)O1VMF#H:^/th̕JqIQU@VqݦfE?nbh"{gHY{ P1*E8WQ0֡.I^}jU3Sg]x$rf9p6+,űe[ϩRNbQM̡> U r,9.:t_نoa 1bD lbh gbwKŬtʒISX&b0p/a`8A7c%2T P*vQ*=y/溬r*bܙz_YơcF1cB * =јO0X07z$wexh -I3U0ftb7]TORPcsh/./t>a_0K,ndGRiF9Cs@Fd_2 +MEy!\J*Ra|MjpoMLY,JL/h]X.q0{0l*1Or-Rn,w% L{h7i%̔:vS)Fob0o x3mlw8z)f 1߉H3b~kR cw=xUmM* jIy.Wcaρ>O9T[ n1bňV:'Bܨޤj/;IZ{Ą VS!ڠFAM{NX|"!)A^ _d̵ R0Pi]JKڟ3RD}שFO*[ jq9{Ls~8FFPػAXCfwD(|P.@M@Jo\`5FhV+ʷ܈.Y Pl+Vʗ,suV轳* v &Fu܌::p}2DsZ:+bED7ԞeKuÿPoBMoNnR"X%73X`DTɕU^RquŨ "‘psn֍A9kJ+yf:>Cq<& E- #R۞ gY:Gz֩[[`? , T<)`kU)طɋ`wIǸ1x8am+gOWxKVdETqΥÊ&/593΂!SX.^Xg:KA],'T.6)nEN_) jj+kFDWnߡ#ǡoC|Ygy@ ]+"*t ˅֙# T*tL,nl T,UWb) ,DEd^,+[Z10KS wf}lgRޘhwP ulXRcsަycC6}9EjH%9iԗxCBY-bYqiR2`>,צż/."r&y*&Or[z C؛!R @Q-2P\٧7^B0 w14X~J)hvkaPLFW~99ee,h8}"SdԶɟeC&ExX%Yզ,:kR*gMm(hsS¹5fBlnX3Y9l櫥]?+#"=dM2Al<}*= w 5c`rq ݽ\tg>6=\.'kK"[9d/09:~tH ta aH* fGՈ6Yb׳e?g(j꼘/_ww#F!huTˣ0ҘnlW:SdN{v]L%wH:y<\XK)2Lj3I\|~ET[{VZ` oM.t1Wx%JhTrUlbbdvy]m(n6}rfa4ٴ(IF[ibR)%7rkejJm--:w77Og`mOiT&%⩔zuw!b Cֽ M!wrv!pR1@L8沇y*T*WpݷmrQr\,`Êy /H[qbAv#\. Ef".Al.0gt5l ]uŃ}yjeߖ6͈]ʷ-ukQVENyuYߊEZę8&jp~M}r>"k U{b^[evk2ζbvp_fN3 \X{QOrZn{_nrݿn|SLUى{SVrL6WTWכn:X%&ѨB 5Nua*KķN 昘q!%XsRǥZa\Nl^l9*`r9\ ۖu"Kbmee.ELRn&{59LG<4HzWj\3dkzE d&4.z^A*Z[hG%#i"ey%61P`m~ֹXec,0_$CTÿTdf'z~NYCEO`tMluoHhKB[*ࢢ#SIX-:m̛9`> ڦgֆq=fH55ACcz.\KSMdK*Ls:D0z]A%(Pʼn&Bb̉ J:?& . g4U8RBDd1W?A&rs7 "ٗs歙ӫP\:<驠ճmE[w~(?<kP\jN\ \֛e3d[/@& O}9~)rkF@$#͔PP$r?{3_ Z4YGd]m;"B,AaD ح3fi0VOSrumRs %}WAM5]kfY(vs=jXyXB炰gW]R”smYl"S+7@Sq֗,/%@^NAxk,G`IOf[9&7SB5 0Cv}FXs-)gRKDW(n沧JsEʸK)Rhs3hhZwZ즄 ANb$sw/f4K:vhsmgG"rpG*I%~Wr(˶WPR"iUpR@"7"38rδbƛOqݑՠ&\sRx#rE-U'̦ԮTi5F%)6ݹK؀;n(]<#ڄV1J.ipUR} n0 5Yhn fD9}֫woCśόoA6Q0syYpnXK&m1 7bgbc3TNVK⇛)w\Z7`%)WNRKcgE`K'VyLZ_8PajU ω/)ьœ39sj~w_;l|r0 R6 8'#3Mq$,"p)@haxOښ4Ym:-I_Qim34Ch)OC,Tp7O둋ɩSDq2\’rM؏X&+1N9*Eo$:s4/1Ԧ3WLt323匞)!7)B/jI8ܝ{1WTQ+N0Oaf"TJ-[ngRS2,P-њrAp4)aEkmxLfL. F0qKpbfĪ3^j:} %bm9.S)^IUU\.c&5圧Ù\.%!1]|ӳfjoRml.nA]!NN_&V7e2Mx_L*UXe9SV-nZZ7*l WZ#SțzWUk5ЦTadpg.RU Hޙ`H=k,{lbԘ;O9ts3㗭"#5&[ ޺T5ٍ݋y-w]u䲈Ըd{sP вzeL4c@K֐$h@yL_}S!rTqߌ<mGʁAOǡ6 Ykj0宸ԳF:yY*>W;W(8bbIE8=>54Щ>[Ą""|R5e İX =b" VCFr?x'Sd֒quz4qdq<ު_j2}cNZ*ZPV30l)[֤ݔE˙ T9d斔j gUs4EWKc mkDYn]8&u+ƀc걳!Rf"-W<%mNFse-tMEqsVj+0.fȉB)XQ"M8{~g dջ48q{ţl-9Y}Km1"{lx}OWljjXjLhSSh!Ub3hxOe ᫕ITT%lR'5$k@[%wE,xd9`6նBl } `W9Ov쫽H/͍;t)! W &Udv @Z g{8O8w#3N`K^28*^iPY4)c+F1Ws Hkݨs 5wv{RDpξATAGP+k8XKrwIb#]QqŒF3 Y3{?3T+ޥziOse,Գ}"˓s8tl<wt:D\|x{LscE*.s+Ypgq9knQ\APl}a;;=i\ !}DaV&1Q*hV@zv(yJh{uJi2StL9޸N=M|9E٭՜؊kN,'O9Bg-6BM`0$ʹEσ5 XuJ'> ml1#vɓA XJ5L8 JC5h7)iۣ$w)VI$4.ׇ mհݹNٛJ oXi-ɹP4ԭqo4<o7k\M\I9N41]8B!=~㜶&ϑl߶Z/&6eI7 R3.alPf4L?&:OgbibRdwlbOo7& ?a_kp\6)U$*䞦E2Ox21OF6t 6t0z@ݠ Ō9dw%c݋s I~\HLf.{ֳ5Cr'.b%ǔBE)ӻ5d)de7% OtXW7٧>x-`alJ %969iR\w͉5d=DsNf.zy5 ^KP'c C[l6l-!'IqG\`mj.ZlpP{Bl'ŌLYPCrœXC49̔RxѥF] y!V":S=0G$jV0a*o:H+)*[1!b]]aМSe7Z~b3xNO 5=zŬ9<65`2A$AOՈK=zZϲ;Kμ`I,dBׯ߂ gޅ/2ƈKg>9˝8Fx&#TwC3fcdXo=bR䯭h&rryތTW5UL[wLsmTMGoQRkX 6yZ1J)>IO_r24i[Ar>g (נ&v1Q؛kcOCӭyXn6n}2+yZ|jp :d*I918x֖З"ĜY,X}݃15/ht_En-sM_KqSc ak9Wpa.װEڱ/{䥊mI A.:8ƾUk*4?zK,wZ9ww <eb#hkVD1y,ՋwE*Z:{-VkfFqq=ǃwo9+z,wV㪶&s`S#K&no9.zCWN\3LtC&vJY=anS>VĨ\n HA!§ _d~,6;asLՊk@ecs UP Ֆ%Tո]4a cUum ֱ8Ym fbԬi4 KM6 YkpY=5y@\U.җ8S}Iީצy0O{-S}a<œvxӫ{ʠIk Y_8Th}m :𹔔ؐͯ Op=4ŷ'/J|O dyH=5jd3MȼjYsb0T^47٫=m;hm[}Fz bƍwzG7ǚZy>oL+m(zҳ ﱍ]k YHr.1&UΫњ|Ja/ґm[Xjc-u\sK܆0YVUqfMJkY|+bdǨ[+Paz%*Ţzɂݤ@)e'Jo03Xom 3ii[ ѢxZ(Yȇ4z|p:|B Lwbޑ?4tIݥn"o_/"IuU3 (36|} %䵽y'#6|,lKF0-`ThЕMA[ ˸:{5: JeqKVj@IPatߕj(ս!ϠB*pҗ@fl/T")f]6-9V* BA VE꠬oo n\hG'bҌ1dYzN"n'MRVp 9la{}:,F;M+H])~f݋pI}c8,F¹k7?֚=+) zy. (Z(\~FEOsH~])ڀ''MFRs#iiripVgBtZ -a/{ǭ*Q۵V[/V¥:[7+bW^#?|J!]rojZ#w= $q917hz IO$w0Xm,:޵_w}tKgR7)3/2؃m3uUU;s3n+],dٖ/; CJ|rK0_`]JZkɜ}h7rY-+ʨwU&Rb2/ǶεmL^BF0at|Yrj1vmE朧.-5 չ. .b-#l$!B * ^suD`DmirXC@1m5r:܌_6تqgs׌yV5ٶ>j,Y eμ$zxI! }SSucPE,B{l(L;TfyǧT צuL#2f Zhiv Q8*Rt!ٖf0qq_]_#?7z:n ҟSv2ܜߤju 互x.:oFfobt-CTduo.Ly]G6f| Ԁ:Ӽ; ŒL0kӾ`X!zKm|6f_.\ǖ5|PD)XN<MlP(+%W_x{ê0IBU֖tWAq CIKAk[]ŢIENDB`torbrowser-launcher-0.3.2/security_design.md000066400000000000000000000060131351446241500212520ustar00rootroot00000000000000# Tor Browser Launcher Security Design This document could be improved. At the moment it's copy/pasted verbatum from a post to the [debian bug tracker](http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=752275). ## TLS/x.509 security torbrowser-launcher doesn't rely on the CA infrastructure. The only TLS it does is make HTTPS requests to check.torproject.org and (if you haven't set a mirror) www.torproject.org. When it connects to these hostnames, it uses a hardcoded certificate. So none of the TLS PKI issues apply at all here. (And I took extra measures to make sure the .pem included with torbrowser-launcher is valid. I downloaded the cert from several different internet connections/ISPs and compared, and when I had one I thought was correct I sought out Tor devs to verify I was including the right one and not a malicious one.) ## Downgrade attacks Downgrade attacks shouldn't be possible, unless they're committed by Tor devs themselves. If an attacker captures a valid old request to https://check.torproject.org/RecommendedTBBVersions that claims that the current version is an older version than what's currently installed, torbrowser-launcher prevents it from installing. (And by "installing" I mean extracting to the user's home dir.) However, there is the scenereo where the user has set a third-party mirror to download from instead of the default. The third-party mirror could serve a tarball and sig that have filenames of the latest version, but are actually an older version. This attack is mitigated by the fact that all mirror options use HTTPS -- though none of the mirror certs are pinned, so in this case it would rely on CA infrastructure. This is an edge case, and would only work against users who are using a non-default mirror, and who also have access to a trusted CA signing key. ## Installing Tor Browser system-wide You cannot install Tor Browser system-wide. It's released by the Tor Project as a bundle. There's a lot of code in there that specifically prevents it from touching any other files outside of it's own directory. All files need to be owned by current user, and it's designed to be runnable off of a USB stick. A long time ago I put a bunch of work into tearing apart the "bundle"-ness of TBB to make it installable systemwide, and concluded it wasn't practical without the Tor devs releasing it as such. If you could install it systemwide, there would be no reason for torbrowser-launcher -- it could then just be a normal debian package. ## What secret keys/access attackers need to succeed Yes, attackers that 1) have access to the trusted keys included with torbrowser-launcher and 2) have access to modify files on https://www.torproject.org/ or have access to its TLS key are able to get arbitrary code exec as the current user when they open Tor Browser. This may or may not include any of the Tor devs whose keys are included. But like Holger said above, this is a feature, not a bug. This is the whole purpose of torbrowser-launcher, so users can automatically install TBB updates that are signed by Tor devs. torbrowser-launcher-0.3.2/setup.py000066400000000000000000000102031351446241500172360ustar00rootroot00000000000000""" Tor Browser Launcher https://github.com/micahflee/torbrowser-launcher/ Copyright (c) 2013-2017 Micah Lee Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ import os import sys import platform import subprocess from distutils.core import setup SHARE = 'share' # detect linux distribution distro = platform.dist()[0] def file_list(path): files = [] for filename in os.listdir(path): if os.path.isfile(path+'/'+filename): files.append(path+'/'+filename) return files def create_mo_files(): po_dir = 'po/' if not os.path.exists(po_dir): return [] domain = 'torbrowser-launcher' mo_files = [] po_files = [f for f in next(os.walk(po_dir))[2] if os.path.splitext(f)[1] == '.po'] for po_file in po_files: filename, extension = os.path.splitext(po_file) mo_file = domain + '.mo' mo_dir = 'share/locale/' + filename + '/LC_MESSAGES/' subprocess.call('mkdir -p ' + mo_dir, shell=True) msgfmt_cmd = 'msgfmt {} -o {}'.format(po_dir + po_file, mo_dir + mo_file) subprocess.call(msgfmt_cmd, shell=True) mo_files.append(mo_dir + mo_file) return mo_files with open(os.path.join(SHARE, 'torbrowser-launcher/version')) as buf: version = buf.read().strip() datafiles = [] for root, dirs, files in os.walk(SHARE): datafiles.append((os.path.join(sys.prefix, root), [os.path.join(root, f) for f in files])) # disable shipping apparmor profiles until they work in ubuntu (#128) if distro != 'Ubuntu': if not hasattr(sys, 'real_prefix'): # we're not in a virtualenv, so we can probably write to /etc datafiles += [ ('/etc/apparmor.d/', [ 'apparmor/torbrowser.Browser.firefox', 'apparmor/torbrowser.Tor.tor']), ('/etc/apparmor.d/local/', [ 'apparmor/local/torbrowser.Browser.firefox', 'apparmor/local/torbrowser.Tor.tor']), ('/etc/apparmor.d/tunables/', ['apparmor/tunables/torbrowser']) ] datafiles += [('/usr/share/locale/', create_mo_files())] setup( name='torbrowser-launcher', version=version, author='Micah Lee', author_email='micah@micahflee.com', url='https://www.github.com/micahflee/torbrowser-launcher', platforms=['GNU/Linux'], license='MIT', description='A program to help you securely download and run Tor Browser', long_description=""" Tor Browser Launcher is intended to make Tor Browser easier to install and use for GNU/Linux users. You install torbrowser-launcher from your distribution's package manager and it handles securely downloading the most recent version of Tor Browser for you, in your language and for your architecture. It also adds a "Tor Browser" application launcher to your operating system's menu. When you first launch Tor Browser Launcher, it will download Tor Browser from https://www.torproject.org/, verify the PGP signature, extract it in your home directory, and launch it. When you run it after that it will just launch Tor Browser. """, packages=['torbrowser_launcher'], scripts=['torbrowser-launcher'], data_files=datafiles ) torbrowser-launcher-0.3.2/share/000077500000000000000000000000001351446241500166325ustar00rootroot00000000000000torbrowser-launcher-0.3.2/share/applications/000077500000000000000000000000001351446241500213205ustar00rootroot00000000000000torbrowser-launcher-0.3.2/share/applications/torbrowser-settings.desktop000066400000000000000000000012761351446241500267670ustar00rootroot00000000000000[Desktop Entry] Name=Tor Browser Launcher Settings Name[fr]=Tor Browser Launcher configurations Name[hu]=Tor-böngésző indító beállításai Name[nl]=Tor Browser Launcher Instellingen Name[ru]=Tor Browser (настройки запуска) GenericName=Tor Browser Launcher Settings GenericName[hu]=Tor-böngésző indító beállításai Comment=Tor Browser Launcher Settings Comment[fr]=Tor Browser Launcher configurations Comment[hu]=Tor-böngésző indító beállításai Comment[nl]=Tor Browser Launcher Instellingen Comment[ru]=Tor Browser (настройки запуска) Exec=torbrowser-launcher --settings Terminal=false Type=Application Icon=torbrowser Categories=Network;WebBrowser; torbrowser-launcher-0.3.2/share/applications/torbrowser.desktop000066400000000000000000000005011351446241500251170ustar00rootroot00000000000000[Desktop Entry] Name=Tor Browser Name[hu]=Tor-böngésző GenericName=Tor browser GenericName[hu]=Tor böngésző indító Comment=Launch Tor Browser Comment[hu]=Tor böngésző indító Exec=torbrowser-launcher %u Terminal=false Type=Application Icon=torbrowser Categories=Network;WebBrowser; StartupWMClass=Tor Browser torbrowser-launcher-0.3.2/share/metainfo/000077500000000000000000000000001351446241500204345ustar00rootroot00000000000000torbrowser-launcher-0.3.2/share/metainfo/torbrowser.appdata.xml000066400000000000000000000034751351446241500250100ustar00rootroot00000000000000 org.torproject.torbrowser.desktop CC0-1.0 MIT Tor Browser Launcher A program to help you download, keep updated, and run the Tor Browser Bundle

Tor Browser Launcher is intended to make the Tor Browser Bundle (TBB) easier to maintain and use for GNU/Linux users. It downloads the same TBB from torproject.org that everyone else uses, and it doesn't alter it in any way. But it does make it much more usable, and it makes the task of keeping it up-to-date more secure.

You install torbrowser-launcher from your distribution's package manager and it handles everything else, including:

  • Downloading the most recent version of TBB for you, in your language and for your architecture
  • Automatically updating (while preserving your bookmarks and preferences)
  • Verifying the TBB's GnuPG signature
  • Includes AppArmor profiles to make a Tor Browser compromise not as bad (in some distros)
  • Adding a Tor Browser application launcher to your desktop environment's menu
  • Lets you set Tor Browser as your default browser
  • Optionally playing a modem sound when you open Tor Browser (because Tor is so slow)
https://raw.githubusercontent.com/micahflee/torbrowser-launcher/master/screenshot.png Window to change Tor Browser Launcher settings https://github.com/micahflee/torbrowser-launcher micah@micahflee.com
torbrowser-launcher-0.3.2/share/pixmaps/000077500000000000000000000000001351446241500203135ustar00rootroot00000000000000torbrowser-launcher-0.3.2/share/pixmaps/torbrowser.png000066400000000000000000000214571351446241500232420ustar00rootroot00000000000000PNG  IHDR>asBIT|d pHYs[tEXtSoftwarewww.inkscape.org< IDATxy|T;d'dI@ADqTJ#.ZnjmڟOU[)TmRÃVPMv!/d23%3r'D?ds{{|EPLZ3.SWL @R'Z]ͬWw}q/ x2D+y.GP dW EPb7RّRrKia{/$a@9۳]P $᎑Ȁea8Ae R?rRQ!FlKy%0(+9Z@] )WI!V]>i{L'?Ixz1SY cwpͯ!~HϱrxMs^jꡘ-Xe^)vt]./{Ƞe-ŧmC>R>W[ټYΞ ;<6^ [һ*\"AJ~=2DV@o]8LZŸu[nb0yȤbBT}@/N W1}uBC<;|"}*$f)HL:MPh*:/m܎-߅*m}q>!LB)9޻.w( B_^L^haȨ4, , 4 MP!jF*4RekRO ةH{9U/ (ȿHzyUyof4'윲0Gs&9Bt:[)khO By p/zS_Guz::*&,7/ .&?:eֱ>Ņ@,lqOB`^ӧJ\]ץ{bAE zD:F%;_kZ23o**7>qFQֺd.G0ǻ߷ǣ|go4aeDi F/m.drZNtbtuӛ$-5;M1L )@XQ7:]wxrYYɖblRϪf0^}r>ڹ҅EX$ONoG ztդp5ù~TE(=V GlȎ5 Yj1[׹F`HG:f,Ø0`I$1ɂ59$$QDF~Y%cNR=U8M~QsAO*bY\]|B"^ ^hzC@EdB FL`9ihC$eI)Ճ}yE% zE) ƻ.{-TJ=0$@0 eܼ\FNS,ZϚKĮ?!Y9Ꞵ(EH}rw,JR_ 7t6x2:C@ ޮdߪJ\:COMA5`R'2vn.5i,-+ᴺdkZۋc@h[t^L`B fOUFB5=论эuZ^Ӯ5.-!jK{CUcsg'}Z~! ;|NV>Y:|k=; 9g([b Y7Xײpsa/(f^!:%GwT4joifrǦ#FsfY\ ,|&mYՓ>_G  OOaj\|YcuObgz33pH3P2%@4_gDGo|3>4SfDſ܂%|qrI"uk-.~عBD€h>sJʷS_f٪<4ͬqasD|C{S͕mtD}LEІʨ H׭m;?j-{$_g`{IKI:zV_{umZA6U;%yѷ 砚6W19i(#B56+0R"ck/rWe#w'57Ъ7yTO6!HtUԶuJ хRyk:^R+ Q* gFd׿Ik.z}ŞU= zK}K:(Ggg"?m*v1%ϋVلNhāN=2lhJv"VǶG鰻HL571/ ޵G ˗x}WY990o[7ÛGѩ|pX ? @Jy/2ޏ} 2rb6#A|u G[hM(ooHwKq:Bw˟&s2cU{OtMLjS>Iǒ9*F-m15w[:F;,>Ycٶ8.䒑vUc2ZȚ}p*J{x ZQ< z)Lz,<W=~!iy)1곥i|&8chC2K7тF䙚lyuYwΉ skfܬ<är:\lx$ΚWhH-}ƮR,Ʉ:?`j\Lν-wۊa#9f5:5jy%tI=np3$igS7X&NɮJ.8wX\N=2F 4C*@JY7Z\ȅdL1D +wTcշsLB$#: `D sonQUav$cqĆG_P(ҤT拯F-tQ-fM`bZ^MYYf 0eQ(99CJ`.A~ǩ8%F-HxX-FMiN6D8L.k 3ۙv{s,8L!D * 5;̂4GmX61-#>ĜdZV ]&H_ӟ_3 9VNno:N=dgRU3F]1kZ!e%ZMHP3ɐ,4'ya@~zʱx5+QtZop=6Wۢ>Μ>0t ЙVc]v i/@ q4T5GrXRR[;eha: vhR6@G.qCcU eQ?!ya6E2 lT Π'#8-Hhv4H-rPЍTC)a% '8q.jyCF&6#צg5+E9%0ƎptwUԲMP8ixX5׵F-/+59QV} Y[DvQ,Ctt: w7`yL>E!yY P}.zyRO Yo  uCQcvN7.BYr:\V4F-OGyXmTAtLd}`,g95>7ZawzhX#.c< -Wv[/j5?fVu˔l}{딩ya!y%vewj.U@Éz/='O!='%vSg{ Z;*6vGˎÌwHv|0Xd#6hi ! #bȈ4q۹abњfpbÚjmT۹/n;t j b`gh„W\LU?Kc`9f=JG R*$x .ϒ_M@'(b#`e&a1g]}09A"'~b!oO`cu :2Ckr:\ kԷnt9S}+\O?dHk +wG-?ZJ<#A+Io2Lt>,{xnvzyɐȌk&g; Dif pƳ'V.%R ֦Pij ٷomj?[i,R̼a Z7zuoxd/pZgVtBK1FFK>u, \|C`'_4F%aM ),Hwf'ɬ1̹ xnAb%v{k_d k܅˥*CB\,&.fo9` y+6&Y Lx+V#bu'ʋ+ƢC7P gİrdZͤ2f(;IsNǒyWOxB BB/C Tv؝ &IW* ^߭R>`Ǘ"A &I"9%$rFe1\ Ə$X͆'Œdc.7`wbԂ| kc(tn P(WH + @.Xm_EN~v#xQgklV1]Kv{`n}Zע V7_݆nr=ENgw((4Ds ~{ 9v|/d"G3#5+ZCKcy2t[] EYC5켹h^; ~:>q$$$wH-Nj8QZGkc{@L=p-dݥĭ`fY.Z_D1;\˿wx+nAz#g"l73M2lϋW}^9/5hz0 p $!SEA,dָs};+/˩::ڝ~z(|#{T&>&]:!s=*sIĭ+b{oq%@vg@Bο|2w/#DuUy7c/]njax&F]i)@P'JTi`C܂,n| &?>x3^zteAa7\;Ĥ??]f :k^($hͨhOHL/_Eo`W,z71|>OYVteO`X5ݱ@6ne.b 3$F}Y }כJ,HCWOȨ'u@E"-r utf-8&%n1<R>b=Sy^"n]O% 'U%Zw0$rά )L~jL{AK4T!I:)"bntRkJ͑0 ~b!RG r)>+ 2S9eb)Sgwy5:{^gjJ'ʇ8ˇ&nWpu- {MϋV>I#؜u2O>Neu5}wkj ;N |}n;I-u,v[n769] OMmzOPQJf\ $C`3HK 7Fvo {زv;m-QmyǪvoHŪEK%߹E 5gz{iT5) 'e;x=[RqL4,Xռ8&gM/yw]`翧Xps/os&%;$CEkcUGj8~+dIDATǀg[YbVey Of+=DzkgK1(^Q%띖IA]gXSWhS4PAKLiyfK_s#Ue1^+7"~okwv_"i >P!Hw֕88խKMo1CJ~$U9rfqL6R[FL=ʇ~kwnmoq&$rӳ:E0SxapDA Vu[ޣo̬;S c냉o-IoBhJ>~sq ^̤H3']!!lHdZ݂ x- HH2ZW.c1, sꎦ  @@IK0 I7)/sUe7H ~~$.$r|}] %?pǥ)7e"9D0 +`@NۄdhmZRg41 RgPY( 2W8Џ R)9 R4^B{EbP ̔3!ap${">qU]-WWkQS IENDB`torbrowser-launcher-0.3.2/share/torbrowser-launcher/000077500000000000000000000000001351446241500226415ustar00rootroot00000000000000torbrowser-launcher-0.3.2/share/torbrowser-launcher/mirrors.txt000066400000000000000000000022761351446241500251060ustar00rootroot00000000000000https://dist.torproject.org/ https://tor.crazyhaze.de/dist/ https://creep.im/tor/dist/ https://tor.ybti.net/dist/ https://tor.0x3d.lu/dist/ https://www.it-sicherheitschannel.de/dist/ https://mirror.freedif.org/TorProject/dist https://tor.secure.voyage/dist https://tor.127001.ovh/dist/ https://mirror.oldsql.cc/tor/dist/ https://mirror.torworld.org/dist/ https://tormirror.tb-itf-tor.de/dist/ https://tor.zilog.es/dist/ https://torproject.ph3x.at/dist/ https://www.torservers.net/mirrors/torproject.org/dist/ https://tor.myrl.net/dist/ https://tor.stalkr.net/dist/ https://tor-mirror.cyberguerrilla.org/dist/ https://mirror.velcommuta.de/tor/dist/ https://tor.eff.org/dist/ https://tor.void.gr/dist/ https://www.moparisthebest.com/tor/dist/ https://108.248.87.242/dist/ https://mirror.ntzk.de/torproject.org/dist/ https://www.eprci.com/tor/dist/ https://sela.io/mirrors/torproject.org/dist/ https://tor.ccc.de/dist/ https://tormirror.snydernet.net/dist/ https://tor.calyxinstitute.org/dist/ https://torproject.mirror.metalgamer.eu/dist/ https://nl.mirror.babylon.network/torproject/dist/ https://fr.mirror.babylon.network/torproject/dist/ https://cyberside.net.ee/sibul/dist/ https://tormirror.tb-itf-tor.de/dist/ torbrowser-launcher-0.3.2/share/torbrowser-launcher/tor-browser-developers.asc000066400000000000000000000322111351446241500277630ustar00rootroot00000000000000-----BEGIN PGP PUBLIC KEY BLOCK----- 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 /WhdDlMfhovcErVqjW6F59ZOjuqUq03zhLf7ikIAJVUZ+6O050R3xYzpKLPTNhdA EWGhnEdUCckLuQINBFSOsFYBEADB79YviDFjY6mwjFD0uw105uCRsNRfPIH92B1c Ehe3WX1HR0uH2+uX1bOAD2nymakK2pdKowyLCNqGYLnnduPyAxfSSGFl/ipLOVmx yT95OxpOvMA3BgZxjEqGirzkLXPy9/+wB54cZxb7bA/GsnbVHwTSAQYjcwF7H6T/ 1n/rRles/u1Pgk+8BN1AqLdhK2/1HeT1UqvBjB2UfiKOOV2w2RBwrZloLN5fs/M4 eC5xX9xz/lLgzZdjwpsQKpfllziNzWweuNDvuGOLCMbdPAt8Msyrhh+pCJUb1xr2 O5AviTX5/KDBtZJynju1n93Q87lCvULwhsTZts8jm7887ffpQr4yZ3aTRFBA5XvG 6N8Wo0AXsZughWCN5bmYxGyyjCNhWNFpd0dmxJgpNxvp5UJZnP/ubO6pmGUqP2Z7 4KFA01DIb1cqYE5MnSuPs6ELsneqhR23ilmj6+nmSI3TuSd7eb/tlmxYwKl1v/Pa x7/WlWmYli+w5LJqwYL8ViB64k3cKbQ3zWHhTpyAkJAh6lKFkNloK1g7rqF7PrdG zp2ujSRykjWZ9huJh2aovLVL9tiJpGGiFVQ5pKBnInWz79epw756FOpttn4vQiqK qBVTSsMi0c+7fVagjNmdk6qnOTxr8N6H9XIaiDldfAA/35NZB7XynJ/S/QPV/m17 hVIPnQARAQABiQREBBgBCgAPAhsCBQJV3aJrBQkFEVkQAinBXSAEGQEKAAYFAlSO sFYACgkQLhrGjtQIFOCSoxAAl61KCTOIrJBf7UQnOu25f0FlcuEQ0JVYXAn51AJ7 iK++n9xI7mKqw+nPEGnG0xc4IE8LbWF8dPTH9wN/PE/42R1f/R5Dxt3MaYKTZqv2 IkIcQlb3bx6PyBpKUvVDLeH+4RY7C+3ZVtee8rPDkPHIEUkNAPxRHjL8xOrp4u3G GeJXy5K0vPeqNJWsov7goOwSkYc+OGvZWFqUPnewRQvq5jBJO54VoFHi42/qC9tj LFbp20ROHJRCmL8k+tweIprZsybHRokDyv/scwnMGKrUTiPa+3To0hyiOVNLNT/z 7122Yqc8oTRcUzy/HzkVvAyUlunYXdOAfoqc+GTBDJMsDTllPMOhHr1bbOw5OTL7 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 =/faz -----END PGP PUBLIC KEY BLOCK----- torbrowser-launcher-0.3.2/share/torbrowser-launcher/version000066400000000000000000000000061351446241500242450ustar00rootroot000000000000000.3.2 torbrowser-launcher-0.3.2/stdeb.cfg000066400000000000000000000003621351446241500173130ustar00rootroot00000000000000[DEFAULT] Package3: torbrowser-launcher Depends3: python3-pyqt5, python3-gpg, python3-requests, python3-socks, gnupg2 Build-Depends: dh-python, python3-pyqt5, python3-gpg, python3-requests, python3-socks, gnupg2 Recommends: tor Suite: bionic torbrowser-launcher-0.3.2/torbrowser-launcher000077500000000000000000000023251351446241500214670ustar00rootroot00000000000000#!/usr/bin/env python3 """ Tor Browser Launcher https://github.com/micahflee/torbrowser-launcher/ Copyright (c) 2013-2017 Micah Lee Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ import torbrowser_launcher torbrowser_launcher.main() torbrowser-launcher-0.3.2/torbrowser_launcher.pot000066400000000000000000000102721351446241500223470ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-23 15:47-0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: __init__.py:65 launcher.py:470 msgid "Tor Browser Launcher" msgstr "" #: __init__.py:66 msgid "By Micah Lee, licensed under MIT" msgstr "" #: __init__.py:67 #, python-brace-format msgid "version {0}" msgstr "" #: common.py:100 #, python-brace-format msgid "Error creating {0}" msgstr "" #: common.py:102 common.py:180 #, python-brace-format msgid "{0} is not writable" msgstr "" #: common.py:177 #, python-brace-format msgid "Cannot create directory {0}" msgstr "" #: common.py:187 msgid "Creating GnuPG homedir" msgstr "" #: common.py:254 #, python-format msgid "Could not import key with fingerprint: %s." msgstr "" #: common.py:259 msgid "Not all keys were imported successfully!" msgstr "" #: launcher.py:83 msgid "Downloading Tor Browser for the first time." msgstr "" #: launcher.py:85 msgid "" "Your version of Tor Browser is out-of-date. Downloading the newest version." msgstr "" #: launcher.py:100 msgid "Downloading over Tor" msgstr "" #: launcher.py:111 msgid "Tor Browser" msgstr "" #: launcher.py:128 msgid "Start" msgstr "" #: launcher.py:174 msgid "Yes" msgstr "" #: launcher.py:178 msgid "Exit" msgstr "" #: launcher.py:192 settings.py:136 msgid "Cancel" msgstr "" #: launcher.py:231 launcher.py:245 launcher.py:249 launcher.py:279 #: launcher.py:281 msgid "Downloading" msgstr "" #: launcher.py:238 msgid "Latest version: {}" msgstr "" #: launcher.py:241 msgid "Error detecting Tor Browser version." msgstr "" #: launcher.py:256 launcher.py:357 msgid "Verifying Signature" msgstr "" #: launcher.py:260 msgid "Extracting" msgstr "" #: launcher.py:264 msgid "Running" msgstr "" #: launcher.py:268 msgid "Starting download over again" msgstr "" #: launcher.py:279 launcher.py:295 msgid "(over Tor)" msgstr "" #: launcher.py:293 msgid "Downloaded" msgstr "" #: launcher.py:393 msgid "Installing" msgstr "" #: launcher.py:401 #, python-brace-format msgid "Tor Browser Launcher doesn't understand the file format of {0}" msgstr "" #: launcher.py:427 msgid "" "The version of Tor Browser you have installed is earlier than it should be, " "which could be a sign of an attack!" msgstr "" #: launcher.py:446 msgid "Downloading Tor Browser over again." msgstr "" #: launcher.py:516 launcher.py:525 launcher.py:533 msgid "Download Error:" msgstr "" #: launcher.py:517 msgid "You are currently using a non-default mirror" msgstr "" #: launcher.py:518 msgid "Would you like to switch back to the default?" msgstr "" #: launcher.py:527 msgid "Would you like to try the English version of Tor Browser instead?" msgstr "" #: launcher.py:548 #, python-brace-format msgid "" "Invalid SSL certificate for:\n" "{0}\n" "\n" "You may be under attack." msgstr "" #: launcher.py:550 msgid "Try the download again using Tor?" msgstr "" #: launcher.py:559 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Trying to download over Tor. Are you sure Tor is configured correctly and " "running?" msgstr "" #: launcher.py:563 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Are you connected to the internet?" msgstr "" #: settings.py:46 msgid "Tor Browser Launcher Settings" msgstr "" #: settings.py:50 msgid "Download over system Tor" msgstr "" #: settings.py:57 msgid "Force downloading English version of Tor Browser" msgstr "" #: settings.py:66 msgid "Tor server" msgstr "" #: settings.py:82 msgid "Status: Installed" msgstr "" #: settings.py:84 msgid "Status: Not Installed" msgstr "" #: settings.py:87 msgid "Install Tor Browser" msgstr "" #: settings.py:92 msgid "Reinstall Tor Browser" msgstr "" #: settings.py:115 msgid "Mirror" msgstr "" #: settings.py:131 msgid "Save && Exit" msgstr "" torbrowser-launcher-0.3.2/torbrowser_launcher/000077500000000000000000000000001351446241500216215ustar00rootroot00000000000000torbrowser-launcher-0.3.2/torbrowser_launcher/__init__.py000066400000000000000000000057071351446241500237430ustar00rootroot00000000000000""" Tor Browser Launcher https://github.com/micahflee/torbrowser-launcher/ Copyright (c) 2013-2017 Micah Lee Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ import os import sys import argparse import signal from PyQt5 import QtCore, QtWidgets from .common import Common, SHARE from .settings import Settings from .launcher import Launcher class Application(QtWidgets.QApplication): """ Qt's QApplication class. It has been overridden to support threads. """ def __init__(self): self.setAttribute(QtCore.Qt.AA_X11InitThreads, True) QtWidgets.QApplication.__init__(self, sys.argv) self.installEventFilter(self) def main(): # Parse arguments parser = argparse.ArgumentParser() parser.add_argument('--settings', action='store_true', dest='settings', help='Open Tor Browser Launcher settings') parser.add_argument('url', nargs='*', help='URL to load') args = parser.parse_args() settings = bool(args.settings) url_list = args.url # Load the version and print the banner with open(os.path.join(SHARE, 'version')) as buf: tor_browser_launcher_version = buf.read().strip() print(_('Tor Browser Launcher')) print(_('By Micah Lee, licensed under MIT')) print(_('version {0}').format(tor_browser_launcher_version)) print('https://github.com/micahflee/torbrowser-launcher') common = Common(tor_browser_launcher_version) app = Application() # Open the window gui = None if settings: # Settings mode gui = Settings(common, app) else: # Launcher mode gui = Launcher(common, app, url_list) # Center the window desktop = app.desktop() window_size = gui.size() gui.move( (desktop.width() - window_size.width()) / 2, (desktop.height() - window_size.height()) / 2 ) gui.show() # Allow ctrl-c to work signal.signal(signal.SIGINT, signal.SIG_DFL) sys.exit(app.exec_()) if __name__ == "__main__": main() torbrowser-launcher-0.3.2/torbrowser_launcher/common.py000066400000000000000000000313031351446241500234630ustar00rootroot00000000000000""" Tor Browser Launcher https://github.com/micahflee/torbrowser-launcher/ Copyright (c) 2013-2017 Micah Lee Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ import os import sys import platform import subprocess import locale import pickle import json import re import gettext import gpg SHARE = os.getenv('TBL_SHARE', sys.prefix + '/share') + '/torbrowser-launcher' gettext.install('torbrowser-launcher') # We're looking for output which: # # 1. The first portion must be `[GNUPG:] IMPORT_OK` # 2. The second must be an integer between [0, 15], inclusive # 3. The third must be an uppercased hex-encoded 160-bit fingerprint gnupg_import_ok_pattern = re.compile( b"(\[GNUPG\:\]) (IMPORT_OK) ([0-9]|[1]?[0-5]) ([A-F0-9]{40})") class Common(object): def __init__(self, tbl_version): self.tbl_version = tbl_version # initialize the app self.default_mirror = 'https://dist.torproject.org/' self.discover_arch_lang() self.build_paths() for d in self.paths['dirs']: self.mkdir(self.paths['dirs'][d]) self.load_mirrors() self.load_settings() self.mkdir(self.paths['download_dir']) self.mkdir(self.paths['tbb']['dir']) self.init_gnupg() # discover the architecture and language def discover_arch_lang(self): # figure out the architecture self.architecture = 'x86_64' if '64' in platform.architecture()[0] else 'i686' # figure out the language available_languages = ['ar', 'ca', 'da', 'de', 'en-US', 'es-ES', 'fa', 'fr', 'ga-IE', 'he', 'id', 'is', 'it', 'ja', 'ko', 'nb-NO', 'nl', 'pl', 'pt-BR', 'ru', 'sv-SE', 'tr', 'vi', 'zh-CN', 'zh-TW'] default_locale = locale.getlocale()[0] if default_locale is None: self.language = 'en-US' else: self.language = default_locale.replace('_', '-') if self.language not in available_languages: self.language = self.language.split('-')[0] if self.language not in available_languages: for l in available_languages: if l[0:2] == self.language: self.language = l # if language isn't available, default to english if self.language not in available_languages: self.language = 'en-US' # build all relevant paths def build_paths(self, tbb_version=None): homedir = os.getenv('HOME') if not homedir: homedir = '/tmp/.torbrowser-'+os.getenv('USER') if not os.path.exists(homedir): try: os.mkdir(homedir, 0o700) except: self.set_gui('error', _("Error creating {0}").format(homedir), [], False) if not os.access(homedir, os.W_OK): self.set_gui('error', _("{0} is not writable").format(homedir), [], False) tbb_config = '{0}/.config/torbrowser'.format(homedir) tbb_cache = '{0}/.cache/torbrowser'.format(homedir) tbb_local = '{0}/.local/share/torbrowser'.format(homedir) old_tbb_data = '{0}/.torbrowser'.format(homedir) if tbb_version: # tarball filename if self.architecture == 'x86_64': arch = 'linux64' else: arch = 'linux32' if hasattr(self, 'settings') and self.settings['force_en-US']: language = 'en-US' else: language = self.language tarball_filename = 'tor-browser-' + arch + '-' + tbb_version + '_' + language + '.tar.xz' # tarball self.paths['tarball_url'] = '{0}torbrowser/' + tbb_version + '/' + tarball_filename self.paths['tarball_file'] = tbb_cache + '/download/' + tarball_filename self.paths['tarball_filename'] = tarball_filename # sig self.paths['sig_url'] = '{0}torbrowser/' + tbb_version + '/' + tarball_filename + '.asc' self.paths['sig_file'] = tbb_cache + '/download/' + tarball_filename + '.asc' self.paths['sig_filename'] = tarball_filename + '.asc' else: self.paths = { 'dirs': { 'config': tbb_config, 'cache': tbb_cache, 'local': tbb_local, }, 'old_data_dir': old_tbb_data, 'tbl_bin': sys.argv[0], 'icon_file': os.path.join(os.path.dirname(SHARE), 'pixmaps/torbrowser.png'), 'torproject_pem': os.path.join(SHARE, 'torproject.pem'), 'signing_keys': { 'tor_browser_developers': os.path.join(SHARE, 'tor-browser-developers.asc') }, 'mirrors_txt': [os.path.join(SHARE, 'mirrors.txt'), tbb_config + '/mirrors.txt'], 'download_dir': tbb_cache + '/download', 'gnupg_homedir': tbb_local + '/gnupg_homedir', 'settings_file': tbb_config + '/settings.json', 'settings_file_pickle': tbb_config + '/settings', 'version_check_url': 'https://aus1.torproject.org/torbrowser/update_3/release/Linux_x86_64-gcc3/x/en-US', 'version_check_file': tbb_cache + '/download/release.xml', 'tbb': { 'changelog': tbb_local + '/tbb/' + self.architecture + '/tor-browser_' + self.language + '/Browser/TorBrowser/Docs/ChangeLog.txt', 'dir': tbb_local + '/tbb/' + self.architecture, 'dir_tbb': tbb_local + '/tbb/' + self.architecture + '/tor-browser_' + self.language, 'start': tbb_local + '/tbb/' + self.architecture + '/tor-browser_' + self.language + '/start-tor-browser.desktop' }, } # Add the expected fingerprint for imported keys: self.fingerprints = { 'tor_browser_developers': 'EF6E286DDA85EA2A4BA7DE684E2C6E8793298290' } # create a directory @staticmethod def mkdir(path): try: if not os.path.exists(path): os.makedirs(path, 0o700) return True except: print(_("Cannot create directory {0}").format(path)) return False if not os.access(path, os.W_OK): print(_("{0} is not writable").format(path)) return False return True # if gnupg_homedir isn't set up, set it up def init_gnupg(self): if not os.path.exists(self.paths['gnupg_homedir']): print(_('Creating GnuPG homedir'), self.paths['gnupg_homedir']) self.mkdir(self.paths['gnupg_homedir']) self.import_keys() def refresh_keyring(self, fingerprint=None): if fingerprint is not None: print('Refreshing local keyring... Missing key: ' + fingerprint) else: print('Refreshing local keyring...') p = subprocess.Popen(['/usr/bin/gpg2', '--status-fd', '2', '--homedir', self.paths['gnupg_homedir'], '--keyserver', 'hkps://keys.openpgp.org', '--refresh-keys'], stderr=subprocess.PIPE) p.wait() for output in p.stderr.readlines(): match = gnupg_import_ok_pattern.match(output) if match and match.group(2) == 'IMPORT_OK': fingerprint = str(match.group(4)) if match.group(3) == '0': print('Keyring refreshed successfully...') print(' No key updates for key: ' + fingerprint) elif match.group(3) == '4': print('Keyring refreshed successfully...') print(' New signatures for key: ' + fingerprint) else: print('Keyring refreshed successfully...') def import_key_and_check_status(self, key): """Import a GnuPG key and check that the operation was successful. :param str key: A string specifying the key's filepath from ``Common.paths`` :rtype: bool :returns: ``True`` if the key is now within the keyring (or was previously and hasn't changed). ``False`` otherwise. """ with gpg.Context() as c: c.set_engine_info(gpg.constants.protocol.OpenPGP, home_dir=self.paths['gnupg_homedir']) impkey = self.paths['signing_keys'][key] try: c.op_import(gpg.Data(file=impkey)) except: return False else: result = c.op_import_result() if result and self.fingerprints[key] in result.imports[0].fpr: return True else: return False # import gpg keys def import_keys(self): """Import all GnuPG keys. :rtype: bool :returns: ``True`` if all keys were successfully imported; ``False`` otherwise. """ keys = ['tor_browser_developers', ] all_imports_succeeded = True for key in keys: imported = self.import_key_and_check_status(key) if not imported: print(_('Could not import key with fingerprint: %s.' % self.fingerprints[key])) all_imports_succeeded = False if not all_imports_succeeded: print(_('Not all keys were imported successfully!')) return all_imports_succeeded # load mirrors def load_mirrors(self): self.mirrors = [] for srcfile in self.paths['mirrors_txt']: if not os.path.exists(srcfile): continue for mirror in open(srcfile, 'r').readlines(): if mirror.strip() not in self.mirrors: self.mirrors.append(mirror.strip()) # load settings def load_settings(self): default_settings = { 'tbl_version': self.tbl_version, 'installed': False, 'download_over_tor': False, 'tor_socks_address': '127.0.0.1:9050', 'mirror': self.default_mirror, 'force_en-US': False, } if os.path.isfile(self.paths['settings_file']): settings = json.load(open(self.paths['settings_file'])) resave = False # detect installed settings['installed'] = os.path.isfile(self.paths['tbb']['start']) # make sure settings file is up-to-date for setting in default_settings: if setting not in settings: settings[setting] = default_settings[setting] resave = True # make sure tor_socks_address doesn't start with 'tcp:' if settings['tor_socks_address'].startswith('tcp:'): settings['tor_socks_address'] = settings['tor_socks_address'][4:] resave = True # make sure the version is current if settings['tbl_version'] != self.tbl_version: settings['tbl_version'] = self.tbl_version resave = True self.settings = settings if resave: self.save_settings() # if settings file is still using old pickle format, convert to json elif os.path.isfile(self.paths['settings_file_pickle']): self.settings = pickle.load(open(self.paths['settings_file_pickle'])) self.save_settings() os.remove(self.paths['settings_file_pickle']) self.load_settings() else: self.settings = default_settings self.save_settings() # save settings def save_settings(self): json.dump(self.settings, open(self.paths['settings_file'], 'w')) return True torbrowser-launcher-0.3.2/torbrowser_launcher/launcher.py000066400000000000000000000553401351446241500240030ustar00rootroot00000000000000""" Tor Browser Launcher https://github.com/micahflee/torbrowser-launcher/ Copyright (c) 2013-2017 Micah Lee Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ import os import sys import subprocess import time import tarfile import lzma import re import requests import gpg import shutil import xml.etree.ElementTree as ET from PyQt5 import QtCore, QtWidgets, QtGui class TryStableException(Exception): pass class TryDefaultMirrorException(Exception): pass class TryForcingEnglishException(Exception): pass class DownloadErrorException(Exception): pass class Launcher(QtWidgets.QMainWindow): """ Launcher window. """ def __init__(self, common, app, url_list): super(Launcher, self).__init__() self.common = common self.app = app self.url_list = url_list self.force_redownload = False # This is the current version of Tor Browser, which should get updated with every release self.min_version = '7.5.2' # Init launcher self.set_state(None, '', []) self.launch_gui = True # If Tor Browser is not installed, detect latest version, download, and install if not self.common.settings['installed'] or not self.check_min_version(): # Different message if downloading for the first time, or because your installed version is too low download_message = "" if not self.common.settings['installed']: download_message = _("Downloading Tor Browser for the first time.") elif not self.check_min_version(): download_message = _("Your version of Tor Browser is out-of-date. " "Downloading the newest version.") # Download and install print(download_message) self.set_state('task', download_message, ['download_version_check', 'set_version', 'download_sig', 'download_tarball', 'verify', 'extract', 'run']) if self.common.settings['download_over_tor']: print(_('Downloading over Tor')) else: # Tor Browser is already installed, so run launch_message = "Launching Tor Browser." print(launch_message) self.set_state('task', launch_message, ['run']) # Build the rest of the UI # Set up the window self.setWindowTitle(_("Tor Browser")) self.setWindowIcon(QtGui.QIcon(self.common.paths['icon_file'])) # Label self.label = QtWidgets.QLabel() # Progress bar self.progress_bar = QtWidgets.QProgressBar() self.progress_bar.setTextVisible(True) self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(0) self.progress_bar.setValue(0) # Buttons self.yes_button = QtWidgets.QPushButton() self.yes_button.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_DialogApplyButton)) self.yes_button.clicked.connect(self.yes_clicked) self.start_button = QtWidgets.QPushButton(_('Start')) self.start_button.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_DialogApplyButton)) self.start_button.clicked.connect(self.start) self.cancel_button = QtWidgets.QPushButton() self.cancel_button.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_DialogCancelButton)) self.cancel_button.clicked.connect(self.close) buttons_layout = QtWidgets.QHBoxLayout() buttons_layout.addStretch() buttons_layout.addWidget(self.yes_button) buttons_layout.addWidget(self.start_button) buttons_layout.addWidget(self.cancel_button) buttons_layout.addStretch() # Layout layout = QtWidgets.QVBoxLayout() layout.addWidget(self.label) layout.addWidget(self.progress_bar) layout.addLayout(buttons_layout) central_widget = QtWidgets.QWidget() central_widget.setLayout(layout) self.setCentralWidget(central_widget) self.update() # Set the current state of Tor Browser Launcher def set_state(self, gui, message, tasks, autostart=True): self.gui = gui self.gui_message = message self.gui_tasks = tasks self.gui_task_i = 0 self.gui_autostart = autostart # Show and hide parts of the UI based on the current state def update(self): # Hide widgets self.progress_bar.hide() self.yes_button.hide() self.start_button.hide() if 'error' in self.gui: # Label self.label.setText(self.gui_message) # Yes button if self.gui != 'error': self.yes_button.setText(_('Yes')) self.yes_button.show() # Exit button self.cancel_button.setText(_('Exit')) elif self.gui == 'task': # Label self.label.setText(self.gui_message) # Progress bar self.progress_bar.show() # Start button if not self.gui_autostart: self.start_button.show() # Cancel button self.cancel_button.setText(_('Cancel')) # Resize the window self.adjustSize() if self.gui_autostart: self.start(None) # Yes button clicked, based on the state decide what to do def yes_clicked(self): if self.gui == 'error_try_stable': self.try_stable() elif self.gui == 'error_try_default_mirror': self.try_default_mirror() elif self.gui == 'error_try_forcing_english': self.try_forcing_english() elif self.gui == 'error_try_tor': self.try_tor() # Start button clicked, begin tasks def start(self, widget, data=None): # Hide the start button self.start_button.hide() # Start running tasks self.run_task() # Run the next task in the task list def run_task(self): if self.gui_task_i >= len(self.gui_tasks): self.close() return task = self.gui_tasks[self.gui_task_i] # Get ready for the next task self.gui_task_i += 1 if task == 'download_version_check': print(_('Downloading'), self.common.paths['version_check_url']) self.download('version check', self.common.paths['version_check_url'], self.common.paths['version_check_file']) if task == 'set_version': version = self.get_stable_version() if version: self.common.build_paths(self.get_stable_version()) print(_('Latest version: {}').format(version)) self.run_task() else: self.set_state('error', _("Error detecting Tor Browser version."), [], False) self.update() elif task == 'download_sig': print(_('Downloading'), self.common.paths['sig_url'].format(self.common.settings['mirror'])) self.download('signature', self.common.paths['sig_url'], self.common.paths['sig_file']) elif task == 'download_tarball': print(_('Downloading'), self.common.paths['tarball_url'].format(self.common.settings['mirror'])) if not self.force_redownload and os.path.exists(self.common.paths['tarball_file']): self.run_task() else: self.download('tarball', self.common.paths['tarball_url'], self.common.paths['tarball_file']) elif task == 'verify': print(_('Verifying Signature')) self.verify() elif task == 'extract': print(_('Extracting'), self.common.paths['tarball_filename']) self.extract() elif task == 'run': print(_('Running'), self.common.paths['tbb']['start']) self.run() elif task == 'start_over': print(_('Starting download over again')) self.start_over() def download(self, name, url, path): # Download from the selected mirror mirror_url = url.format(self.common.settings['mirror']).encode() # Initialize the progress bar self.progress_bar.setValue(0) self.progress_bar.setMaximum(100) if self.common.settings['download_over_tor']: self.progress_bar.setFormat(_('Downloading') + ' {0} '.format(name) + _('(over Tor)') + ', %p%') else: self.progress_bar.setFormat(_('Downloading') + ' {0}, %p%'.format(name)) def progress_update(total_bytes, bytes_so_far): percent = float(bytes_so_far) / float(total_bytes) amount = float(bytes_so_far) units = "bytes" for (size, unit) in [(1024 * 1024, "MiB"), (1024, "KiB")]: if amount > size: units = unit amount /= float(size) break message = _('Downloaded') + (' %2.1f%% (%2.1f %s)' % ((percent * 100.0), amount, units)) if self.common.settings['download_over_tor']: message += ' ' + _('(over Tor)') self.progress_bar.setMaximum(total_bytes) self.progress_bar.setValue(bytes_so_far) self.progress_bar.setFormat(message) def download_complete(): # Download complete, next task self.run_task() def download_error(gui, message): print(message) self.set_state(gui, message, [], False) self.update() t = DownloadThread(self.common, mirror_url, path) t.progress_update.connect(progress_update) t.download_complete.connect(download_complete) t.download_error.connect(download_error) t.start() time.sleep(0.2) def try_default_mirror(self): # change mirror to default and relaunch TBL self.common.settings['mirror'] = self.common.default_mirror self.common.save_settings() subprocess.Popen([self.common.paths['tbl_bin']]) self.close() def try_forcing_english(self): # change force english to true and relaunch TBL self.common.settings['force_en-US'] = True self.common.save_settings() subprocess.Popen([self.common.paths['tbl_bin']]) self.close() def try_tor(self): # set download_over_tor to true and relaunch TBL self.common.settings['download_over_tor'] = True self.common.save_settings() subprocess.Popen([self.common.paths['tbl_bin']]) self.close() def get_stable_version(self): tree = ET.parse(self.common.paths['version_check_file']) for up in tree.getroot(): if up.tag == 'update' and up.attrib['appVersion']: version = str(up.attrib['appVersion']) # make sure the version does not contain directory traversal attempts # e.g. "5.5.3", "6.0a", "6.0a-hardened" are valid but "../../../../.." is invalid if not re.match(r'^[a-z0-9\.\-]+$', version): return None return version return None def verify(self): self.progress_bar.setValue(0) self.progress_bar.setMaximum(0) self.progress_bar.show() self.label.setText(_('Verifying Signature')) def success(): self.run_task() def error(message): # Make backup of tarball and sig backup_tarball_filename = self.common.paths['tarball_file'] + '.verification_failed' backup_sig_filename = self.common.paths['sig_file'] + '.verification_failed' shutil.copyfile(self.common.paths['tarball_file'], backup_tarball_filename) shutil.copyfile(self.common.paths['sig_file'], backup_sig_filename) sigerror = 'SIGNATURE VERIFICATION FAILED!\n\n' \ 'Error Code: {0}\n\n' \ 'You might be under attack, there might be a network problem, or you may be missing a ' \ 'recently added Tor Browser verification key.\n\n' \ 'A copy of the Tor Browser files you downloaded have been saved here:\n' \ '{1}\n{2}\n\n' \ 'Click Start to refresh the keyring and try again. If the message persists report the above ' \ 'error code here:\nhttps://github.com/micahflee/torbrowser-launcher/issues' sigerror = sigerror.format(message, backup_tarball_filename, backup_sig_filename) self.set_state('task', sigerror, ['start_over'], False) self.update() t = VerifyThread(self.common) t.error.connect(error) t.success.connect(success) t.start() time.sleep(0.2) def extract(self): self.progress_bar.setValue(0) self.progress_bar.setMaximum(0) self.progress_bar.show() self.label.setText(_('Installing')) def success(): self.run_task() def error(message): self.set_state( 'task', _("Tor Browser Launcher doesn't understand the file format of {0}".format(self.common.paths['tarball_file'])), ['start_over'], False ) self.update() t = ExtractThread(self.common) t.error.connect(error) t.success.connect(success) t.start() time.sleep(0.2) def check_min_version(self): installed_version = None for line in open(self.common.paths['tbb']['changelog'],'rb').readlines(): if line.startswith(b'Tor Browser '): installed_version = line.split()[2].decode() break if self.min_version <= installed_version: return True return False def run(self): # Don't run if it isn't at least the minimum version if not self.check_min_version(): message = _("The version of Tor Browser you have installed is earlier than it should be, which could be a " "sign of an attack!") print(message) Alert(self.common, message) return # Run Tor Browser subprocess.call([self.common.paths['tbb']['start']], cwd=self.common.paths['tbb']['dir_tbb']) sys.exit(0) # Start over and download TBB again def start_over(self): self.force_redownload = True # Overwrite any existing file self.label.setText(_("Downloading Tor Browser over again.")) self.gui_tasks = ['download_tarball', 'verify', 'extract', 'run'] self.gui_task_i = 0 self.start(None) def closeEvent(self, event): # Clear the download cache try: os.remove(self.common.paths['version_check_file']) os.remove(self.common.paths['sig_file']) os.remove(self.common.paths['tarball_file']) except: pass super(Launcher, self).closeEvent(event) class Alert(QtWidgets.QMessageBox): """ An alert box dialog. """ def __init__(self, common, message, icon=QtWidgets.QMessageBox.NoIcon, buttons=QtWidgets.QMessageBox.Ok, autostart=True): super(Alert, self).__init__(None) self.setWindowTitle(_("Tor Browser Launcher")) self.setWindowIcon(QtGui.QIcon(common.paths['icon_file'])) self.setText(message) self.setIcon(icon) self.setStandardButtons(buttons) if autostart: self.exec_() class DownloadThread(QtCore.QThread): """ Download a file in a separate thread. """ progress_update = QtCore.pyqtSignal(int, int) download_complete = QtCore.pyqtSignal() download_error = QtCore.pyqtSignal(str, str) def __init__(self, common, url, path): super(DownloadThread, self).__init__() self.common = common self.url = url self.path = path # Use tor socks5 proxy, if enabled if self.common.settings['download_over_tor']: socks5_address = 'socks5://{}'.format(self.common.settings['tor_socks_address']) self.proxies = { 'https': socks5_address, 'http': socks5_address } else: self.proxies = None def run(self): with open(self.path, "wb") as f: try: # Start the request r = requests.get(self.url, headers={'User-Agent': 'torbrowser-launcher'}, stream=True, proxies=self.proxies) # If status code isn't 200, something went wrong if r.status_code != 200: # Should we use the default mirror? if self.common.settings['mirror'] != self.common.default_mirror: message = (_("Download Error:") + " {0}\n\n" + _("You are currently using a non-default mirror") + ":\n{1}\n\n" + _("Would you like to switch back to the default?")).format( r.status_code, self.common.settings['mirror'] ) self.download_error.emit('error_try_default_mirror', message) # Should we switch to English? elif self.common.language != 'en-US' and not self.common.settings['force_en-US']: message = (_("Download Error:") + " {0}\n\n" + _("Would you like to try the English version of Tor Browser instead?")).format( r.status_code ) self.download_error.emit('error_try_forcing_english', message) else: message = (_("Download Error:") + " {0}").format(r.status_code) self.download_error.emit('error', message) r.close() return # Start streaming the download total_bytes = int(r.headers.get('content-length')) bytes_so_far = 0 for data in r.iter_content(chunk_size=4096): bytes_so_far += len(data) f.write(data) self.progress_update.emit(total_bytes, bytes_so_far) except requests.exceptions.SSLError: message = _('Invalid SSL certificate for:\n{0}\n\nYou may be under attack.').format(self.url.decode()) if not self.common.settings['download_over_tor']: message += "\n\n" + _('Try the download again using Tor?') self.download_error.emit('error_try_tor', message) else: self.download_error.emit('error', message) return except requests.exceptions.ConnectionError: # Connection error if self.common.settings['download_over_tor']: message = _("Error starting download:\n\n{0}\n\nTrying to download over Tor. " "Are you sure Tor is configured correctly and running?").format(self.url.decode()) self.download_error.emit('error', message) else: message = _("Error starting download:\n\n{0}\n\nAre you connected to the internet?").format( self.url.decode() ) self.download_error.emit('error', message) return self.download_complete.emit() class VerifyThread(QtCore.QThread): """ Verify the signature in a separate thread """ success = QtCore.pyqtSignal() error = QtCore.pyqtSignal(str) def __init__(self, common): super(VerifyThread, self).__init__() self.common = common def run(self): def verify(second_try=False): with gpg.Context() as c: c.set_engine_info(gpg.constants.protocol.OpenPGP, home_dir=self.common.paths['gnupg_homedir']) sig = gpg.Data(file=self.common.paths['sig_file']) signed = gpg.Data(file=self.common.paths['tarball_file']) try: c.verify(signature=sig, signed_data=signed) except gpg.errors.BadSignatures as e: if second_try: self.error.emit(str(e)) else: raise Exception else: self.success.emit() try: # Try verifying verify() except: # If it fails, refresh the keyring and try again self.common.refresh_keyring() verify(True) class ExtractThread(QtCore.QThread): """ Extract the tarball in a separate thread """ success = QtCore.pyqtSignal() error = QtCore.pyqtSignal() def __init__(self, common): super(ExtractThread, self).__init__() self.common = common def run(self): extracted = False try: if self.common.paths['tarball_file'][-2:] == 'xz': # if tarball is .tar.xz xz = lzma.LZMAFile(self.common.paths['tarball_file']) tf = tarfile.open(fileobj=xz) tf.extractall(self.common.paths['tbb']['dir']) extracted = True else: # if tarball is .tar.gz if tarfile.is_tarfile(self.common.paths['tarball_file']): tf = tarfile.open(self.common.paths['tarball_file']) tf.extractall(self.common.paths['tbb']['dir']) extracted = True except: pass if extracted: self.success.emit() else: self.error.emit() torbrowser-launcher-0.3.2/torbrowser_launcher/settings.py000066400000000000000000000152301351446241500240340ustar00rootroot00000000000000""" Tor Browser Launcher https://github.com/micahflee/torbrowser-launcher/ Copyright (c) 2013-2017 Micah Lee Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ import subprocess import shutil from PyQt5 import QtCore, QtWidgets, QtGui class Settings(QtWidgets.QMainWindow): """ Settings window. """ def __init__(self, common, app): super(Settings, self).__init__() self.common = common self.app = app # Set up the window self.setWindowTitle(_("Tor Browser Launcher Settings")) self.setWindowIcon(QtGui.QIcon(self.common.paths['icon_file'])) # Download over system tor self.tor_download_checkbox = QtWidgets.QCheckBox(_("Download over system Tor")) if self.common.settings['download_over_tor']: self.tor_download_checkbox.setCheckState(QtCore.Qt.Checked) else: self.tor_download_checkbox.setCheckState(QtCore.Qt.Unchecked) # Force en-US, only display if language isn't already en-US self.force_en_checkbox = QtWidgets.QCheckBox(_("Force downloading English version of Tor Browser")) if self.common.settings['force_en-US']: self.force_en_checkbox.setCheckState(QtCore.Qt.Checked) else: self.force_en_checkbox.setCheckState(QtCore.Qt.Unchecked) if self.common.language == 'en-US': self.force_en_checkbox.hide() # Tor SOCKS address tor_addr_label = QtWidgets.QLabel(_('Tor server')) self.tor_addr = QtWidgets.QLineEdit() self.tor_addr.setText(self.common.settings['tor_socks_address']) tor_addr_layout = QtWidgets.QHBoxLayout() tor_addr_layout.addWidget(tor_addr_label) tor_addr_layout.addWidget(self.tor_addr) # Settings layout settings_layout = QtWidgets.QVBoxLayout() settings_layout.addWidget(self.tor_download_checkbox) settings_layout.addWidget(self.force_en_checkbox) settings_layout.addLayout(tor_addr_layout) # Status status_label = QtWidgets.QLabel() if(self.common.settings['installed']): status_label.setText(_('Status: Installed')) else: status_label.setText(_('Status: Not Installed')) # Install button install_button = QtWidgets.QPushButton(_("Install Tor Browser")) install_button.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_DialogApplyButton)) install_button.clicked.connect(self.install) # Reinstall buttons reinstall_button = QtWidgets.QPushButton(_("Reinstall Tor Browser")) reinstall_button.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_DialogApplyButton)) reinstall_button.clicked.connect(self.reinstall) if(self.common.settings['installed']): install_button.hide() reinstall_button.show() else: install_button.show() reinstall_button.hide() # Status layout status_layout = QtWidgets.QVBoxLayout() status_layout.addWidget(status_label) status_layout.addWidget(install_button) status_layout.addWidget(reinstall_button) # Top layout top_layout = QtWidgets.QHBoxLayout() top_layout.addLayout(settings_layout) top_layout.addLayout(status_layout) # Mirror mirror_label = QtWidgets.QLabel(_('Mirror')) self.mirror = QtWidgets.QComboBox() for mirror in self.common.mirrors: self.mirror.addItem(mirror) if self.common.settings['mirror'] in self.common.mirrors: self.mirror.setCurrentIndex(self.mirror.findText(self.common.settings['mirror'])) else: self.mirror.setCurrentIndex(0) mirror_layout = QtWidgets.QHBoxLayout() mirror_layout.addWidget(mirror_label) mirror_layout.addWidget(self.mirror) # Save & Exit button self.save_exit_button = QtWidgets.QPushButton(_("Save && Exit")) self.save_exit_button.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_DialogApplyButton)) self.save_exit_button.clicked.connect(self.save_exit) # Cancel button self.cancel_button = QtWidgets.QPushButton(_("Cancel")) self.cancel_button.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_DialogCancelButton)) self.cancel_button.clicked.connect(self.close) # Buttons layout buttons_layout = QtWidgets.QHBoxLayout() buttons_layout.addWidget(self.save_exit_button) buttons_layout.addWidget(self.cancel_button) # Main layout layout = QtWidgets.QVBoxLayout() layout.addLayout(top_layout) layout.addLayout(mirror_layout) layout.addLayout(buttons_layout) central_widget = QtWidgets.QWidget() central_widget.setLayout(layout) self.setCentralWidget(central_widget) # Install def install(self): self.save() subprocess.Popen([self.common.paths['tbl_bin']]) self.close() # Reinstall def reinstall(self): self.save() shutil.rmtree(self.common.paths['tbb']['dir']) subprocess.Popen([self.common.paths['tbl_bin']]) self.close() # Save & Exit def save_exit(self): self.save() self.close() # Save settings def save(self): # Checkbox options self.common.settings['download_over_tor'] = self.tor_download_checkbox.isChecked() self.common.settings['force_en-US'] = self.force_en_checkbox.isChecked() self.common.settings['tor_socks_address'] = self.tor_addr.text() # Figure out the selected mirror self.common.settings['mirror'] = self.mirror.currentText() # Save them self.common.save_settings()